diff --git a/captcha/AHGBold.ttf b/captcha/AHGBold.ttf deleted file mode 100644 index 764b23d..0000000 Binary files a/captcha/AHGBold.ttf and /dev/null differ diff --git a/captcha/LICENSE.txt b/captcha/LICENSE.txt deleted file mode 100644 index 889bc2c..0000000 --- a/captcha/LICENSE.txt +++ /dev/null @@ -1,25 +0,0 @@ -COPYRIGHT: - Copyright (c) 2011 Drew Phillips - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - diff --git a/captcha/README.FONT.txt b/captcha/README.FONT.txt deleted file mode 100644 index d4770de..0000000 --- a/captcha/README.FONT.txt +++ /dev/null @@ -1,12 +0,0 @@ -AHGBold.ttf is used by Securimage under the following license: - -Alte Haas Grotesk is a typeface that look like an helvetica printed in an old Muller-Brockmann Book. - -These fonts are freeware and can be distributed as long as they are -together with this text file. - -I would appreciate very much to see what you have done with it anyway. - -yann le coroller -www.yannlecoroller.com -yann@lecoroller.com \ No newline at end of file diff --git a/captcha/README.txt b/captcha/README.txt deleted file mode 100644 index 2acb06a..0000000 --- a/captcha/README.txt +++ /dev/null @@ -1,180 +0,0 @@ -NAME: - - Securimage - A PHP class for creating captcha images and audio with many options. - -VERSION: 3.2RC2 - -AUTHOR: - - Drew Phillips - -DOWNLOAD: - - The latest version can always be - found at http://www.phpcaptcha.org - -DOCUMENTATION: - - Online documentation of the class, methods, and variables can - be found at http://www.phpcaptcha.org/Securimage_Docs/ - -REQUIREMENTS: - PHP 5.2 or greater - GD 2.0 - FreeType (Required, for TTF fonts) - -SYNOPSIS: - - require_once 'securimage.php'; - - $image = new Securimage(); - - $image->show(); - - // Code Validation - - $image = new Securimage(); - if ($image->check($_POST['code']) == true) { - echo "Correct!"; - } else { - echo "Sorry, wrong code."; - } - -DESCRIPTION: - - What is Securimage? - - Securimage is a PHP class that is used to generate and validate CAPTCHA images. - The classes uses an existing PHP session or creates its own if none is found to store the - CAPTCHA code. Variables within the class are used to control the style and display of the image. - The class supports TTF fonts and effects for strengthening the security of the image. - An audible code can also be streamed to the browser for visually impared users. - - -COPYRIGHT: - Copyright (c) 2012 Drew Phillips - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - ----------------------------------------------------------------------------- - The WavFile.php class used in Securimage by Drew Phillips and Paul Voegler is - used under the BSD License. See WavFile.php for details. - Many thanks to Paul Voegler (http://voegler.eu/audio/pub) for contributing to - Securimage. - - ----------------------------------------------------------------------------- - Flash code created for Securimage by Age Bosma & Mario Romero (animario@hotmail.com) - Many thanks for releasing this to the project! - - ------------------------------------------------------------------------------ - Portions of Securimage contain code from Han-Kwang Nienhuys' PHP captcha - - Han-Kwang Nienhuys' PHP captcha - Copyright June 2007 - - This copyright message and attribution must be preserved upon - modification. Redistribution under other licenses is expressly allowed. - Other licenses include GPL 2 or higher, BSD, and non-free licenses. - The original, unrestricted version can be obtained from - http://www.lagom.nl/linux/hkcaptcha/ - - ------------------------------------------------------------------------------- - AHGBold.ttf (AlteHaasGroteskBold.ttf) font was created by Yann Le Coroller and is distributed as freeware - - Alte Haas Grotesk is a typeface that look like an helvetica printed in an old Muller-Brockmann Book. - - These fonts are freeware and can be distributed as long as they are - together with this text file. - - I would appreciate very much to see what you have done with it anyway. - - yann le coroller - www.yannlecoroller.com - yann@lecoroller.com - - ------------------------------------------------------------------------------- - Portions of securimage_play.swf use the PopForge flash library for playing audio - - /** - * Copyright(C) 2007 Andre Michelle and Joa Ebert - * - * PopForge is an ActionScript3 code sandbox developed by Andre Michelle and Joa Ebert - * http://sandbox.popforge.de - * - * PopforgeAS3Audio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * PopforgeAS3Audio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - - ------------------------------------------------------------------------------- - Some graphics used are from the Humility Icon Pack by WorLord - - License: GNU/GPL (http://findicons.com/pack/1723/humility) - http://findicons.com/icon/192558/gnome_volume_control - http://findicons.com/icon/192562/gtk_refresh - - ------------------------------------------------------------------------------- - Background noise sound files are from SoundJay.com - http://www.soundjay.com/tos.html - - All sound effects on this website are created by us and protected under - the copyright laws, international treaty provisions and other applicable - laws. By downloading sounds, music or any material from this site implies - that you have read and accepted these terms and conditions: - - Sound Effects - You are allowed to use the sounds free of charge and royalty free in your - projects (such as films, videos, games, presentations, animations, stage - plays, radio plays, audio books, apps) be it for commercial or - non-commercial purposes. - - But you are NOT allowed to - - post the sounds (as sound effects or ringtones) on any website for - others to download, copy or use - - use them as a raw material to create sound effects or ringtones that - you will sell, distribute or offer for downloading - - sell, re-sell, license or re-license the sounds (as individual sound - effects or as a sound effects library) to anyone else - - claim the sounds as yours - - link directly to individual sound files - - distribute the sounds in apps or computer programs that are clearly - sound related in nature (such as sound machine, sound effect - generator, ringtone maker, funny sounds app, sound therapy app, etc.) - or in apps or computer programs that use the sounds as the program's - sound resource library for other people's use (such as animation - creator, digital book creator, song maker software, etc.). If you are - developing such computer programs, contact us for licensing options. - - If you use the sound effects, please consider giving us a credit and - linking back to us but it's not required. - - \ No newline at end of file diff --git a/captcha/WavFile.php b/captcha/WavFile.php deleted file mode 100644 index 9eff88e..0000000 --- a/captcha/WavFile.php +++ /dev/null @@ -1,1861 +0,0 @@ - -* File: WavFile.php
-* -* Copyright (c) 2012, Drew Phillips -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* - Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* - Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -* Any modifications to the library should be indicated clearly in the source code -* to inform users that the changes are not a part of the original software.

-* -* @copyright 2012 Drew Phillips -* @author Drew Phillips -* @author Paul Voegler -* @version 1.0RC1 (April 2012) -* @package PHPWavUtils -* @license BSD License -* -* Changelog: -* -* 1.0 RC1 (4/20/2012) -* - Initial release candidate -* - Supports 8, 16, 24, 32 bit PCM, 32-bit IEEE FLOAT, Extensible Format -* - Support for 18 channels of audio -* - Ability to read an offset from a file to reduce memory footprint with large files -* - Single-pass audio filter processing -* - Highly accurate and efficient mix and normalization filters (http://www.voegler.eu/pub/audio/) -* - Utility filters for degrading audio, and inserting silence -* -* 0.6 (4/12/2012) -* - Support 8, 16, 24, 32 bit and PCM float (Paul Voegler) -* - Add normalize filter, misc improvements and fixes (Paul Voegler) -* - Normalize parameters to filter() to use filter constants as array indices -* - Add option to mix filter to loop the target file if the source is longer -* -* 0.5 (4/3/2012) -* - Fix binary pack routine (Paul Voegler) -* - Add improved mixing function (Paul Voegler) -* -*/ - -class WavFile -{ - /*%******************************************************************************************%*/ - // Class constants - - /** @var int Filter flag for mixing two files */ - const FILTER_MIX = 0x01; - - /** @var int Filter flag for normalizing audio data */ - const FILTER_NORMALIZE = 0x02; - - /** @var int Filter flag for degrading audio data */ - const FILTER_DEGRADE = 0x04; - - /** @var int Maximum number of channels */ - const MAX_CHANNEL = 18; - - /** @var int Maximum sample rate */ - const MAX_SAMPLERATE = 192000; - - /** Channel Locations for ChannelMask */ - const SPEAKER_DEFAULT = 0x000000; - const SPEAKER_FRONT_LEFT = 0x000001; - const SPEAKER_FRONT_RIGHT = 0x000002; - const SPEAKER_FRONT_CENTER = 0x000004; - const SPEAKER_LOW_FREQUENCY = 0x000008; - const SPEAKER_BACK_LEFT = 0x000010; - const SPEAKER_BACK_RIGHT = 0x000020; - const SPEAKER_FRONT_LEFT_OF_CENTER = 0x000040; - const SPEAKER_FRONT_RIGHT_OF_CENTER = 0x000080; - const SPEAKER_BACK_CENTER = 0x000100; - const SPEAKER_SIDE_LEFT = 0x000200; - const SPEAKER_SIDE_RIGHT = 0x000400; - const SPEAKER_TOP_CENTER = 0x000800; - const SPEAKER_TOP_FRONT_LEFT = 0x001000; - const SPEAKER_TOP_FRONT_CENTER = 0x002000; - const SPEAKER_TOP_FRONT_RIGHT = 0x004000; - const SPEAKER_TOP_BACK_LEFT = 0x008000; - const SPEAKER_TOP_BACK_CENTER = 0x010000; - const SPEAKER_TOP_BACK_RIGHT = 0x020000; - const SPEAKER_ALL = 0x03FFFF; - - /** @var int PCM Audio Format */ - const WAVE_FORMAT_PCM = 0x0001; - - /** @var int IEEE FLOAT Audio Format */ - const WAVE_FORMAT_IEEE_FLOAT = 0x0003; - - /** @var int EXTENSIBLE Audio Format - actual audio format defined by SubFormat */ - const WAVE_FORMAT_EXTENSIBLE = 0xFFFE; - - /** @var string PCM Audio Format SubType - LE hex representation of GUID {00000001-0000-0010-8000-00AA00389B71} */ - const WAVE_SUBFORMAT_PCM = "0100000000001000800000aa00389b71"; - - /** @var string IEEE FLOAT Audio Format SubType - LE hex representation of GUID {00000003-0000-0010-8000-00AA00389B71} */ - const WAVE_SUBFORMAT_IEEE_FLOAT = "0300000000001000800000aa00389b71"; - - - /*%******************************************************************************************%*/ - // Properties - - /** @var array Log base modifier lookup table for a given threshold (in 0.05 steps) used by normalizeSample. - * Adjusts the slope (1st derivative) of the log function at the threshold to 1 for a smooth transition - * from linear to logarithmic amplitude output. */ - protected static $LOOKUP_LOGBASE = array( - 2.513, 2.667, 2.841, 3.038, 3.262, - 3.520, 3.819, 4.171, 4.589, 5.093, - 5.711, 6.487, 7.483, 8.806, 10.634, - 13.302, 17.510, 24.970, 41.155, 96.088 - ); - - /** @var int The actual physical file size */ - protected $_actualSize; - - /** @var int The size of the file in RIFF header */ - protected $_chunkSize; - - /** @var int The size of the "fmt " chunk */ - protected $_fmtChunkSize; - - /** @var int The size of the extended "fmt " data */ - protected $_fmtExtendedSize; - - /** @var int The size of the "fact" chunk */ - protected $_factChunkSize; - - /** @var int Size of the data chunk */ - protected $_dataSize; - - /** @var int Size of the data chunk in the opened wav file */ - protected $_dataSize_fp; - - /** @var int Does _dataSize really reflect strlen($_samples)? Case when a wav file is read with readData = false */ - protected $_dataSize_valid; - - /** @var int Starting offset of data chunk */ - protected $_dataOffset; - - /** @var int The audio format - WavFile::WAVE_FORMAT_* */ - protected $_audioFormat; - - /** @var int The audio subformat - WavFile::WAVE_SUBFORMAT_* */ - protected $_audioSubFormat; - - /** @var int Number of channels in the audio file */ - protected $_numChannels; - - /** @var int The channel mask */ - protected $_channelMask; - - /** @var int Samples per second */ - protected $_sampleRate; - - /** @var int Number of bits per sample */ - protected $_bitsPerSample; - - /** @var int Number of valid bits per sample */ - protected $_validBitsPerSample; - - /** @var int NumChannels * BitsPerSample/8 */ - protected $_blockAlign; - - /** @var int Number of sample blocks */ - protected $_numBlocks; - - /** @var int Bytes per second */ - protected $_byteRate; - - /** @var string Binary string of samples */ - protected $_samples; - - /** @var resource The file pointer used for reading wavs from file or memory */ - protected $_fp; - - - /*%******************************************************************************************%*/ - // Special methods - - /** - * WavFile Constructor. - * - * - * $wav1 = new WavFile(2, 44100, 16); // new wav with 2 channels, at 44100 samples/sec and 16 bits per sample - * $wav2 = new WavFile('./audio/sound.wav'); // open and read wav file - * - * - * @param string|int $numChannelsOrFileName (Optional) If string, the filename of the wav file to open. The number of channels otherwise. Defaults to 1. - * @param int|bool $sampleRateOrReadData (Optional) If opening a file and boolean, decides whether to read the data chunk or not. Defaults to true. The sample rate in samples per second otherwise. 8000 = standard telephone, 16000 = wideband telephone, 32000 = FM radio and 44100 = CD quality. Defaults to 8000. - * @param int $bitsPerSample (Optional) The number of bits per sample. Has to be 8, 16 or 24 for PCM audio or 32 for IEEE FLOAT audio. 8 = telephone, 16 = CD and 24 or 32 = studio quality. Defaults to 8. - * @throws WavFormatException - * @throws WavFileException - */ - public function __construct($numChannelsOrFileName = null, $sampleRateOrReadData = null, $bitsPerSample = null) - { - $this->_actualSize = 44; - $this->_chunkSize = 36; - $this->_fmtChunkSize = 16; - $this->_fmtExtendedSize = 0; - $this->_factChunkSize = 0; - $this->_dataSize = 0; - $this->_dataSize_fp = 0; - $this->_dataSize_valid = true; - $this->_dataOffset = 44; - $this->_audioFormat = self::WAVE_FORMAT_PCM; - $this->_audioSubFormat = null; - $this->_numChannels = 1; - $this->_channelMask = self::SPEAKER_DEFAULT; - $this->_sampleRate = 8000; - $this->_bitsPerSample = 8; - $this->_validBitsPerSample = 8; - $this->_blockAlign = 1; - $this->_numBlocks = 0; - $this->_byteRate = 8000; - $this->_samples = ''; - $this->_fp = null; - - - if (is_string($numChannelsOrFileName)) { - $this->openWav($numChannelsOrFileName, is_bool($sampleRateOrReadData) ? $sampleRateOrReadData : true); - - } else { - $this->setNumChannels(is_null($numChannelsOrFileName) ? 1 : $numChannelsOrFileName) - ->setSampleRate(is_null($sampleRateOrReadData) ? 8000 : $sampleRateOrReadData) - ->setBitsPerSample(is_null($bitsPerSample) ? 8 : $bitsPerSample); - } - } - - public function __destruct() { - if (is_resource($this->_fp)) $this->closeWav(); - } - - public function __clone() { - $this->_fp = null; - } - - /** - * Output the wav file headers and data. - * - * @return string The encoded file. - */ - public function __toString() - { - return $this->makeHeader() . - $this->getDataSubchunk(); - } - - - /*%******************************************************************************************%*/ - // Static methods - - /** - * Unpacks a single binary sample to numeric value. - * - * @param string $sampleBinary (Required) The sample to decode. - * @param int $bitDepth (Optional) The bits per sample to decode. If omitted, derives it from the length of $sampleBinary. - * @return int|float The numeric sample value. Float for 32-bit samples. Returns null for unsupported bit depths. - */ - public static function unpackSample($sampleBinary, $bitDepth = null) - { - if ($bitDepth === null) { - $bitDepth = strlen($sampleBinary) * 8; - } - - switch ($bitDepth) { - case 8: - // unsigned char - return ord($sampleBinary); - - case 16: - // signed short, little endian - $data = unpack('v', $sampleBinary); - $sample = $data[1]; - if ($sample >= 0x8000) { - $sample -= 0x10000; - } - return $sample; - - case 24: - // 3 byte packed signed integer, little endian - $data = unpack('C3', $sampleBinary); - $sample = $data[1] | ($data[2] << 8) | ($data[3] << 16); - if ($sample >= 0x800000) { - $sample -= 0x1000000; - } - return $sample; - - case 32: - // 32-bit float - $data = unpack('f', $sampleBinary); - return $data[1]; - - default: - return null; - } - } - - /** - * Packs a single numeric sample to binary. - * - * @param int|float $sample (Required) The sample to encode. Has to be within valid range for $bitDepth. Float values only for 32 bits. - * @param int $bitDepth (Required) The bits per sample to encode with. - * @return string The encoded binary sample. Returns null for unsupported bit depths. - */ - public static function packSample($sample, $bitDepth) - { - switch ($bitDepth) { - case 8: - // unsigned char - return chr($sample); - - case 16: - // signed short, little endian - if ($sample < 0) { - $sample += 0x10000; - } - return pack('v', $sample); - - case 24: - // 3 byte packed signed integer, little endian - if ($sample < 0) { - $sample += 0x1000000; - } - return pack('C3', $sample & 0xff, ($sample >> 8) & 0xff, ($sample >> 16) & 0xff); - - case 32: - // 32-bit float - return pack('f', $sample); - - default: - return null; - } - } - - /** - * Unpacks a binary sample block to numeric values. - * - * @param string $sampleBlock (Required) The binary sample block (all channels). - * @param int $bitDepth (Required) The bits per sample to decode. - * @param int $numChannels (Optional) The number of channels to decode. If omitted, derives it from the length of $sampleBlock and $bitDepth. - * @return array The sample values as an array of integers of floats for 32 bits. First channel is array index 1. - */ - public static function unpackSampleBlock($sampleBlock, $bitDepth, $numChannels = null) { - $sampleBytes = $bitDepth / 8; - if ($numChannels === null) { - $numChannels = strlen($sampleBlock) / $sampleBytes; - } - - $samples = array(); - for ($i = 0; $i < $numChannels; $i++) { - $sampleBinary = substr($sampleBlock, $i * $sampleBytes, $sampleBytes); - $samples[$i + 1] = self::unpackSample($sampleBinary, $bitDepth); - } - - return $samples; - } - - /** - * Packs an array of numeric channel samples to a binary sample block. - * - * @param array $samples (Required) The array of channel sample values. Expects float values for 32 bits and integer otherwise. - * @param int $bitDepth (Required) The bits per sample to encode with. - * @return string The encoded binary sample block. - */ - public static function packSampleBlock($samples, $bitDepth) { - $sampleBlock = ''; - foreach($samples as $sample) { - $sampleBlock .= self::packSample($sample, $bitDepth); - } - - return $sampleBlock; - } - - /** - * Normalizes a float audio sample. Maximum input range assumed for compression is [-2, 2]. - * See http://www.voegler.eu/pub/audio/ for more information. - * - * @param float $sampleFloat (Required) The float sample to normalize. - * @param float $threshold (Required) The threshold or gain factor for normalizing the amplitude.
    - *
  • >= 1 - Normalize by multiplying by the threshold (boost - positive gain).
    - * A value of 1 in effect means no normalization (and results in clipping).
  • - *
  • <= -1 - Normalize by dividing by the the absolute value of threshold (attenuate - negative gain).
    - * A factor of 2 (-2) is about 6dB reduction in volume.
  • - *
  • [0, 1) - (open inverval - not including 1) - The threshold - * above which amplitudes are comressed logarithmically.
    - * e.g. 0.6 to leave amplitudes up to 60% "as is" and compress above.
  • - *
  • (-1, 0) - (open inverval - not including -1 and 0) - The threshold - * above which amplitudes are comressed linearly.
    - * e.g. -0.6 to leave amplitudes up to 60% "as is" and compress above.
- * @return float The normalized sample. - **/ - public static function normalizeSample($sampleFloat, $threshold) { - // apply positive gain - if ($threshold >= 1) { - return $sampleFloat * $threshold; - } - - // apply negative gain - if ($threshold <= -1) { - return $sampleFloat / -$threshold; - } - - $sign = $sampleFloat < 0 ? -1 : 1; - $sampleAbs = abs($sampleFloat); - - // logarithmic compression - if ($threshold >= 0 && $threshold < 1 && $sampleAbs > $threshold) { - $loga = self::$LOOKUP_LOGBASE[(int)($threshold * 20)]; // log base modifier - return $sign * ($threshold + (1 - $threshold) * log(1 + $loga * ($sampleAbs - $threshold) / (2 - $threshold)) / log(1 + $loga)); - } - - // linear compression - $thresholdAbs = abs($threshold); - if ($threshold > -1 && $threshold < 0 && $sampleAbs > $thresholdAbs) { - return $sign * ($thresholdAbs + (1 - $thresholdAbs) / (2 - $thresholdAbs) * ($sampleAbs - $thresholdAbs)); - } - - // else ? - return $sampleFloat; - } - - - /*%******************************************************************************************%*/ - // Getter and Setter methods for properties - - public function getActualSize() { - return $this->_actualSize; - } - - protected function setActualSize($actualSize = null) { - if (is_null($actualSize)) { - $this->_actualSize = 8 + $this->_chunkSize; // + "RIFF" header (ID + size) - } else { - $this->_actualSize = $actualSize; - } - - return $this; - } - - public function getChunkSize() { - return $this->_chunkSize; - } - - protected function setChunkSize($chunkSize = null) { - if (is_null($chunkSize)) { - $this->_chunkSize = 4 + // "WAVE" chunk - 8 + $this->_fmtChunkSize + // "fmt " subchunk - ($this->_factChunkSize > 0 ? 8 + $this->_factChunkSize : 0) + // "fact" subchunk - 8 + $this->_dataSize + // "data" subchunk - ($this->_dataSize & 1); // padding byte - } else { - $this->_chunkSize = $chunkSize; - } - - $this->setActualSize(); - - return $this; - } - - public function getFmtChunkSize() { - return $this->_fmtChunkSize; - } - - protected function setFmtChunkSize($fmtChunkSize = null) { - if (is_null($fmtChunkSize)) { - $this->_fmtChunkSize = 16 + $this->_fmtExtendedSize; - } else { - $this->_fmtChunkSize = $fmtChunkSize; - } - - $this->setChunkSize() // implicit setActualSize() - ->setDataOffset(); - - return $this; - } - - public function getFmtExtendedSize() { - return $this->_fmtExtendedSize; - } - - protected function setFmtExtendedSize($fmtExtendedSize = null) { - if (is_null($fmtExtendedSize)) { - if ($this->_audioFormat == self::WAVE_FORMAT_EXTENSIBLE) { - $this->_fmtExtendedSize = 2 + 22; // extension size for WAVE_FORMAT_EXTENSIBLE - } elseif ($this->_audioFormat != self::WAVE_FORMAT_PCM) { - $this->_fmtExtendedSize = 2 + 0; // empty extension - } else { - $this->_fmtExtendedSize = 0; // no extension, only for WAVE_FORMAT_PCM - } - } else { - $this->_fmtExtendedSize = $fmtExtendedSize; - } - - $this->setFmtChunkSize(); // implicit setSize(), setActualSize(), setDataOffset() - - return $this; - } - - public function getFactChunkSize() { - return $this->_factChunkSize; - } - - protected function setFactChunkSize($factChunkSize = null) { - if (is_null($factChunkSize)) { - if ($this->_audioFormat != self::WAVE_FORMAT_PCM) { - $this->_factChunkSize = 4; - } else { - $this->_factChunkSize = 0; - } - } else { - $this->_factChunkSize = $factChunkSize; - } - - $this->setChunkSize() // implicit setActualSize() - ->setDataOffset(); - - return $this; - } - - public function getDataSize() { - return $this->_dataSize; - } - - protected function setDataSize($dataSize = null) { - if (is_null($dataSize)) { - $this->_dataSize = strlen($this->_samples); - } else { - $this->_dataSize = $dataSize; - } - - $this->setChunkSize() // implicit setActualSize() - ->setNumBlocks(); - $this->_dataSize_valid = true; - - return $this; - } - - public function getDataOffset() { - return $this->_dataOffset; - } - - protected function setDataOffset($dataOffset = null) { - if (is_null($dataOffset)) { - $this->_dataOffset = 8 + // "RIFF" header (ID + size) - 4 + // "WAVE" chunk - 8 + $this->_fmtChunkSize + // "fmt " subchunk - ($this->_factChunkSize > 0 ? 8 + $this->_factChunkSize : 0) + // "fact" subchunk - 8; // "data" subchunk - } else { - $this->_dataOffset = $dataOffset; - } - - return $this; - } - - public function getAudioFormat() { - return $this->_audioFormat; - } - - protected function setAudioFormat($audioFormat = null) { - if (is_null($audioFormat)) { - if (($this->_bitsPerSample <= 16 || $this->_bitsPerSample == 32) - && $this->_validBitsPerSample == $this->_bitsPerSample - && $this->_channelMask == self::SPEAKER_DEFAULT - && $this->_numChannels <= 2) { - if ($this->_bitsPerSample <= 16) { - $this->_audioFormat = self::WAVE_FORMAT_PCM; - } else { - $this->_audioFormat = self::WAVE_FORMAT_IEEE_FLOAT; - } - } else { - $this->_audioFormat = self::WAVE_FORMAT_EXTENSIBLE; - } - } else { - $this->_audioFormat = $audioFormat; - } - - $this->setAudioSubFormat() - ->setFactChunkSize() // implicit setSize(), setActualSize(), setDataOffset() - ->setFmtExtendedSize(); // implicit setFmtChunkSize(), setSize(), setActualSize(), setDataOffset() - - return $this; - } - - public function getAudioSubFormat() { - return $this->_audioSubFormat; - } - - protected function setAudioSubFormat($audioSubFormat = null) { - if (is_null($audioSubFormat)) { - if ($this->_bitsPerSample == 32) { - $this->_audioSubFormat = self::WAVE_SUBFORMAT_IEEE_FLOAT; // 32 bits are IEEE FLOAT in this class - } else { - $this->_audioSubFormat = self::WAVE_SUBFORMAT_PCM; // 8, 16 and 24 bits are PCM in this class - } - } else { - $this->_audioSubFormat = $audioSubFormat; - } - - return $this; - } - - public function getNumChannels() { - return $this->_numChannels; - } - - public function setNumChannels($numChannels) { - if ($numChannels < 1 || $numChannels > self::MAX_CHANNEL) { - throw new WavFileException('Unsupported number of channels. Only up to ' . self::MAX_CHANNEL . ' channels are supported.'); - } elseif ($this->_samples !== '') { - trigger_error('Wav already has sample data. Changing the number of channels does not convert and may corrupt the data.', E_USER_NOTICE); - } - - $this->_numChannels = (int)$numChannels; - - $this->setAudioFormat() // implicit setAudioSubFormat(), setFactChunkSize(), setFmtExtendedSize(), setFmtChunkSize(), setSize(), setActualSize(), setDataOffset() - ->setByteRate() - ->setBlockAlign(); // implicit setNumBlocks() - - return $this; - } - - public function getChannelMask() { - return $this->_channelMask; - } - - public function setChannelMask($channelMask = self::SPEAKER_DEFAULT) { - if ($channelMask != 0) { - // count number of set bits - Hamming weight - $c = (int)$channelMask; - $n = 0; - while ($c > 0) { - $n += $c & 1; - $c >>= 1; - } - if ($n != $this->_numChannels || (((int)$channelMask | self::SPEAKER_ALL) != self::SPEAKER_ALL)) { - throw new WavFileException('Invalid channel mask. The number of channels does not match the number of locations in the mask.'); - } - } - - $this->_channelMask = (int)$channelMask; - - $this->setAudioFormat(); // implicit setAudioSubFormat(), setFactChunkSize(), setFmtExtendedSize(), setFmtChunkSize(), setSize(), setActualSize(), setDataOffset() - - return $this; - } - - public function getSampleRate() { - return $this->_sampleRate; - } - - public function setSampleRate($sampleRate) { - if ($sampleRate < 1 || $sampleRate > self::MAX_SAMPLERATE) { - throw new WavFileException('Invalid sample rate.'); - } elseif ($this->_samples !== '') { - trigger_error('Wav already has sample data. Changing the sample rate does not convert the data and may yield undesired results.', E_USER_NOTICE); - } - - $this->_sampleRate = (int)$sampleRate; - - $this->setByteRate(); - - return $this; - } - - public function getBitsPerSample() { - return $this->_bitsPerSample; - } - - public function setBitsPerSample($bitsPerSample) { - if (!in_array($bitsPerSample, array(8, 16, 24, 32))) { - throw new WavFileException('Unsupported bits per sample. Only 8, 16, 24 and 32 bits are supported.'); - } elseif ($this->_samples !== '') { - trigger_error('Wav already has sample data. Changing the bits per sample does not convert and may corrupt the data.', E_USER_NOTICE); - } - - $this->_bitsPerSample = (int)$bitsPerSample; - - $this->setValidBitsPerSample() // implicit setAudioFormat(), setAudioSubFormat(), setFmtChunkSize(), setFactChunkSize(), setSize(), setActualSize(), setDataOffset() - ->setByteRate() - ->setBlockAlign(); // implicit setNumBlocks() - - return $this; - } - - public function getValidBitsPerSample() { - return $this->_validBitsPerSample; - } - - protected function setValidBitsPerSample($validBitsPerSample = null) { - if (is_null($validBitsPerSample)) { - $this->_validBitsPerSample = $this->_bitsPerSample; - } else { - if ($validBitsPerSample < 1 || $validBitsPerSample > $this->_bitsPerSample) { - throw new WavFileException('ValidBitsPerSample cannot be greater than BitsPerSample.'); - } - $this->_validBitsPerSample = (int)$validBitsPerSample; - } - - $this->setAudioFormat(); // implicit setAudioSubFormat(), setFactChunkSize(), setFmtExtendedSize(), setFmtChunkSize(), setSize(), setActualSize(), setDataOffset() - - return $this; - } - - public function getBlockAlign() { - return $this->_blockAlign; - } - - protected function setBlockAlign($blockAlign = null) { - if (is_null($blockAlign)) { - $this->_blockAlign = $this->_numChannels * $this->_bitsPerSample / 8; - } else { - $this->_blockAlign = $blockAlign; - } - - $this->setNumBlocks(); - - return $this; - } - - public function getNumBlocks() - { - return $this->_numBlocks; - } - - protected function setNumBlocks($numBlocks = null) { - if (is_null($numBlocks)) { - $this->_numBlocks = (int)($this->_dataSize / $this->_blockAlign); // do not count incomplete sample blocks - } else { - $this->_numBlocks = $numBlocks; - } - - return $this; - } - - public function getByteRate() { - return $this->_byteRate; - } - - protected function setByteRate($byteRate = null) { - if (is_null($byteRate)) { - $this->_byteRate = $this->_sampleRate * $this->_numChannels * $this->_bitsPerSample / 8; - } else { - $this->_byteRate = $byteRate; - } - - return $this; - } - - public function getSamples() { - return $this->_samples; - } - - public function setSamples(&$samples = '') { - if (strlen($samples) % $this->_blockAlign != 0) { - throw new WavFileException('Incorrect samples size. Has to be a multiple of BlockAlign.'); - } - - $this->_samples = $samples; - - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - return $this; - } - - - /*%******************************************************************************************%*/ - // Getters - - public function getMinAmplitude() - { - if ($this->_bitsPerSample == 8) { - return 0; - } elseif ($this->_bitsPerSample == 32) { - return -1.0; - } else { - return -(1 << ($this->_bitsPerSample - 1)); - } - } - - public function getZeroAmplitude() - { - if ($this->_bitsPerSample == 8) { - return 0x80; - } elseif ($this->_bitsPerSample == 32) { - return 0.0; - } else { - return 0; - } - } - - public function getMaxAmplitude() - { - if($this->_bitsPerSample == 8) { - return 0xFF; - } elseif($this->_bitsPerSample == 32) { - return 1.0; - } else { - return (1 << ($this->_bitsPerSample - 1)) - 1; - } - } - - - /*%******************************************************************************************%*/ - // Wave file methods - - /** - * Construct a wav header from this object. Includes "fact" chunk in necessary. - * http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html - * - * @return string The RIFF header data. - */ - public function makeHeader() - { - // reset and recalculate - $this->setAudioFormat(); // implicit setAudioSubFormat(), setFactChunkSize(), setFmtExtendedSize(), setFmtChunkSize(), setSize(), setActualSize(), setDataOffset() - $this->setNumBlocks(); - - // RIFF header - $header = pack('N', 0x52494646); // ChunkID - "RIFF" - $header .= pack('V', $this->getChunkSize()); // ChunkSize - $header .= pack('N', 0x57415645); // Format - "WAVE" - - // "fmt " subchunk - $header .= pack('N', 0x666d7420); // SubchunkID - "fmt " - $header .= pack('V', $this->getFmtChunkSize()); // SubchunkSize - $header .= pack('v', $this->getAudioFormat()); // AudioFormat - $header .= pack('v', $this->getNumChannels()); // NumChannels - $header .= pack('V', $this->getSampleRate()); // SampleRate - $header .= pack('V', $this->getByteRate()); // ByteRate - $header .= pack('v', $this->getBlockAlign()); // BlockAlign - $header .= pack('v', $this->getBitsPerSample()); // BitsPerSample - if($this->getFmtExtendedSize() == 24) { - $header .= pack('v', 22); // extension size = 24 bytes, cbSize: 24 - 2 = 22 bytes - $header .= pack('v', $this->getValidBitsPerSample()); // ValidBitsPerSample - $header .= pack('V', $this->getChannelMask()); // ChannelMask - $header .= pack('H32', $this->getAudioSubFormat()); // SubFormat - } elseif ($this->getFmtExtendedSize() == 2) { - $header .= pack('v', 0); // extension size = 2 bytes, cbSize: 2 - 2 = 0 bytes - } - - // "fact" subchunk - if ($this->getFactChunkSize() == 4) { - $header .= pack('N', 0x66616374); // SubchunkID - "fact" - $header .= pack('V', 4); // SubchunkSize - $header .= pack('V', $this->getNumBlocks()); // SampleLength (per channel) - } - - return $header; - } - - /** - * Construct wav DATA chunk. - * - * @return string The DATA header and chunk. - */ - public function getDataSubchunk() - { - // check preconditions - if (!$this->_dataSize_valid) { - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - } - - - // create subchunk - return pack('N', 0x64617461) . // SubchunkID - "data" - pack('V', $this->getDataSize()) . // SubchunkSize - $this->_samples . // Subchunk data - ($this->getDataSize() & 1 ? chr(0) : ''); // padding byte - } - - /** - * Save the wav data to a file. - * - * @param string $filename (Required) The file path to save the wav to. - * @throws WavFileException - */ - public function save($filename) - { - $fp = @fopen($filename, 'w+b'); - if (!is_resource($fp)) { - throw new WavFileException('Failed to open "' . $filename . '" for writing.'); - } - - fwrite($fp, $this->makeHeader()); - fwrite($fp, $this->getDataSubchunk()); - fclose($fp); - - return $this; - } - - /** - * Reads a wav header and data from a file. - * - * @param string $filename (Required) The path to the wav file to read. - * @param bool $readData (Optional) If true, also read the data chunk. - * @throws WavFormatException - * @throws WavFileException - */ - public function openWav($filename, $readData = true) - { - // check preconditions - if (!file_exists($filename)) { - throw new WavFileException('Failed to open "' . $filename . '". File not found.'); - } elseif (!is_readable($filename)) { - throw new WavFileException('Failed to open "' . $filename . '". File is not readable.'); - } elseif (is_resource($this->_fp)) { - $this->closeWav(); - } - - - // open the file - $this->_fp = @fopen($filename, 'rb'); - if (!is_resource($this->_fp)) { - throw new WavFileException('Failed to open "' . $filename . '".'); - } - - // read the file - return $this->readWav($readData); - } - - /** - * Close a with openWav() previously opened wav file or free the buffer of setWavData(). - * Not necessary if the data has been read (readData = true) already. - */ - public function closeWav() { - if (is_resource($this->_fp)) fclose($this->_fp); - - return $this; - } - - /** - * Set the wav file data and properties from a wav file in a string. - * - * @param string $data (Required) The wav file data. Passed by reference. - * @param bool $free (Optional) True to free the passed $data after copying. - * @throws WavFormatException - * @throws WavFileException - */ - public function setWavData(&$data, $free = true) - { - // check preconditions - if (is_resource($this->_fp)) $this->closeWav(); - - - // open temporary stream in memory - $this->_fp = @fopen('php://memory', 'w+b'); - if (!is_resource($this->_fp)) { - throw new WavFileException('Failed to open memory stream to write wav data. Use openWav() instead.'); - } - - // prepare stream - fwrite($this->_fp, $data); - rewind($this->_fp); - - // free the passed data - if ($free) $data = null; - - // read the stream like a file - return $this->readWav(true); - } - - /** - * Read wav file from a stream. - * - * @param $readData (Optional) If true, also read the data chunk. - * @throws WavFormatException - * @throws WavFileException - */ - protected function readWav($readData = true) - { - if (!is_resource($this->_fp)) { - throw new WavFileException('No wav file open. Use openWav() first.'); - } - - try { - $this->readWavHeader(); - } catch (WavFileException $ex) { - $this->closeWav(); - throw $ex; - } - - if ($readData) return $this->readWavData(); - - return $this; - } - - /** - * Parse a wav header. - * http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html - * - * @throws WavFormatException - * @throws WavFileException - */ - protected function readWavHeader() - { - if (!is_resource($this->_fp)) { - throw new WavFileException('No wav file open. Use openWav() first.'); - } - - // get actual file size - $stat = fstat($this->_fp); - $actualSize = $stat['size']; - - $this->_actualSize = $actualSize; - - - // read the common header - $header = fread($this->_fp, 36); // minimum size of the wav header - if (strlen($header) < 36) { - throw new WavFormatException('Not wav format. Header too short.', 1); - } - - - // check "RIFF" header - $RIFF = unpack('NChunkID/VChunkSize/NFormat', $header); - - if ($RIFF['ChunkID'] != 0x52494646) { // "RIFF" - throw new WavFormatException('Not wav format. "RIFF" signature missing.', 2); - } - - if ($actualSize - 8 < $RIFF['ChunkSize']) { - trigger_error('"RIFF" chunk size does not match actual file size. Found ' . $RIFF['ChunkSize'] . ', expected ' . ($actualSize - 8) . '.', E_USER_NOTICE); - $RIFF['ChunkSize'] = $actualSize - 8; - //throw new WavFormatException('"RIFF" chunk size does not match actual file size. Found ' . $RIFF['ChunkSize'] . ', expected ' . ($actualSize - 8) . '.', 3); - } - - if ($RIFF['Format'] != 0x57415645) { // "WAVE" - throw new WavFormatException('Not wav format. "RIFF" chunk format is not "WAVE".', 4); - } - - $this->_chunkSize = $RIFF['ChunkSize']; - - - // check common "fmt " subchunk - $fmt = unpack('NSubchunkID/VSubchunkSize/vAudioFormat/vNumChannels/' - .'VSampleRate/VByteRate/vBlockAlign/vBitsPerSample', - substr($header, 12)); - - if ($fmt['SubchunkID'] != 0x666d7420) { // "fmt " - throw new WavFormatException('Bad wav header. Expected "fmt " subchunk.', 11); - } - - if ($fmt['SubchunkSize'] < 16) { - throw new WavFormatException('Bad "fmt " subchunk size.', 12); - } - - if ( $fmt['AudioFormat'] != self::WAVE_FORMAT_PCM - && $fmt['AudioFormat'] != self::WAVE_FORMAT_IEEE_FLOAT - && $fmt['AudioFormat'] != self::WAVE_FORMAT_EXTENSIBLE) - { - throw new WavFormatException('Unsupported audio format. Only PCM or IEEE FLOAT (EXTENSIBLE) audio is supported.', 13); - } - - if ($fmt['NumChannels'] < 1 || $fmt['NumChannels'] > self::MAX_CHANNEL) { - throw new WavFormatException('Invalid number of channels in "fmt " subchunk.', 14); - } - - if ($fmt['SampleRate'] < 1 || $fmt['SampleRate'] > self::MAX_SAMPLERATE) { - throw new WavFormatException('Invalid sample rate in "fmt " subchunk.', 15); - } - - if ( ($fmt['AudioFormat'] == self::WAVE_FORMAT_PCM && !in_array($fmt['BitsPerSample'], array(8, 16, 24))) - || ($fmt['AudioFormat'] == self::WAVE_FORMAT_IEEE_FLOAT && $fmt['BitsPerSample'] != 32) - || ($fmt['AudioFormat'] == self::WAVE_FORMAT_EXTENSIBLE && !in_array($fmt['BitsPerSample'], array(8, 16, 24, 32)))) - { - throw new WavFormatException('Only 8, 16 and 24-bit PCM and 32-bit IEEE FLOAT (EXTENSIBLE) audio is supported.', 16); - } - - $blockAlign = $fmt['NumChannels'] * $fmt['BitsPerSample'] / 8; - if ($blockAlign != $fmt['BlockAlign']) { - trigger_error('Invalid block align in "fmt " subchunk. Found ' . $fmt['BlockAlign'] . ', expected ' . $blockAlign . '.', E_USER_NOTICE); - $fmt['BlockAlign'] = $blockAlign; - //throw new WavFormatException('Invalid block align in "fmt " subchunk. Found ' . $fmt['BlockAlign'] . ', expected ' . $blockAlign . '.', 17); - } - - $byteRate = $fmt['SampleRate'] * $blockAlign; - if ($byteRate != $fmt['ByteRate']) { - trigger_error('Invalid average byte rate in "fmt " subchunk. Found ' . $fmt['ByteRate'] . ', expected ' . $byteRate . '.', E_USER_NOTICE); - $fmt['ByteRate'] = $byteRate; - //throw new WavFormatException('Invalid average byte rate in "fmt " subchunk. Found ' . $fmt['ByteRate'] . ', expected ' . $byteRate . '.', 18); - } - - $this->_fmtChunkSize = $fmt['SubchunkSize']; - $this->_audioFormat = $fmt['AudioFormat']; - $this->_numChannels = $fmt['NumChannels']; - $this->_sampleRate = $fmt['SampleRate']; - $this->_byteRate = $fmt['ByteRate']; - $this->_blockAlign = $fmt['BlockAlign']; - $this->_bitsPerSample = $fmt['BitsPerSample']; - - - // read extended "fmt " subchunk data - $extendedFmt = ''; - if ($fmt['SubchunkSize'] > 16) { - // possibly handle malformed subchunk without a padding byte - $extendedFmt = fread($this->_fp, $fmt['SubchunkSize'] - 16 + ($fmt['SubchunkSize'] & 1)); // also read padding byte - if (strlen($extendedFmt) < $fmt['SubchunkSize'] - 16) { - throw new WavFormatException('Not wav format. Header too short.', 1); - } - } - - - // check extended "fmt " for EXTENSIBLE Audio Format - if ($fmt['AudioFormat'] == self::WAVE_FORMAT_EXTENSIBLE) { - if (strlen($extendedFmt) < 24) { - throw new WavFormatException('Invalid EXTENSIBLE "fmt " subchunk size. Found ' . $fmt['SubchunkSize'] . ', expected at least 40.', 19); - } - - $extensibleFmt = unpack('vSize/vValidBitsPerSample/VChannelMask/H32SubFormat', substr($extendedFmt, 0, 24)); - - if ( $extensibleFmt['SubFormat'] != self::WAVE_SUBFORMAT_PCM - && $extensibleFmt['SubFormat'] != self::WAVE_SUBFORMAT_IEEE_FLOAT) - { - throw new WavFormatException('Unsupported audio format. Only PCM or IEEE FLOAT (EXTENSIBLE) audio is supported.', 13); - } - - if ( ($extensibleFmt['SubFormat'] == self::WAVE_SUBFORMAT_PCM && !in_array($fmt['BitsPerSample'], array(8, 16, 24))) - || ($extensibleFmt['SubFormat'] == self::WAVE_SUBFORMAT_IEEE_FLOAT && $fmt['BitsPerSample'] != 32)) - { - throw new WavFormatException('Only 8, 16 and 24-bit PCM and 32-bit IEEE FLOAT (EXTENSIBLE) audio is supported.', 16); - } - - if ($extensibleFmt['Size'] != 22) { - trigger_error('Invaid extension size in EXTENSIBLE "fmt " subchunk.', E_USER_NOTICE); - $extensibleFmt['Size'] = 22; - //throw new WavFormatException('Invaid extension size in EXTENSIBLE "fmt " subchunk.', 20); - } - - if ($extensibleFmt['ValidBitsPerSample'] != $fmt['BitsPerSample']) { - trigger_error('Invaid or unsupported valid bits per sample in EXTENSIBLE "fmt " subchunk.', E_USER_NOTICE); - $extensibleFmt['ValidBitsPerSample'] = $fmt['BitsPerSample']; - //throw new WavFormatException('Invaid or unsupported valid bits per sample in EXTENSIBLE "fmt " subchunk.', 21); - } - - if ($extensibleFmt['ChannelMask'] != 0) { - // count number of set bits - Hamming weight - $c = (int)$extensibleFmt['ChannelMask']; - $n = 0; - while ($c > 0) { - $n += $c & 1; - $c >>= 1; - } - if ($n != $fmt['NumChannels'] || (((int)$extensibleFmt['ChannelMask'] | self::SPEAKER_ALL) != self::SPEAKER_ALL)) { - trigger_error('Invalid channel mask in EXTENSIBLE "fmt " subchunk. The number of channels does not match the number of locations in the mask.', E_USER_NOTICE); - $extensibleFmt['ChannelMask'] = 0; - //throw new WavFormatException('Invalid channel mask in EXTENSIBLE "fmt " subchunk. The number of channels does not match the number of locations in the mask.', 22); - } - } - - $this->_fmtExtendedSize = strlen($extendedFmt); - $this->_validBitsPerSample = $extensibleFmt['ValidBitsPerSample']; - $this->_channelMask = $extensibleFmt['ChannelMask']; - $this->_audioSubFormat = $extensibleFmt['SubFormat']; - - } else { - $this->_fmtExtendedSize = strlen($extendedFmt); - $this->_validBitsPerSample = $fmt['BitsPerSample']; - $this->_channelMask = 0; - $this->_audioSubFormat = null; - } - - - // read additional subchunks until "data" subchunk is found - $factSubchunk = array(); - $dataSubchunk = array(); - - while (!feof($this->_fp)) { - $subchunkHeader = fread($this->_fp, 8); - if (strlen($subchunkHeader) < 8) { - throw new WavFormatException('Missing "data" subchunk.', 101); - } - - $subchunk = unpack('NSubchunkID/VSubchunkSize', $subchunkHeader); - - if ($subchunk['SubchunkID'] == 0x66616374) { // "fact" - // possibly handle malformed subchunk without a padding byte - $subchunkData = fread($this->_fp, $subchunk['SubchunkSize'] + ($subchunk['SubchunkSize'] & 1)); // also read padding byte - if (strlen($subchunkData) < 4) { - throw new WavFormatException('Invalid "fact" subchunk.', 102); - } - - $factParams = unpack('VSampleLength', substr($subchunkData, 0, 4)); - $factSubchunk = array_merge($subchunk, $factParams); - - } elseif ($subchunk['SubchunkID'] == 0x64617461) { // "data" - $dataSubchunk = $subchunk; - - break; - - } elseif ($subchunk['SubchunkID'] == 0x7761766C) { // "wavl" - throw new WavFormatException('Wave List Chunk ("wavl" subchunk) is not supported.', 106); - } else { - // skip all other (unknown) subchunks - // possibly handle malformed subchunk without a padding byte - if ( $subchunk['SubchunkSize'] < 0 - || fseek($this->_fp, $subchunk['SubchunkSize'] + ($subchunk['SubchunkSize'] & 1), SEEK_CUR) !== 0) { // also skip padding byte - throw new WavFormatException('Invalid subchunk (0x' . dechex($subchunk['SubchunkID']) . ') encountered.', 103); - } - } - } - - if (empty($dataSubchunk)) { - throw new WavFormatException('Missing "data" subchunk.', 101); - } - - - // check "data" subchunk - $dataOffset = ftell($this->_fp); - if ($dataSubchunk['SubchunkSize'] < 0 || $actualSize - $dataOffset < $dataSubchunk['SubchunkSize']) { - trigger_error('Invalid "data" subchunk size.', E_USER_NOTICE); - $dataSubchunk['SubchunkSize'] = $actualSize - $dataOffset; - //throw new WavFormatException('Invalid "data" subchunk size.', 104); - } - - $this->_dataOffset = $dataOffset; - $this->_dataSize = $dataSubchunk['SubchunkSize']; - $this->_dataSize_fp = $dataSubchunk['SubchunkSize']; - $this->_dataSize_valid = false; - $this->_samples = ''; - - - // check "fact" subchunk - $numBlocks = (int)($dataSubchunk['SubchunkSize'] / $fmt['BlockAlign']); - - if (empty($factSubchunk)) { // construct fake "fact" subchunk - $factSubchunk = array('SubchunkSize' => 0, 'SampleLength' => $numBlocks); - } - - if ($factSubchunk['SampleLength'] != $numBlocks) { - trigger_error('Invalid sample length in "fact" subchunk.', E_USER_NOTICE); - $factSubchunk['SampleLength'] = $numBlocks; - //throw new WavFormatException('Invalid sample length in "fact" subchunk.', 105); - } - - $this->_factChunkSize = $factSubchunk['SubchunkSize']; - $this->_numBlocks = $factSubchunk['SampleLength']; - - - return $this; - - } - - /** - * Read the wav data from the file into the buffer. - * - * @param $dataOffset (Optional) The byte offset to skip before starting to read. Must be a multiple of BlockAlign. - * @param $dataSize (Optional) The size of the data to read in bytes. Must be a multiple of BlockAlign. Defaults to all data. - * @throws WavFileException - */ - public function readWavData($dataOffset = 0, $dataSize = null) - { - // check preconditions - if (!is_resource($this->_fp)) { - throw new WavFileException('No wav file open. Use openWav() first.'); - } - - if ($dataOffset < 0 || $dataOffset % $this->getBlockAlign() > 0) { - throw new WavFileException('Invalid data offset. Has to be a multiple of BlockAlign.'); - } - - if (is_null($dataSize)) { - $dataSize = $this->_dataSize_fp - ($this->_dataSize_fp % $this->getBlockAlign()); // only read complete blocks - } elseif ($dataSize < 0 || $dataSize % $this->getBlockAlign() > 0) { - throw new WavFileException('Invalid data size to read. Has to be a multiple of BlockAlign.'); - } - - - // skip offset - if ($dataOffset > 0 && fseek($this->_fp, $dataOffset, SEEK_CUR) !== 0) { - throw new WavFileException('Seeking to data offset failed.'); - } - - // read data - $this->_samples .= fread($this->_fp, $dataSize); // allow appending - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - // close file or memory stream - return $this->closeWav(); - } - - - /*%******************************************************************************************%*/ - // Sample manipulation methods - - /** - * Return a single sample block from the file. - * - * @param int $blockNum (Required) The sample block number. Zero based. - * @return string The binary sample block (all channels). Returns null if the sample block number was out of range. - */ - public function getSampleBlock($blockNum) - { - // check preconditions - if (!$this->_dataSize_valid) { - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - } - - $offset = $blockNum * $this->_blockAlign; - if ($offset + $this->_blockAlign > $this->_dataSize || $offset < 0) { - return null; - } - - - // read data - return substr($this->_samples, $offset, $this->_blockAlign); - } - - /** - * Set a single sample block.
- * Allows to append a sample block. - * - * @param string $sampleBlock (Required) The binary sample block (all channels). - * @param int $blockNum (Required) The sample block number. Zero based. - * @throws WavFileException - */ - public function setSampleBlock($sampleBlock, $blockNum) - { - // check preconditions - $blockAlign = $this->_blockAlign; - if (!isset($sampleBlock[$blockAlign - 1]) || isset($sampleBlock[$blockAlign])) { // faster than: if (strlen($sampleBlock) != $blockAlign) - throw new WavFileException('Incorrect sample block size. Got ' . strlen($sampleBlock) . ', expected ' . $blockAlign . '.'); - } - - if (!$this->_dataSize_valid) { - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - } - - $numBlocks = (int)($this->_dataSize / $blockAlign); - $offset = $blockNum * $blockAlign; - if ($blockNum > $numBlocks || $blockNum < 0) { // allow appending - throw new WavFileException('Sample block number is out of range.'); - } - - - // replace or append data - if ($blockNum == $numBlocks) { - // append - $this->_samples .= $sampleBlock; - $this->_dataSize += $blockAlign; - $this->_chunkSize += $blockAlign; - $this->_actualSize += $blockAlign; - $this->_numBlocks++; - } else { - // replace - for ($i = 0; $i < $blockAlign; ++$i) { - $this->_samples[$offset + $i] = $sampleBlock[$i]; - } - } - - return $this; - } - - /** - * Get a float sample value for a specific sample block and channel number. - * - * @param int $blockNum (Required) The sample block number to fetch. Zero based. - * @param int $channelNum (Required) The channel number within the sample block to fetch. First channel is 1. - * @return float The float sample value. Returns null if the sample block number was out of range. - * @throws WavFileException - */ - public function getSampleValue($blockNum, $channelNum) - { - // check preconditions - if ($channelNum < 1 || $channelNum > $this->_numChannels) { - throw new WavFileException('Channel number is out of range.'); - } - - if (!$this->_dataSize_valid) { - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - } - - $sampleBytes = $this->_bitsPerSample / 8; - $offset = $blockNum * $this->_blockAlign + ($channelNum - 1) * $sampleBytes; - if ($offset + $sampleBytes > $this->_dataSize || $offset < 0) { - return null; - } - - // read binary value - $sampleBinary = substr($this->_samples, $offset, $sampleBytes); - - // convert binary to value - switch ($this->_bitsPerSample) { - case 8: - // unsigned char - return (float)((ord($sampleBinary) - 0x80) / 0x80); - - case 16: - // signed short, little endian - $data = unpack('v', $sampleBinary); - $sample = $data[1]; - if ($sample >= 0x8000) { - $sample -= 0x10000; - } - return (float)($sample / 0x8000); - - case 24: - // 3 byte packed signed integer, little endian - $data = unpack('C3', $sampleBinary); - $sample = $data[1] | ($data[2] << 8) | ($data[3] << 16); - if ($sample >= 0x800000) { - $sample -= 0x1000000; - } - return (float)($sample / 0x800000); - - case 32: - // 32-bit float - $data = unpack('f', $sampleBinary); - return (float)$data[1]; - - default: - return null; - } - } - - /** - * Sets a float sample value for a specific sample block number and channel.
- * Converts float values to appropriate integer values and clips properly.
- * Allows to append samples (in order). - * - * @param float $sampleFloat (Required) The float sample value to set. Converts float values and clips if necessary. - * @param int $blockNum (Required) The sample block number to set or append. Zero based. - * @param int $channelNum (Required) The channel number within the sample block to set or append. First channel is 1. - * @throws WavFileException - */ - public function setSampleValue($sampleFloat, $blockNum, $channelNum) - { - // check preconditions - if ($channelNum < 1 || $channelNum > $this->_numChannels) { - throw new WavFileException('Channel number is out of range.'); - } - - if (!$this->_dataSize_valid) { - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - } - - $dataSize = $this->_dataSize; - $bitsPerSample = $this->_bitsPerSample; - $sampleBytes = $bitsPerSample / 8; - $offset = $blockNum * $this->_blockAlign + ($channelNum - 1) * $sampleBytes; - if (($offset + $sampleBytes > $dataSize && $offset != $dataSize) || $offset < 0) { // allow appending - throw new WavFileException('Sample block or channel number is out of range.'); - } - - - // convert to value, quantize and clip - if ($bitsPerSample == 32) { - $sample = $sampleFloat < -1.0 ? -1.0 : ($sampleFloat > 1.0 ? 1.0 : $sampleFloat); - } else { - $p = 1 << ($bitsPerSample - 1); // 2 to the power of _bitsPerSample divided by 2 - - // project and quantize (round) float to integer values - $sample = $sampleFloat < 0 ? (int)($sampleFloat * $p - 0.5) : (int)($sampleFloat * $p + 0.5); - - // clip if necessary to [-$p, $p - 1] - if ($sample < -$p) { - $sample = -$p; - } elseif ($sample > $p - 1) { - $sample = $p - 1; - } - } - - // convert to binary - switch ($bitsPerSample) { - case 8: - // unsigned char - $sampleBinary = chr($sample + 0x80); - break; - - case 16: - // signed short, little endian - if ($sample < 0) { - $sample += 0x10000; - } - $sampleBinary = pack('v', $sample); - break; - - case 24: - // 3 byte packed signed integer, little endian - if ($sample < 0) { - $sample += 0x1000000; - } - $sampleBinary = pack('C3', $sample & 0xff, ($sample >> 8) & 0xff, ($sample >> 16) & 0xff); - break; - - case 32: - // 32-bit float - $sampleBinary = pack('f', $sample); - break; - - default: - $sampleBinary = null; - $sampleBytes = 0; - break; - } - - // replace or append data - if ($offset == $dataSize) { - // append - $this->_samples .= $sampleBinary; - $this->_dataSize += $sampleBytes; - $this->_chunkSize += $sampleBytes; - $this->_actualSize += $sampleBytes; - $this->_numBlocks = (int)($this->_dataSize / $this->_blockAlign); - } else { - // replace - for ($i = 0; $i < $sampleBytes; ++$i) { - $this->_samples{$offset + $i} = $sampleBinary{$i}; - } - } - - return $this; - } - - - /*%******************************************************************************************%*/ - // Audio processing methods - - /** - * Run samples through audio processing filters. - * - * - * $wav->filter( - * array( - * WavFile::FILTER_MIX => array( // Filter for mixing 2 WavFile instances. - * 'wav' => $wav2, // (Required) The WavFile to mix into this WhavFile. If no optional arguments are given, can be passed without the array. - * 'loop' => true, // (Optional) Loop the selected portion (with warping to the beginning at the end). - * 'blockOffset' => 0, // (Optional) Block number to start mixing from. - * 'numBlocks' => null // (Optional) Number of blocks to mix in or to select for looping. Defaults to the end or all data for looping. - * ), - * WavFile::FILTER_NORMALIZE => 0.6, // (Required) Normalization of (mixed) audio samples - see threshold parameter for normalizeSample(). - * WavFile::FILTER_DEGRADE => 0.9 // (Required) Introduce random noise. The quality relative to the amplitude. 1 = no noise, 0 = max. noise. - * ), - * 0, // (Optional) The block number of this WavFile to start with. - * null // (Optional) The number of blocks to process. - * ); - * - * - * @param array $filters (Required) An array of 1 or more audio processing filters. - * @param int $blockOffset (Optional) The block number to start precessing from. - * @param int $numBlocks (Optional) The maximum number of blocks to process. - * @throws WavFileException - */ - public function filter($filters, $blockOffset = 0, $numBlocks = null) - { - // check preconditions - $totalBlocks = $this->getNumBlocks(); - $numChannels = $this->getNumChannels(); - if (is_null($numBlocks)) $numBlocks = $totalBlocks - $blockOffset; - - if (!is_array($filters) || empty($filters) || $blockOffset < 0 || $blockOffset > $totalBlocks || $numBlocks <= 0) { - // nothing to do - return $this; - } - - // check filtes - $filter_mix = false; - if (array_key_exists(self::FILTER_MIX, $filters)) { - if (!is_array($filters[self::FILTER_MIX])) { - // assume the 'wav' parameter - $filters[self::FILTER_MIX] = array('wav' => $filters[self::FILTER_MIX]); - } - - $mix_wav = @$filters[self::FILTER_MIX]['wav']; - if (!($mix_wav instanceof WavFile)) { - throw new WavFileException("WavFile to mix is missing or invalid."); - } elseif ($mix_wav->getSampleRate() != $this->getSampleRate()) { - throw new WavFileException("Sample rate of WavFile to mix does not match."); - } else if ($mix_wav->getNumChannels() != $this->getNumChannels()) { - throw new WavFileException("Number of channels of WavFile to mix does not match."); - } - - $mix_loop = @$filters[self::FILTER_MIX]['loop']; - if (is_null($mix_loop)) $mix_loop = false; - - $mix_blockOffset = @$filters[self::FILTER_MIX]['blockOffset']; - if (is_null($mix_blockOffset)) $mix_blockOffset = 0; - - $mix_totalBlocks = $mix_wav->getNumBlocks(); - $mix_numBlocks = @$filters[self::FILTER_MIX]['numBlocks']; - if (is_null($mix_numBlocks)) $mix_numBlocks = $mix_loop ? $mix_totalBlocks : $mix_totalBlocks - $mix_blockOffset; - $mix_maxBlock = min($mix_blockOffset + $mix_numBlocks, $mix_totalBlocks); - - $filter_mix = true; - } - - $filter_normalize = false; - if (array_key_exists(self::FILTER_NORMALIZE, $filters)) { - $normalize_threshold = @$filters[self::FILTER_NORMALIZE]; - - if (!is_null($normalize_threshold) && abs($normalize_threshold) != 1) $filter_normalize = true; - } - - $filter_degrade = false; - if (array_key_exists(self::FILTER_DEGRADE, $filters)) { - $degrade_quality = @$filters[self::FILTER_DEGRADE]; - if (is_null($degrade_quality)) $degrade_quality = 1; - - if ($degrade_quality >= 0 && $degrade_quality < 1) $filter_degrade = true; - } - - - // loop through all sample blocks - for ($block = 0; $block < $numBlocks; ++$block) { - // loop through all channels - for ($channel = 1; $channel <= $numChannels; ++$channel) { - // read current sample - $currentBlock = $blockOffset + $block; - $sampleFloat = $this->getSampleValue($currentBlock, $channel); - - - /************* MIX FILTER ***********************/ - if ($filter_mix) { - if ($mix_loop) { - $mixBlock = ($mix_blockOffset + ($block % $mix_numBlocks)) % $mix_totalBlocks; - } else { - $mixBlock = $mix_blockOffset + $block; - } - - if ($mixBlock < $mix_maxBlock) { - $sampleFloat += $mix_wav->getSampleValue($mixBlock, $channel); - } - } - - /************* NORMALIZE FILTER *******************/ - if ($filter_normalize) { - $sampleFloat = $this->normalizeSample($sampleFloat, $normalize_threshold); - } - - /************* DEGRADE FILTER *******************/ - if ($filter_degrade) { - $sampleFloat += rand(1000000 * ($degrade_quality - 1), 1000000 * (1 - $degrade_quality)) / 1000000; - } - - - // write current sample - $this->setSampleValue($sampleFloat, $currentBlock, $channel); - } - } - - return $this; - } - - /** - * Append a wav file to the current wav.
- * The wav files must have the same sample rate, number of bits per sample, and number of channels. - * - * @param WavFile $wav (Required) The wav file to append. - * @throws WavFileException - */ - public function appendWav(WavFile $wav) { - // basic checks - if ($wav->getSampleRate() != $this->getSampleRate()) { - throw new WavFileException("Sample rate for wav files do not match."); - } else if ($wav->getBitsPerSample() != $this->getBitsPerSample()) { - throw new WavFileException("Bits per sample for wav files do not match."); - } else if ($wav->getNumChannels() != $this->getNumChannels()) { - throw new WavFileException("Number of channels for wav files do not match."); - } - - $this->_samples .= $wav->_samples; - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - return $this; - } - - /** - * Mix 2 wav files together.
- * Both wavs must have the same sample rate and same number of channels. - * - * @param WavFile $wav (Required) The WavFile to mix. - * @param float $normalizeThreshold (Optional) See normalizeSample for an explanation. - * @throws WavFileException - */ - public function mergeWav(WavFile $wav, $normalizeThreshold = null) { - return $this->filter(array( - WavFile::FILTER_MIX => $wav, - WavFile::FILTER_NORMALIZE => $normalizeThreshold - )); - } - - /** - * Add silence to the wav file. - * - * @param float $duration (Optional) How many seconds of silence. If negative, add to the beginning of the file. Defaults to 1s. - */ - public function insertSilence($duration = 1.0) - { - $numSamples = $this->getSampleRate() * abs($duration); - $numChannels = $this->getNumChannels(); - - $data = str_repeat(self::packSample($this->getZeroAmplitude(), $this->getBitsPerSample()), $numSamples * $numChannels); - if ($duration >= 0) { - $this->_samples .= $data; - } else { - $this->_samples = $data . $this->_samples; - } - - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - return $this; - } - - /** - * Degrade the quality of the wav file by introducing random noise. - * - * @param float quality (Optional) The quality relative to the amplitude. 1 = no noise, 0 = max. noise. - */ - public function degrade($quality = 1.0) - { - return $this->filter(self::FILTER_DEGRADE, array( - WavFile::FILTER_DEGRADE => $quality - )); - } - - /** - * Generate noise at the end of the wav for the specified duration and volume. - * - * @param float $duration (Optional) Number of seconds of noise to generate. - * @param float $percent (Optional) The percentage of the maximum amplitude to use. 100 = full amplitude. - */ - public function generateNoise($duration = 1.0, $percent = 100) - { - $numChannels = $this->getNumChannels(); - $numSamples = $this->getSampleRate() * $duration; - $minAmp = $this->getMinAmplitude(); - $maxAmp = $this->getMaxAmplitude(); - $bitDepth = $this->getBitsPerSample(); - - for ($s = 0; $s < $numSamples; ++$s) { - if ($bitDepth == 32) { - $val = rand(-$percent * 10000, $percent * 10000) / 1000000; - } else { - $val = rand($minAmp, $maxAmp); - $val = (int)($val * $percent / 100); - } - - $this->_samples .= str_repeat(self::packSample($val, $bitDepth), $numChannels); - } - - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - return $this; - } - - /** - * Convert sample data to different bits per sample. - * - * @param int $bitsPerSample (Required) The new number of bits per sample; - * @throws WavFileException - */ - public function convertBitsPerSample($bitsPerSample) { - if ($this->getBitsPerSample() == $bitsPerSample) { - return $this; - } - - $tempWav = new WavFile($this->getNumChannels(), $this->getSampleRate(), $bitsPerSample); - $tempWav->filter( - array(self::FILTER_MIX => $this), - 0, - $this->getNumBlocks() - ); - - $this->setSamples() // implicit setDataSize(), setSize(), setActualSize(), setNumBlocks() - ->setBitsPerSample($bitsPerSample); // implicit setValidBitsPerSample(), setAudioFormat(), setAudioSubFormat(), setFmtChunkSize(), setFactChunkSize(), setSize(), setActualSize(), setDataOffset(), setByteRate(), setBlockAlign(), setNumBlocks() - $this->_samples = $tempWav->_samples; - $this->setDataSize(); // implicit setSize(), setActualSize(), setNumBlocks() - - return $this; - } - - - /*%******************************************************************************************%*/ - // Miscellaneous methods - - /** - * Output information about the wav object. - */ - public function displayInfo() - { - $s = "File Size: %u\n" - ."Chunk Size: %u\n" - ."fmt Subchunk Size: %u\n" - ."Extended fmt Size: %u\n" - ."fact Subchunk Size: %u\n" - ."Data Offset: %u\n" - ."Data Size: %u\n" - ."Audio Format: %s\n" - ."Audio SubFormat: %s\n" - ."Channels: %u\n" - ."Channel Mask: 0x%s\n" - ."Sample Rate: %u\n" - ."Bits Per Sample: %u\n" - ."Valid Bits Per Sample: %u\n" - ."Sample Block Size: %u\n" - ."Number of Sample Blocks: %u\n" - ."Byte Rate: %uBps\n"; - - $s = sprintf($s, $this->getActualSize(), - $this->getChunkSize(), - $this->getFmtChunkSize(), - $this->getFmtExtendedSize(), - $this->getFactChunkSize(), - $this->getDataOffset(), - $this->getDataSize(), - $this->getAudioFormat() == self::WAVE_FORMAT_PCM ? 'PCM' : ($this->getAudioFormat() == self::WAVE_FORMAT_IEEE_FLOAT ? 'IEEE FLOAT' : 'EXTENSIBLE'), - $this->getAudioSubFormat() == self::WAVE_SUBFORMAT_PCM ? 'PCM' : 'IEEE FLOAT', - $this->getNumChannels(), - dechex($this->getChannelMask()), - $this->getSampleRate(), - $this->getBitsPerSample(), - $this->getValidBitsPerSample(), - $this->getBlockAlign(), - $this->getNumBlocks(), - $this->getByteRate()); - - if (php_sapi_name() == 'cli') { - return $s; - } else { - return nl2br($s); - } - } -} - - -/*%******************************************************************************************%*/ -// Exceptions - -/** - * WavFileException indicates an illegal state or argument in this class. - */ -class WavFileException extends Exception {} - -/** - * WavFormatException indicates a malformed or unsupported wav file header. - */ -class WavFormatException extends WavFileException {} diff --git a/captcha/audio/0.wav b/captcha/audio/0.wav deleted file mode 100644 index 7cd0b37..0000000 Binary files a/captcha/audio/0.wav and /dev/null differ diff --git a/captcha/audio/1.wav b/captcha/audio/1.wav deleted file mode 100644 index b589080..0000000 Binary files a/captcha/audio/1.wav and /dev/null differ diff --git a/captcha/audio/10.wav b/captcha/audio/10.wav deleted file mode 100644 index 526e55d..0000000 Binary files a/captcha/audio/10.wav and /dev/null differ diff --git a/captcha/audio/11.wav b/captcha/audio/11.wav deleted file mode 100644 index 587268e..0000000 Binary files a/captcha/audio/11.wav and /dev/null differ diff --git a/captcha/audio/12.wav b/captcha/audio/12.wav deleted file mode 100644 index 346908a..0000000 Binary files a/captcha/audio/12.wav and /dev/null differ diff --git a/captcha/audio/13.wav b/captcha/audio/13.wav deleted file mode 100644 index 88eaf08..0000000 Binary files a/captcha/audio/13.wav and /dev/null differ diff --git a/captcha/audio/14.wav b/captcha/audio/14.wav deleted file mode 100644 index b179d33..0000000 Binary files a/captcha/audio/14.wav and /dev/null differ diff --git a/captcha/audio/15.wav b/captcha/audio/15.wav deleted file mode 100644 index 2e2c1b6..0000000 Binary files a/captcha/audio/15.wav and /dev/null differ diff --git a/captcha/audio/16.wav b/captcha/audio/16.wav deleted file mode 100644 index 5481083..0000000 Binary files a/captcha/audio/16.wav and /dev/null differ diff --git a/captcha/audio/17.wav b/captcha/audio/17.wav deleted file mode 100644 index 2e2405b..0000000 Binary files a/captcha/audio/17.wav and /dev/null differ diff --git a/captcha/audio/18.wav b/captcha/audio/18.wav deleted file mode 100644 index e25da9f..0000000 Binary files a/captcha/audio/18.wav and /dev/null differ diff --git a/captcha/audio/19.wav b/captcha/audio/19.wav deleted file mode 100644 index 4d6231e..0000000 Binary files a/captcha/audio/19.wav and /dev/null differ diff --git a/captcha/audio/2.wav b/captcha/audio/2.wav deleted file mode 100644 index 8ef091d..0000000 Binary files a/captcha/audio/2.wav and /dev/null differ diff --git a/captcha/audio/20.wav b/captcha/audio/20.wav deleted file mode 100644 index a660611..0000000 Binary files a/captcha/audio/20.wav and /dev/null differ diff --git a/captcha/audio/3.wav b/captcha/audio/3.wav deleted file mode 100644 index 56b6eb9..0000000 Binary files a/captcha/audio/3.wav and /dev/null differ diff --git a/captcha/audio/4.wav b/captcha/audio/4.wav deleted file mode 100644 index 1622b39..0000000 Binary files a/captcha/audio/4.wav and /dev/null differ diff --git a/captcha/audio/5.wav b/captcha/audio/5.wav deleted file mode 100644 index 1eb0022..0000000 Binary files a/captcha/audio/5.wav and /dev/null differ diff --git a/captcha/audio/6.wav b/captcha/audio/6.wav deleted file mode 100644 index 3682320..0000000 Binary files a/captcha/audio/6.wav and /dev/null differ diff --git a/captcha/audio/7.wav b/captcha/audio/7.wav deleted file mode 100644 index fe530bb..0000000 Binary files a/captcha/audio/7.wav and /dev/null differ diff --git a/captcha/audio/8.wav b/captcha/audio/8.wav deleted file mode 100644 index 1206aa7..0000000 Binary files a/captcha/audio/8.wav and /dev/null differ diff --git a/captcha/audio/9.wav b/captcha/audio/9.wav deleted file mode 100644 index ae0172b..0000000 Binary files a/captcha/audio/9.wav and /dev/null differ diff --git a/captcha/audio/A.wav b/captcha/audio/A.wav deleted file mode 100644 index a7fafe0..0000000 Binary files a/captcha/audio/A.wav and /dev/null differ diff --git a/captcha/audio/B.wav b/captcha/audio/B.wav deleted file mode 100644 index cefb619..0000000 Binary files a/captcha/audio/B.wav and /dev/null differ diff --git a/captcha/audio/C.wav b/captcha/audio/C.wav deleted file mode 100644 index affc191..0000000 Binary files a/captcha/audio/C.wav and /dev/null differ diff --git a/captcha/audio/D.wav b/captcha/audio/D.wav deleted file mode 100644 index 87efc95..0000000 Binary files a/captcha/audio/D.wav and /dev/null differ diff --git a/captcha/audio/E.wav b/captcha/audio/E.wav deleted file mode 100644 index 1af4e02..0000000 Binary files a/captcha/audio/E.wav and /dev/null differ diff --git a/captcha/audio/F.wav b/captcha/audio/F.wav deleted file mode 100644 index d139b32..0000000 Binary files a/captcha/audio/F.wav and /dev/null differ diff --git a/captcha/audio/G.wav b/captcha/audio/G.wav deleted file mode 100644 index b54d507..0000000 Binary files a/captcha/audio/G.wav and /dev/null differ diff --git a/captcha/audio/H.wav b/captcha/audio/H.wav deleted file mode 100644 index 99f1318..0000000 Binary files a/captcha/audio/H.wav and /dev/null differ diff --git a/captcha/audio/I.wav b/captcha/audio/I.wav deleted file mode 100644 index 809c560..0000000 Binary files a/captcha/audio/I.wav and /dev/null differ diff --git a/captcha/audio/J.wav b/captcha/audio/J.wav deleted file mode 100644 index 85ef1b6..0000000 Binary files a/captcha/audio/J.wav and /dev/null differ diff --git a/captcha/audio/K.wav b/captcha/audio/K.wav deleted file mode 100644 index 3a40e2d..0000000 Binary files a/captcha/audio/K.wav and /dev/null differ diff --git a/captcha/audio/L.wav b/captcha/audio/L.wav deleted file mode 100644 index e56c0e3..0000000 Binary files a/captcha/audio/L.wav and /dev/null differ diff --git a/captcha/audio/M.wav b/captcha/audio/M.wav deleted file mode 100644 index a4dd9b5..0000000 Binary files a/captcha/audio/M.wav and /dev/null differ diff --git a/captcha/audio/MINUS.wav b/captcha/audio/MINUS.wav deleted file mode 100644 index cb2c086..0000000 Binary files a/captcha/audio/MINUS.wav and /dev/null differ diff --git a/captcha/audio/N.wav b/captcha/audio/N.wav deleted file mode 100644 index 807a947..0000000 Binary files a/captcha/audio/N.wav and /dev/null differ diff --git a/captcha/audio/O.wav b/captcha/audio/O.wav deleted file mode 100644 index 538be6b..0000000 Binary files a/captcha/audio/O.wav and /dev/null differ diff --git a/captcha/audio/P.wav b/captcha/audio/P.wav deleted file mode 100644 index 77696ac..0000000 Binary files a/captcha/audio/P.wav and /dev/null differ diff --git a/captcha/audio/PLUS.wav b/captcha/audio/PLUS.wav deleted file mode 100644 index f340b6c..0000000 Binary files a/captcha/audio/PLUS.wav and /dev/null differ diff --git a/captcha/audio/Q.wav b/captcha/audio/Q.wav deleted file mode 100644 index 33b3c89..0000000 Binary files a/captcha/audio/Q.wav and /dev/null differ diff --git a/captcha/audio/R.wav b/captcha/audio/R.wav deleted file mode 100644 index b3523c5..0000000 Binary files a/captcha/audio/R.wav and /dev/null differ diff --git a/captcha/audio/S.wav b/captcha/audio/S.wav deleted file mode 100644 index 4147bf9..0000000 Binary files a/captcha/audio/S.wav and /dev/null differ diff --git a/captcha/audio/T.wav b/captcha/audio/T.wav deleted file mode 100644 index d01e529..0000000 Binary files a/captcha/audio/T.wav and /dev/null differ diff --git a/captcha/audio/TIMES.wav b/captcha/audio/TIMES.wav deleted file mode 100644 index 85692b8..0000000 Binary files a/captcha/audio/TIMES.wav and /dev/null differ diff --git a/captcha/audio/U.wav b/captcha/audio/U.wav deleted file mode 100644 index 8ab9d17..0000000 Binary files a/captcha/audio/U.wav and /dev/null differ diff --git a/captcha/audio/V.wav b/captcha/audio/V.wav deleted file mode 100644 index 763e599..0000000 Binary files a/captcha/audio/V.wav and /dev/null differ diff --git a/captcha/audio/W.wav b/captcha/audio/W.wav deleted file mode 100644 index 8e742b6..0000000 Binary files a/captcha/audio/W.wav and /dev/null differ diff --git a/captcha/audio/X.wav b/captcha/audio/X.wav deleted file mode 100644 index 225e690..0000000 Binary files a/captcha/audio/X.wav and /dev/null differ diff --git a/captcha/audio/Y.wav b/captcha/audio/Y.wav deleted file mode 100644 index 9d766ac..0000000 Binary files a/captcha/audio/Y.wav and /dev/null differ diff --git a/captcha/audio/Z.wav b/captcha/audio/Z.wav deleted file mode 100644 index 69be2dd..0000000 Binary files a/captcha/audio/Z.wav and /dev/null differ diff --git a/captcha/audio/error.wav b/captcha/audio/error.wav deleted file mode 100644 index 35209ab..0000000 Binary files a/captcha/audio/error.wav and /dev/null differ diff --git a/captcha/audio/noise/check-point-1.wav b/captcha/audio/noise/check-point-1.wav deleted file mode 100644 index 9533b12..0000000 Binary files a/captcha/audio/noise/check-point-1.wav and /dev/null differ diff --git a/captcha/audio/noise/crowd-talking-1.wav b/captcha/audio/noise/crowd-talking-1.wav deleted file mode 100644 index 7f451df..0000000 Binary files a/captcha/audio/noise/crowd-talking-1.wav and /dev/null differ diff --git a/captcha/audio/noise/crowd-talking-6.wav b/captcha/audio/noise/crowd-talking-6.wav deleted file mode 100644 index fd9a10d..0000000 Binary files a/captcha/audio/noise/crowd-talking-6.wav and /dev/null differ diff --git a/captcha/audio/noise/crowd-talking-7.wav b/captcha/audio/noise/crowd-talking-7.wav deleted file mode 100644 index 986f6ae..0000000 Binary files a/captcha/audio/noise/crowd-talking-7.wav and /dev/null differ diff --git a/captcha/audio/noise/kids-playing-1.wav b/captcha/audio/noise/kids-playing-1.wav deleted file mode 100644 index cb9d17b..0000000 Binary files a/captcha/audio/noise/kids-playing-1.wav and /dev/null differ diff --git a/captcha/backgrounds/bg3.jpg b/captcha/backgrounds/bg3.jpg deleted file mode 100644 index a2d62d6..0000000 Binary files a/captcha/backgrounds/bg3.jpg and /dev/null differ diff --git a/captcha/backgrounds/bg4.jpg b/captcha/backgrounds/bg4.jpg deleted file mode 100644 index 37a22f8..0000000 Binary files a/captcha/backgrounds/bg4.jpg and /dev/null differ diff --git a/captcha/backgrounds/bg5.jpg b/captcha/backgrounds/bg5.jpg deleted file mode 100644 index 0a04181..0000000 Binary files a/captcha/backgrounds/bg5.jpg and /dev/null differ diff --git a/captcha/backgrounds/bg6.png b/captcha/backgrounds/bg6.png deleted file mode 100644 index 22f9d67..0000000 Binary files a/captcha/backgrounds/bg6.png and /dev/null differ diff --git a/captcha/captcha.html b/captcha/captcha.html deleted file mode 100644 index fef088d..0000000 --- a/captcha/captcha.html +++ /dev/null @@ -1,13 +0,0 @@ - - -

- CAPTCHA Image - - - -   - Reload Image
- Enter Code*:
- -

- \ No newline at end of file diff --git a/captcha/database/.htaccess b/captcha/database/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/captcha/database/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/captcha/database/index.html b/captcha/database/index.html deleted file mode 100644 index 8d1c8b6..0000000 --- a/captcha/database/index.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/captcha/database/securimage.sqlite b/captcha/database/securimage.sqlite deleted file mode 100644 index 783f48e..0000000 Binary files a/captcha/database/securimage.sqlite and /dev/null differ diff --git a/captcha/example_form.ajax.php b/captcha/example_form.ajax.php deleted file mode 100644 index 31cc1f8..0000000 --- a/captcha/example_form.ajax.php +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Securimage Example Form - - - - - - - - -
-Example Form - -

- This is an example PHP form that processes user information, checks for errors, and validates the captcha code.
- This example form also demonstrates how to submit a form to itself to display error messages. -

- - - -
- - -

- Name*:
- -

- -

- Email*:
- -

- -

- URL:
- -

- -

- Message*:
- -

- -

- CAPTCHA Image - - - -   - Reload Image
- Enter Code*:
- -

- -

-
- -

- -
-
- - - - - $value) { - if (!is_array($key)) { - // sanitize the input data - if ($key != 'ct_message') $value = strip_tags($value); - $_POST[$key] = htmlspecialchars(stripslashes(trim($value))); - } - } - - $name = @$_POST['ct_name']; // name from the form - $email = @$_POST['ct_email']; // email from the form - $URL = @$_POST['ct_URL']; // url from the form - $message = @$_POST['ct_message']; // the message from the form - $captcha = @$_POST['ct_captcha']; // the user's entry for the captcha code - $name = substr($name, 0, 64); // limit name to 64 characters - - $errors = array(); // initialize empty error array - - if (isset($GLOBALS['DEBUG_MODE']) && $GLOBALS['DEBUG_MODE'] == false) { - // only check for errors if the form is not in debug mode - - if (strlen($name) < 3) { - // name too short, add error - $errors['name_error'] = 'Your name is required'; - } - - if (strlen($email) == 0) { - // no email address given - $errors['email_error'] = 'Email address is required'; - } else if ( !preg_match('/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/i', $email)) { - // invalid email format - $errors['email_error'] = 'Email address entered is invalid'; - } - - if (strlen($message) < 20) { - // message length too short - $errors['message_error'] = 'Please enter a message'; - } - } - - // Only try to validate the captcha if the form has no errors - // This is especially important for ajax calls - if (sizeof($errors) == 0) { - require_once dirname(__FILE__) . '/securimage.php'; - $securimage = new Securimage(); - - if ($securimage->check($captcha) == false) { - $errors['captcha_error'] = 'Incorrect security code entered'; - } - } - - if (sizeof($errors) == 0) { - // no errors, send the form - $time = date('r'); - $message = "A message was submitted from the contact form. The following information was provided.

" - . "Name: $name
" - . "Email: $email
" - . "URL: $URL
" - . "Message:
" - . "
$message
" - . "

IP Address: {$_SERVER['REMOTE_ADDR']}
" - . "Time: $time
" - . "Browser: {$_SERVER['HTTP_USER_AGENT']}
"; - - if (isset($GLOBALS['DEBUG_MODE']) && $GLOBALS['DEBUG_MODE'] == false) { - // send the message with mail() - mail($GLOBALS['ct_recipient'], $GLOBALS['ct_msg_subject'], $message, "From: {$GLOBALS['ct_recipient']}\r\nReply-To: {$email}\r\nContent-type: text/html; charset=ISO-8859-1\r\nMIME-Version: 1.0"); - } - - $return = array('error' => 0, 'message' => 'OK'); - die(json_encode($return)); - } else { - $errmsg = ''; - foreach($errors as $key => $error) { - // set up error messages to display with each field - $errmsg .= " - {$error}\n"; - } - - $return = array('error' => 1, 'message' => $errmsg); - die(json_encode($return)); - } - } // POST -} // function process_si_contact_form() diff --git a/captcha/example_form.php b/captcha/example_form.php deleted file mode 100644 index 10ba189..0000000 --- a/captcha/example_form.php +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - Securimage Example Form - - - - -
-Example Form - -

- This is an example PHP form that processes user information, checks for errors, and validates the captcha code.
- This example form also demonstrates how to submit a form to itself to display error messages. -

- - -There was a problem with your submission. Errors are displayed below in red.

- -The captcha was correct and the message has been sent!

- - -
- - -

- Name*:   
- -

- -

- Email*:   
- -

- -

- URL:   
- -

- -

- Message*:   
- -

- -

- CAPTCHA Image - - - -   - Reload Image
- Enter Code*:
- - -

- -

-
- -

- -
-
- - - - - $value) { - if (!is_array($key)) { - // sanitize the input data - if ($key != 'ct_message') $value = strip_tags($value); - $_POST[$key] = htmlspecialchars(stripslashes(trim($value))); - } - } - - $name = @$_POST['ct_name']; // name from the form - $email = @$_POST['ct_email']; // email from the form - $URL = @$_POST['ct_URL']; // url from the form - $message = @$_POST['ct_message']; // the message from the form - $captcha = @$_POST['ct_captcha']; // the user's entry for the captcha code - $name = substr($name, 0, 64); // limit name to 64 characters - - $errors = array(); // initialize empty error array - - if (isset($GLOBALS['DEBUG_MODE']) && $GLOBALS['DEBUG_MODE'] == false) { - // only check for errors if the form is not in debug mode - - if (strlen($name) < 3) { - // name too short, add error - $errors['name_error'] = 'Your name is required'; - } - - if (strlen($email) == 0) { - // no email address given - $errors['email_error'] = 'Email address is required'; - } else if ( !preg_match('/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/i', $email)) { - // invalid email format - $errors['email_error'] = 'Email address entered is invalid'; - } - - if (strlen($message) < 20) { - // message length too short - $errors['message_error'] = 'Please enter a message'; - } - } - - // Only try to validate the captcha if the form has no errors - // This is especially important for ajax calls - if (sizeof($errors) == 0) { - require_once dirname(__FILE__) . '/securimage.php'; - $securimage = new Securimage(); - - if ($securimage->check($captcha) == false) { - $errors['captcha_error'] = 'Incorrect security code entered
'; - } - } - - if (sizeof($errors) == 0) { - // no errors, send the form - $time = date('r'); - $message = "A message was submitted from the contact form. The following information was provided.

" - . "Name: $name
" - . "Email: $email
" - . "URL: $URL
" - . "Message:
" - . "
$message
" - . "

IP Address: {$_SERVER['REMOTE_ADDR']}
" - . "Time: $time
" - . "Browser: {$_SERVER['HTTP_USER_AGENT']}
"; - - $message = wordwrap($message, 70); - - if (isset($GLOBALS['DEBUG_MODE']) && $GLOBALS['DEBUG_MODE'] == false) { - // send the message with mail() - mail($GLOBALS['ct_recipient'], $GLOBALS['ct_msg_subject'], $message, "From: {$GLOBALS['ct_recipient']}\r\nReply-To: {$email}\r\nContent-type: text/html; charset=ISO-8859-1\r\nMIME-Version: 1.0"); - } - - $_SESSION['ctform']['error'] = false; // no error with form - $_SESSION['ctform']['success'] = true; // message sent - } else { - // save the entries, this is to re-populate the form - $_SESSION['ctform']['ct_name'] = $name; // save name from the form submission - $_SESSION['ctform']['ct_email'] = $email; // save email - $_SESSION['ctform']['ct_URL'] = $URL; // save URL - $_SESSION['ctform']['ct_message'] = $message; // save message - - foreach($errors as $key => $error) { - // set up error messages to display with each field - $_SESSION['ctform'][$key] = "$error"; - } - - $_SESSION['ctform']['error'] = true; // set error floag - } - } // POST -} - -$_SESSION['ctform']['success'] = false; // clear success value after running diff --git a/captcha/images/audio_icon.png b/captcha/images/audio_icon.png deleted file mode 100644 index 9922ef1..0000000 Binary files a/captcha/images/audio_icon.png and /dev/null differ diff --git a/captcha/images/refresh.png b/captcha/images/refresh.png deleted file mode 100644 index f5e7d82..0000000 Binary files a/captcha/images/refresh.png and /dev/null differ diff --git a/captcha/index.php b/captcha/index.php deleted file mode 100644 index 090bbd5..0000000 --- a/captcha/index.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/captcha/securimage.php b/captcha/securimage.php deleted file mode 100644 index 459a512..0000000 --- a/captcha/securimage.php +++ /dev/null @@ -1,1857 +0,0 @@ - - * File: securimage.php
- * - * Copyright (c) 2012, Drew Phillips - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Any modifications to the library should be indicated clearly in the source code - * to inform users that the changes are not a part of the original software.

- * - * If you found this script useful, please take a quick moment to rate it.
- * http://www.hotscripts.com/rate/49400.html Thanks. - * - * @link http://www.phpcaptcha.org Securimage PHP CAPTCHA - * @link http://www.phpcaptcha.org/latest.zip Download Latest Version - * @link http://www.phpcaptcha.org/Securimage_Docs/ Online Documentation - * @copyright 2012 Drew Phillips - * @author Drew Phillips - * @version 3.2RC3 (May 2012) - * @package Securimage - * - */ - -/** - ChangeLog - - 3.2RC3 - - Fix canSendHeaders() check which was breaking if a PHP startup error was issued - - 3.2RC2 - - Add error handler (https://github.com/dapphp/securimage/issues/15) - - Fix flash examples to use the correct value name for audio parameter - - 3.2RC1 - - New audio captcha code. Faster, fully dynamic audio, full WAV support - (Paul Voegler, Drew Phillips) - - New Flash audio streaming button. User defined image and size supported - - Additional options for customizing captcha (noise_level, send_headers, - no_exit, no_session, display_value - - Add captcha ID support. Uses sqlite and unique captcha IDs to track captchas, - no session used - - Add static methods for creating and validating captcha by ID - - Automatic clearing of old codes from SQLite database - - 3.0.3Beta - - Add improved mixing function to WavFile class (Paul Voegler) - - Improve performance and security of captcha audio (Paul Voegler, Drew Phillips) - - Add option to use random file as background noise in captcha audio - - Add new securimage options for audio files - - 3.0.2Beta - - Fix issue with session variables when upgrading from 2.0 - 3.0 - - Improve audio captcha, switch to use WavFile class, make mathematical captcha audio work - - 3.0.1 - - Bugfix: removed use of deprecated variable in addSignature method that would cause errors with display_errors on - - 3.0 - - Rewrite class using PHP5 OOP - - Remove support for GD fonts, require FreeType - - Remove support for multi-color codes - - Add option to make codes case-sensitive - - Add namespaces to support multiple captchas on a single page or page specific captchas - - Add option to show simple math problems instead of codes - - Remove support for mp3 files due to vulnerability in decoding mp3 audio files - - Create new flash file to stream wav files instead of mp3 - - Changed to BSD license - - 2.0.2 - - Fix pathing to make integration into libraries easier (Nathan Phillip Brink ohnobinki@ohnopublishing.net) - - 2.0.1 - - Add support for browsers with cookies disabled (requires php5, sqlite) maps users to md5 hashed ip addresses and md5 hashed codes for security - - Add fallback to gd fonts if ttf support is not enabled or font file not found (Mike Challis http://www.642weather.com/weather/scripts.php) - - Check for previous definition of image type constants (Mike Challis) - - Fix mime type settings for audio output - - Fixed color allocation issues with multiple colors and background images, consolidate allocation to one function - - Ability to let codes expire after a given length of time - - Allow HTML color codes to be passed to Securimage_Color (suggested by Mike Challis) - - 2.0.0 - - Add mathematical distortion to characters (using code from HKCaptcha) - - Improved session support - - Added Securimage_Color class for easier color definitions - - Add distortion to audio output to prevent binary comparison attack (proposed by Sven "SavageTiger" Hagemann [insecurity.nl]) - - Flash button to stream mp3 audio (Douglas Walsh www.douglaswalsh.net) - - Audio output is mp3 format by default - - Change font to AlteHaasGrotesk by yann le coroller - - Some code cleanup - - 1.0.4 (unreleased) - - Ability to output audible codes in mp3 format to stream from flash - - 1.0.3.1 - - Error reading from wordlist in some cases caused words to be cut off 1 letter short - - 1.0.3 - - Removed shadow_text from code which could cause an undefined property error due to removal from previous version - - 1.0.2 - - Audible CAPTCHA Code wav files - - Create codes from a word list instead of random strings - - 1.0 - - Added the ability to use a selected character set, rather than a-z0-9 only. - - Added the multi-color text option to use different colors for each letter. - - Switched to automatic session handling instead of using files for code storage - - Added GD Font support if ttf support is not available. Can use internal GD fonts or load new ones. - - Added the ability to set line thickness - - Added option for drawing arced lines over letters - - Added ability to choose image type for output - - */ - - -/** - * Securimage CAPTCHA Class. - * - * @version 3.0 - * @package Securimage - * @subpackage classes - * @author Drew Phillips - * - */ -class Securimage -{ - // All of the public variables below are securimage options - // They can be passed as an array to the Securimage constructor, set below, - // or set from securimage_show.php and securimage_play.php - - /** - * Renders captcha as a JPEG image - * @var int - */ - const SI_IMAGE_JPEG = 1; - /** - * Renders captcha as a PNG image (default) - * @var int - */ - const SI_IMAGE_PNG = 2; - /** - * Renders captcha as a GIF image - * @var int - */ - const SI_IMAGE_GIF = 3; - - /** - * Create a normal alphanumeric captcha - * @var int - */ - const SI_CAPTCHA_STRING = 0; - /** - * Create a captcha consisting of a simple math problem - * @var int - */ - const SI_CAPTCHA_MATHEMATIC = 1; - - /** - * The width of the captcha image - * @var int - */ - public $image_width = 215; - /** - * The height of the captcha image - * @var int - */ - public $image_height = 80; - /** - * The type of the image, default = png - * @var int - */ - public $image_type = self::SI_IMAGE_PNG; - - /** - * The background color of the captcha - * @var Securimage_Color - */ - public $image_bg_color = '#ffffff'; - /** - * The color of the captcha text - * @var Securimage_Color - */ - public $text_color = '#707070'; - /** - * The color of the lines over the captcha - * @var Securimage_Color - */ - public $line_color = '#707070'; - /** - * The color of the noise that is drawn - * @var Securimage_Color - */ - public $noise_color = '#707070'; - - /** - * How transparent to make the text 0 = completely opaque, 100 = invisible - * @var int - */ - public $text_transparency_percentage = 50; - /** - * Whether or not to draw the text transparently, true = use transparency, false = no transparency - * @var bool - */ - public $use_transparent_text = false; - - /** - * The length of the captcha code - * @var int - */ - public $code_length = 6; - /** - * Whether the captcha should be case sensitive (not recommended, use only for maximum protection) - * @var bool - */ - public $case_sensitive = false; - /** - * The character set to use for generating the captcha code - * @var string - */ - public $charset = 'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789'; - /** - * How long in seconds a captcha remains valid, after this time it will not be accepted - * @var unknown_type - */ - public $expiry_time = 900; - - /** - * The session name securimage should use, only set this if your application uses a custom session name - * It is recommended to set this value below so it is used by all securimage scripts - * @var string - */ - public $session_name = null; - - /** - * true to use the wordlist file, false to generate random captcha codes - * @var bool - */ - public $use_wordlist = false; - - /** - * The level of distortion, 0.75 = normal, 1.0 = very high distortion - * @var double - */ - public $perturbation = 0.75; - /** - * How many lines to draw over the captcha code to increase security - * @var int - */ - public $num_lines = 8; - /** - * The level of noise (random dots) to place on the image, 0-10 - * @var int - */ - public $noise_level = 0; - - /** - * The signature text to draw on the bottom corner of the image - * @var string - */ - public $image_signature = ''; - /** - * The color of the signature text - * @var Securimage_Color - */ - public $signature_color = '#707070'; - /** - * The path to the ttf font file to use for the signature text, defaults to $ttf_file (AHGBold.ttf) - * @var string - */ - public $signature_font; - - /** - * Use an SQLite database to store data (for users that do not support cookies) - * @var bool - */ - public $use_sqlite_db = false; - - /** - * The type of captcha to create, either alphanumeric, or a math problem
- * Securimage::SI_CAPTCHA_STRING or Securimage::SI_CAPTCHA_MATHEMATIC - * @var int - */ - public $captcha_type = self::SI_CAPTCHA_STRING; // or self::SI_CAPTCHA_MATHEMATIC; - - /** - * The captcha namespace, use this if you have multiple forms on a single page, blank if you do not use multiple forms on one page - * @var string - * - * namespace = 'contact_form'; - * - * // in form validator - * $img->namespace = 'contact_form'; - * if ($img->check($code) == true) { - * echo "Valid!"; - * } - * - */ - public $namespace; - - /** - * The font file to use to draw the captcha code, leave blank for default font AHGBold.ttf - * @var string - */ - public $ttf_file; - /** - * The path to the wordlist file to use, leave blank for default words/words.txt - * @var string - */ - public $wordlist_file; - /** - * The directory to scan for background images, if set a random background will be chosen from this folder - * @var string - */ - public $background_directory; - /** - * The path to the SQLite database file to use, if $use_sqlite_database = true, should be chmod 666 - * @var string - */ - public $sqlite_database; - /** - * The path to the securimage audio directory, can be set in securimage_play.php - * @var string - * - * $img->audio_path = '/home/yoursite/public_html/securimage/audio/'; - * - */ - public $audio_path; - /** - * The path to the directory containing audio files that will be selected - * randomly and mixed with the captcha audio. - * - * @var string - */ - public $audio_noise_path; - /** - * Whether or not to mix background noise files into captcha audio (true = mix, false = no) - * Mixing random background audio with noise can help improve security of audio captcha. - * Default: securimage/audio/noise - * - * @since 3.0.3 - * @see Securimage::$audio_noise_path - * @var bool - */ - public $audio_use_noise; - /** - * The method and threshold (or gain factor) used to normalize the mixing with background noise. - * See http://www.voegler.eu/pub/audio/ for more information. - * - * Valid:
    - *
  • >= 1 - Normalize by multiplying by the threshold (boost - positive gain).
    - * A value of 1 in effect means no normalization (and results in clipping).
  • - *
  • <= -1 - Normalize by dividing by the the absolute value of threshold (attenuate - negative gain).
    - * A factor of 2 (-2) is about 6dB reduction in volume.
  • - *
  • [0, 1) - (open inverval - not including 1) - The threshold - * above which amplitudes are comressed logarithmically.
    - * e.g. 0.6 to leave amplitudes up to 60% "as is" and compress above.
  • - *
  • (-1, 0) - (open inverval - not including -1 and 0) - The threshold - * above which amplitudes are comressed linearly.
    - * e.g. -0.6 to leave amplitudes up to 60% "as is" and compress above.
- * - * Default: 0.6 - * - * @since 3.0.4 - * @var float - */ - public $audio_mix_normalization = 0.6; - /** - * Whether or not to degrade audio by introducing random noise (improves security of audio captcha) - * Default: true - * - * @since 3.0.3 - * @var bool - */ - public $degrade_audio; - /** - * Minimum delay to insert between captcha audio letters in milliseconds - * - * @since 3.0.3 - * @var float - */ - public $audio_gap_min = 0; - /** - * Maximum delay to insert between captcha audio letters in milliseconds - * - * @since 3.0.3 - * @var float - */ - public $audio_gap_max = 600; - - /** - * Captcha ID if using static captcha - * @var string Unique captcha id - */ - protected static $_captchaId = null; - - protected $im; - protected $tmpimg; - protected $bgimg; - protected $iscale = 5; - - protected $securimage_path = null; - - /** - * The captcha challenge value (either the case-sensitive/insensitive word captcha, or the solution to the math captcha) - * - * @var string Captcha challenge value - */ - protected $code; - - /** - * The display value of the captcha to draw on the image (the word captcha, or the math equation to present to the user) - * - * @var string Captcha display value to draw on the image - */ - protected $code_display; - - /** - * A value that can be passed to the constructor that can be used to generate a captcha image with a given value - * This value does not get stored in the session or database and is only used when calling Securimage::show(). - * If a display_value was passed to the constructor and the captcha image is generated, the display_value will be used - * as the string to draw on the captcha image. Used only if captcha codes are generated and managed by a 3rd party app/library - * - * @var string Captcha code value to display on the image - */ - protected $display_value; - - /** - * Captcha code supplied by user [set from Securimage::check()] - * - * @var string - */ - protected $captcha_code; - - /** - * Flag that can be specified telling securimage not to call exit after generating a captcha image or audio file - * - * @var bool If true, script will not terminate; if false script will terminate (default) - */ - protected $no_exit; - - /** - * Flag indicating whether or not a PHP session should be started and used - * - * @var bool If true, no session will be started; if false, session will be started and used to store data (default) - */ - protected $no_session; - - /** - * Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio - * - * @var bool If true (default) headers will be sent, if false, no headers are sent - */ - protected $send_headers; - - // sqlite database handle (if using sqlite) - protected $sqlite_handle; - - // gd color resources that are allocated for drawing the image - protected $gdbgcolor; - protected $gdtextcolor; - protected $gdlinecolor; - protected $gdsignaturecolor; - - /** - * Create a new securimage object, pass options to set in the constructor.
- * This can be used to display a captcha, play an audible captcha, or validate an entry - * @param array $options - * - * $options = array( - * 'text_color' => new Securimage_Color('#013020'), - * 'code_length' => 5, - * 'num_lines' => 5, - * 'noise_level' => 3, - * 'font_file' => Securimage::getPath() . '/custom.ttf' - * ); - * - * $img = new Securimage($options); - * - */ - public function __construct($options = array()) - { - $this->securimage_path = dirname(__FILE__); - - if (is_array($options) && sizeof($options) > 0) { - foreach($options as $prop => $val) { - if ($prop == 'captchaId') { - Securimage::$_captchaId = $val; - $this->use_sqlite_db = true; - } else { - $this->$prop = $val; - } - } - } - - $this->image_bg_color = $this->initColor($this->image_bg_color, '#ffffff'); - $this->text_color = $this->initColor($this->text_color, '#616161'); - $this->line_color = $this->initColor($this->line_color, '#616161'); - $this->noise_color = $this->initColor($this->noise_color, '#616161'); - $this->signature_color = $this->initColor($this->signature_color, '#616161'); - - if (is_null($this->ttf_file)) { - $this->ttf_file = $this->securimage_path . '/AHGBold.ttf'; - } - - $this->signature_font = $this->ttf_file; - - if (is_null($this->wordlist_file)) { - $this->wordlist_file = $this->securimage_path . '/words/words.txt'; - } - - if (is_null($this->sqlite_database)) { - $this->sqlite_database = $this->securimage_path . '/database/securimage.sqlite'; - } - - if (is_null($this->audio_path)) { - $this->audio_path = $this->securimage_path . '/audio/'; - } - - if (is_null($this->audio_noise_path)) { - $this->audio_noise_path = $this->audio_path . '/noise/'; - } - - if (is_null($this->audio_use_noise)) { - $this->audio_use_noise = true; - } - - if (is_null($this->degrade_audio)) { - $this->degrade_audio = true; - } - - if (is_null($this->code_length) || (int)$this->code_length < 1) { - $this->code_length = 6; - } - - if (is_null($this->perturbation) || !is_numeric($this->perturbation)) { - $this->perturbation = 0.75; - } - - if (is_null($this->namespace) || !is_string($this->namespace)) { - $this->namespace = 'default'; - } - - if (is_null($this->no_exit)) { - $this->no_exit = false; - } - - if (is_null($this->no_session)) { - $this->no_session = false; - } - - if (is_null($this->send_headers)) { - $this->send_headers = true; - } - - if ($this->no_session != true) { - // Initialize session or attach to existing - if ( session_id() == '' ) { // no session has been started yet, which is needed for validation - if (!is_null($this->session_name) && trim($this->session_name) != '') { - session_name(trim($this->session_name)); // set session name if provided - } - session_start(); - } - } - } - - /** - * Return the absolute path to the Securimage directory - * @return string The path to the securimage base directory - */ - public static function getPath() - { - return dirname(__FILE__); - } - - /** - * Generate a new captcha ID or retrieve the current ID - * - * @param $new bool If true, generates a new challenge and returns and ID - * @param $options array Additional options to be passed to Securimage - * - * @return null|string Returns null if no captcha id set and new was false, or string captcha ID - */ - public static function getCaptchaId($new = true, array $options = array()) - { - if ((bool)$new == true) { - $id = sha1(uniqid($_SERVER['REMOTE_ADDR'], true)); - $opts = array('no_session' => true, - 'use_sqlite_db' => true); - if (sizeof($options) > 0) $opts = array_merge($opts, $options); - $si = new self($opts); - Securimage::$_captchaId = $id; - $si->createCode(); - - return $id; - } else { - return Securimage::$_captchaId; - } - } - - /** - * Validate a captcha code input against a captcha ID - * @param string $id The captcha ID to check - * @param string $value The captcha value supplied by the user - * - * @return bool true if the code was valid for the given captcha ID, false if not or if database failed to open - */ - public static function checkByCaptchaId($id, $value) - { - $si = new self(array('captchaId' => $id, - 'no_session' => true, - 'use_sqlite_db' => true)); - - if ($si->openDatabase()) { - $code = $si->getCodeFromDatabase(); - - if (is_array($code)) { - $si->code = $code['code']; - $si->code_display = $code['code_disp']; - } - - if ($si->check($value)) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - - /** - * Used to serve a captcha image to the browser - * @param string $background_image The path to the background image to use - * - * $img = new Securimage(); - * $img->code_length = 6; - * $img->num_lines = 5; - * $img->noise_level = 5; - * - * $img->show(); // sends the image to browser - * exit; - * - */ - public function show($background_image = '') - { - set_error_handler(array(&$this, 'errorHandler')); - - if($background_image != '' && is_readable($background_image)) { - $this->bgimg = $background_image; - } - - $this->doImage(); - } - - /** - * Check a submitted code against the stored value - * @param string $code The captcha code to check - * - * $code = $_POST['code']; - * $img = new Securimage(); - * if ($img->check($code) == true) { - * $captcha_valid = true; - * } else { - * $captcha_valid = false; - * } - * - */ - public function check($code) - { - $this->code_entered = $code; - $this->validate(); - return $this->correct_code; - } - - /** - * Output a wav file of the captcha code to the browser - * - * - * $img = new Securimage(); - * $img->outputAudioFile(); // outputs a wav file to the browser - * exit; - * - */ - public function outputAudioFile() - { - set_error_handler(array(&$this, 'errorHandler')); - - require_once dirname(__FILE__) . '/WavFile.php'; - - try { - $audio = $this->getAudibleCode(); - } catch (Exception $ex) { - if (($fp = @fopen(dirname(__FILE__) . '/si.error_log', 'a+')) !== false) { - fwrite($fp, date('Y-m-d H:i:s') . ': Securimage audio error "' . $ex->getMessage() . '"' . "\n"); - fclose($fp); - } - - $audio = $this->audioError(); - } - - if ($this->canSendHeaders() || $this->send_headers == false) { - if ($this->send_headers) { - $uniq = md5(uniqid(microtime())); - header("Content-Disposition: attachment; filename=\"securimage_audio-{$uniq}.wav\""); - header('Cache-Control: no-store, no-cache, must-revalidate'); - header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); - header('Content-type: audio/x-wav'); - - if (extension_loaded('zlib')) { - ini_set('zlib.output_compression', true); // compress output if supported by browser - } else { - header('Content-Length: ' . strlen($audio)); - } - } - - echo $audio; - } else { - echo '
' - .'Failed to generate audio file, content has already been ' - .'output.
This is most likely due to misconfiguration or ' - .'a PHP error was sent to the browser.
'; - } - - restore_error_handler(); - - if (!$this->no_exit) exit; - } - - /** - * Return the code from the session or sqlite database if used. If none exists yet, an empty string is returned - * - * @param $array bool True to receive an array containing the code and properties - * @return array|string Array if $array = true, otherwise a string containing the code - */ - public function getCode($array = false) - { - $code = ''; - $time = 0; - $disp = 'error'; - - if ($this->no_session != true) { - if (isset($_SESSION['securimage_code_value'][$this->namespace]) && - trim($_SESSION['securimage_code_value'][$this->namespace]) != '') { - if ($this->isCodeExpired( - $_SESSION['securimage_code_ctime'][$this->namespace]) == false) { - $code = $_SESSION['securimage_code_value'][$this->namespace]; - $time = $_SESSION['securimage_code_ctime'][$this->namespace]; - $disp = $_SESSION['securimage_code_disp'] [$this->namespace]; - } - } - } - - if ($this->use_sqlite_db == true && function_exists('sqlite_open')) { - // no code in session - may mean user has cookies turned off - $this->openDatabase(); - $code = $this->getCodeFromDatabase(); - } else { /* no code stored in session or sqlite database, validation will fail */ } - - if ($array == true) { - return array('code' => $code, 'ctime' => $time, 'display' => $disp); - } else { - return $code; - } - } - - /** - * The main image drawing routing, responsible for constructing the entire image and serving it - */ - protected function doImage() - { - if( ($this->use_transparent_text == true || $this->bgimg != '') && function_exists('imagecreatetruecolor')) { - $imagecreate = 'imagecreatetruecolor'; - } else { - $imagecreate = 'imagecreate'; - } - - $this->im = $imagecreate($this->image_width, $this->image_height); - $this->tmpimg = $imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale); - - $this->allocateColors(); - imagepalettecopy($this->tmpimg, $this->im); - - $this->setBackground(); - - $code = ''; - - if ($this->getCaptchaId(false) !== null) { - // a captcha Id was supplied - - // check to see if a display_value for the captcha image was set - if (is_string($this->display_value) && strlen($this->display_value) > 0) { - $this->code_display = $this->display_value; - $this->code = ($this->case_sensitive) ? - $this->display_value : - strtolower($this->display_value); - $code = $this->code; - } else if ($this->openDatabase()) { - // no display_value, check the database for existing captchaId - $code = $this->getCodeFromDatabase(); - - // got back a result from the database with a valid code for captchaId - if (is_array($code)) { - $this->code = $code['code']; - $this->code_display = $code['code_disp']; - $code = $code['code']; - } - } - } - - if ($code == '') { - // if the code was not set using display_value or was not found in - // the database, create a new code - $this->createCode(); - } - - if ($this->noise_level > 0) { - $this->drawNoise(); - } - - $this->drawWord(); - - if ($this->perturbation > 0 && is_readable($this->ttf_file)) { - $this->distortedCopy(); - } - - if ($this->num_lines > 0) { - $this->drawLines(); - } - - if (trim($this->image_signature) != '') { - $this->addSignature(); - } - - $this->output(); - } - - /** - * Allocate the colors to be used for the image - */ - protected function allocateColors() - { - // allocate bg color first for imagecreate - $this->gdbgcolor = imagecolorallocate($this->im, - $this->image_bg_color->r, - $this->image_bg_color->g, - $this->image_bg_color->b); - - $alpha = intval($this->text_transparency_percentage / 100 * 127); - - if ($this->use_transparent_text == true) { - $this->gdtextcolor = imagecolorallocatealpha($this->im, - $this->text_color->r, - $this->text_color->g, - $this->text_color->b, - $alpha); - $this->gdlinecolor = imagecolorallocatealpha($this->im, - $this->line_color->r, - $this->line_color->g, - $this->line_color->b, - $alpha); - $this->gdnoisecolor = imagecolorallocatealpha($this->im, - $this->noise_color->r, - $this->noise_color->g, - $this->noise_color->b, - $alpha); - } else { - $this->gdtextcolor = imagecolorallocate($this->im, - $this->text_color->r, - $this->text_color->g, - $this->text_color->b); - $this->gdlinecolor = imagecolorallocate($this->im, - $this->line_color->r, - $this->line_color->g, - $this->line_color->b); - $this->gdnoisecolor = imagecolorallocate($this->im, - $this->noise_color->r, - $this->noise_color->g, - $this->noise_color->b); - } - - $this->gdsignaturecolor = imagecolorallocate($this->im, - $this->signature_color->r, - $this->signature_color->g, - $this->signature_color->b); - - } - - /** - * The the background color, or background image to be used - */ - protected function setBackground() - { - // set background color of image by drawing a rectangle since imagecreatetruecolor doesn't set a bg color - imagefilledrectangle($this->im, 0, 0, - $this->image_width, $this->image_height, - $this->gdbgcolor); - imagefilledrectangle($this->tmpimg, 0, 0, - $this->image_width * $this->iscale, $this->image_height * $this->iscale, - $this->gdbgcolor); - - if ($this->bgimg == '') { - if ($this->background_directory != null && - is_dir($this->background_directory) && - is_readable($this->background_directory)) - { - $img = $this->getBackgroundFromDirectory(); - if ($img != false) { - $this->bgimg = $img; - } - } - } - - if ($this->bgimg == '') { - return; - } - - $dat = @getimagesize($this->bgimg); - if($dat == false) { - return; - } - - switch($dat[2]) { - case 1: $newim = @imagecreatefromgif($this->bgimg); break; - case 2: $newim = @imagecreatefromjpeg($this->bgimg); break; - case 3: $newim = @imagecreatefrompng($this->bgimg); break; - default: return; - } - - if(!$newim) return; - - imagecopyresized($this->im, $newim, 0, 0, 0, 0, - $this->image_width, $this->image_height, - imagesx($newim), imagesy($newim)); - } - - /** - * Scan the directory for a background image to use - */ - protected function getBackgroundFromDirectory() - { - $images = array(); - - if ( ($dh = opendir($this->background_directory)) !== false) { - while (($file = readdir($dh)) !== false) { - if (preg_match('/(jpg|gif|png)$/i', $file)) $images[] = $file; - } - - closedir($dh); - - if (sizeof($images) > 0) { - return rtrim($this->background_directory, '/') . '/' . $images[rand(0, sizeof($images)-1)]; - } - } - - return false; - } - - /** - * Generates the code or math problem and saves the value to the session - */ - protected function createCode() - { - $this->code = false; - - switch($this->captcha_type) { - case self::SI_CAPTCHA_MATHEMATIC: - { - do { - $signs = array('+', '-', 'x'); - $left = rand(1, 10); - $right = rand(1, 5); - $sign = $signs[rand(0, 2)]; - - switch($sign) { - case 'x': $c = $left * $right; break; - case '-': $c = $left - $right; break; - default: $c = $left + $right; break; - } - } while ($c <= 0); // no negative #'s or 0 - - $this->code = $c; - $this->code_display = "$left $sign $right"; - break; - } - - default: - { - if ($this->use_wordlist && is_readable($this->wordlist_file)) { - $this->code = $this->readCodeFromFile(); - } - - if ($this->code == false) { - $this->code = $this->generateCode($this->code_length); - } - - $this->code_display = $this->code; - $this->code = ($this->case_sensitive) ? $this->code : strtolower($this->code); - } // default - } - - $this->saveData(); - } - - /** - * Draws the captcha code on the image - */ - protected function drawWord() - { - $width2 = $this->image_width * $this->iscale; - $height2 = $this->image_height * $this->iscale; - - if (!is_readable($this->ttf_file)) { - imagestring($this->im, 4, 10, ($this->image_height / 2) - 5, 'Failed to load TTF font file!', $this->gdtextcolor); - } else { - if ($this->perturbation > 0) { - $font_size = $height2 * .4; - $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display); - $tx = $bb[4] - $bb[0]; - $ty = $bb[5] - $bb[1]; - $x = floor($width2 / 2 - $tx / 2 - $bb[0]); - $y = round($height2 / 2 - $ty / 2 - $bb[1]); - - imagettftext($this->tmpimg, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display); - } else { - $font_size = $this->image_height * .4; - $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display); - $tx = $bb[4] - $bb[0]; - $ty = $bb[5] - $bb[1]; - $x = floor($this->image_width / 2 - $tx / 2 - $bb[0]); - $y = round($this->image_height / 2 - $ty / 2 - $bb[1]); - - imagettftext($this->im, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display); - } - } - - // DEBUG - //$this->im = $this->tmpimg; - //$this->output(); - - } - - /** - * Copies the captcha image to the final image with distortion applied - */ - protected function distortedCopy() - { - $numpoles = 3; // distortion factor - // make array of poles AKA attractor points - for ($i = 0; $i < $numpoles; ++ $i) { - $px[$i] = rand($this->image_width * 0.2, $this->image_width * 0.8); - $py[$i] = rand($this->image_height * 0.2, $this->image_height * 0.8); - $rad[$i] = rand($this->image_height * 0.2, $this->image_height * 0.8); - $tmp = ((- $this->frand()) * 0.15) - .15; - $amp[$i] = $this->perturbation * $tmp; - } - - $bgCol = imagecolorat($this->tmpimg, 0, 0); - $width2 = $this->iscale * $this->image_width; - $height2 = $this->iscale * $this->image_height; - imagepalettecopy($this->im, $this->tmpimg); // copy palette to final image so text colors come across - // loop over $img pixels, take pixels from $tmpimg with distortion field - for ($ix = 0; $ix < $this->image_width; ++ $ix) { - for ($iy = 0; $iy < $this->image_height; ++ $iy) { - $x = $ix; - $y = $iy; - for ($i = 0; $i < $numpoles; ++ $i) { - $dx = $ix - $px[$i]; - $dy = $iy - $py[$i]; - if ($dx == 0 && $dy == 0) { - continue; - } - $r = sqrt($dx * $dx + $dy * $dy); - if ($r > $rad[$i]) { - continue; - } - $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i]); - $x += $dx * $rscale; - $y += $dy * $rscale; - } - $c = $bgCol; - $x *= $this->iscale; - $y *= $this->iscale; - if ($x >= 0 && $x < $width2 && $y >= 0 && $y < $height2) { - $c = imagecolorat($this->tmpimg, $x, $y); - } - if ($c != $bgCol) { // only copy pixels of letters to preserve any background image - imagesetpixel($this->im, $ix, $iy, $c); - } - } - } - } - - /** - * Draws distorted lines on the image - */ - protected function drawLines() - { - for ($line = 0; $line < $this->num_lines; ++ $line) { - $x = $this->image_width * (1 + $line) / ($this->num_lines + 1); - $x += (0.5 - $this->frand()) * $this->image_width / $this->num_lines; - $y = rand($this->image_height * 0.1, $this->image_height * 0.9); - - $theta = ($this->frand() - 0.5) * M_PI * 0.7; - $w = $this->image_width; - $len = rand($w * 0.4, $w * 0.7); - $lwid = rand(0, 2); - - $k = $this->frand() * 0.6 + 0.2; - $k = $k * $k * 0.5; - $phi = $this->frand() * 6.28; - $step = 0.5; - $dx = $step * cos($theta); - $dy = $step * sin($theta); - $n = $len / $step; - $amp = 1.5 * $this->frand() / ($k + 5.0 / $len); - $x0 = $x - 0.5 * $len * cos($theta); - $y0 = $y - 0.5 * $len * sin($theta); - - $ldx = round(- $dy * $lwid); - $ldy = round($dx * $lwid); - - for ($i = 0; $i < $n; ++ $i) { - $x = $x0 + $i * $dx + $amp * $dy * sin($k * $i * $step + $phi); - $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i * $step + $phi); - imagefilledrectangle($this->im, $x, $y, $x + $lwid, $y + $lwid, $this->gdlinecolor); - } - } - } - - /** - * Draws random noise on the image - */ - protected function drawNoise() - { - if ($this->noise_level > 10) { - $noise_level = 10; - } else { - $noise_level = $this->noise_level; - } - - $t0 = microtime(true); - - $noise_level *= 125; // an arbitrary number that works well on a 1-10 scale - - $points = $this->image_width * $this->image_height * $this->iscale; - $height = $this->image_height * $this->iscale; - $width = $this->image_width * $this->iscale; - for ($i = 0; $i < $noise_level; ++$i) { - $x = rand(10, $width); - $y = rand(10, $height); - $size = rand(7, 10); - if ($x - $size <= 0 && $y - $size <= 0) continue; // dont cover 0,0 since it is used by imagedistortedcopy - imagefilledarc($this->tmpimg, $x, $y, $size, $size, 0, 360, $this->gdnoisecolor, IMG_ARC_PIE); - } - - $t1 = microtime(true); - - $t = $t1 - $t0; - - /* - // DEBUG - imagestring($this->tmpimg, 5, 25, 30, "$t", $this->gdnoisecolor); - header('content-type: image/png'); - imagepng($this->tmpimg); - exit; - */ - } - - /** - * Print signature text on image - */ - protected function addSignature() - { - $bbox = imagettfbbox(10, 0, $this->signature_font, $this->image_signature); - $textlen = $bbox[2] - $bbox[0]; - $x = $this->image_width - $textlen - 5; - $y = $this->image_height - 3; - - imagettftext($this->im, 10, 0, $x, $y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature); - } - - /** - * Sends the appropriate image and cache headers and outputs image to the browser - */ - protected function output() - { - if ($this->canSendHeaders() || $this->send_headers == false) { - if ($this->send_headers) { - // only send the content-type headers if no headers have been output - // this will ease debugging on misconfigured servers where warnings - // may have been output which break the image and prevent easily viewing - // source to see the error. - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - } - - switch ($this->image_type) { - case self::SI_IMAGE_JPEG: - if ($this->send_headers) header("Content-Type: image/jpeg"); - imagejpeg($this->im, null, 90); - break; - case self::SI_IMAGE_GIF: - if ($this->send_headers) header("Content-Type: image/gif"); - imagegif($this->im); - break; - default: - if ($this->send_headers) header("Content-Type: image/png"); - imagepng($this->im); - break; - } - } else { - echo '
' - .'Failed to generate captcha image, content has already been ' - .'output.
This is most likely due to misconfiguration or ' - .'a PHP error was sent to the browser.
'; - } - - imagedestroy($this->im); - restore_error_handler(); - - if (!$this->no_exit) exit; - } - - /** - * Gets the code and returns the binary audio file for the stored captcha code - * - * @return The audio representation of the captcha in Wav format - */ - protected function getAudibleCode() - { - $letters = array(); - $code = $this->getCode(true); - - if ($code['code'] == '') { - $this->createCode(); - $code = $this->getCode(true); - } - - if (preg_match('/(\d+) (\+|-|x) (\d+)/i', $code['display'], $eq)) { - $math = true; - - $left = $eq[1]; - $sign = str_replace(array('+', '-', 'x'), array('plus', 'minus', 'times'), $eq[2]); - $right = $eq[3]; - - $letters = array($left, $sign, $right); - } else { - $math = false; - - $length = strlen($code['display']); - - for($i = 0; $i < $length; ++$i) { - $letter = $code['display']{$i}; - $letters[] = $letter; - } - } - - try { - return $this->generateWAV($letters); - } catch(Exception $ex) { - throw $ex; - } - } - - /** - * Gets a captcha code from a wordlist - */ - protected function readCodeFromFile() - { - $fp = @fopen($this->wordlist_file, 'rb'); - if (!$fp) return false; - - $fsize = filesize($this->wordlist_file); - if ($fsize < 128) return false; // too small of a list to be effective - - fseek($fp, rand(0, $fsize - 64), SEEK_SET); // seek to a random position of file from 0 to filesize-64 - $data = fread($fp, 64); // read a chunk from our random position - fclose($fp); - $data = preg_replace("/\r?\n/", "\n", $data); - - $start = @strpos($data, "\n", rand(0, 56)) + 1; // random start position - $end = @strpos($data, "\n", $start); // find end of word - - if ($start === false) { - return false; - } else if ($end === false) { - $end = strlen($data); - } - - return strtolower(substr($data, $start, $end - $start)); // return a line of the file - } - - /** - * Generates a random captcha code from the set character set - */ - protected function generateCode() - { - $code = ''; - - for($i = 1, $cslen = strlen($this->charset); $i <= $this->code_length; ++$i) { - $code .= $this->charset{rand(0, $cslen - 1)}; - } - - //return 'testing'; // debug, set the code to given string - - return $code; - } - - /** - * Checks the entered code against the value stored in the session or sqlite database, handles case sensitivity - * Also clears the stored codes if the code was entered correctly to prevent re-use - */ - protected function validate() - { - if (!is_string($this->code) || strlen($this->code) == 0) { - $code = $this->getCode(); - // returns stored code, or an empty string if no stored code was found - // checks the session and sqlite database if enabled - } else { - $code = $this->code; - } - - if ($this->case_sensitive == false && preg_match('/[A-Z]/', $code)) { - // case sensitive was set from securimage_show.php but not in class - // the code saved in the session has capitals so set case sensitive to true - $this->case_sensitive = true; - } - - $code_entered = trim( (($this->case_sensitive) ? $this->code_entered - : strtolower($this->code_entered)) - ); - $this->correct_code = false; - - if ($code != '') { - if ($code == $code_entered) { - $this->correct_code = true; - if ($this->no_session != true) { - $_SESSION['securimage_code_value'][$this->namespace] = ''; - $_SESSION['securimage_code_ctime'][$this->namespace] = ''; - } - $this->clearCodeFromDatabase(); - } - } - } - - /** - * Save data to session namespace and database if used - */ - protected function saveData() - { - if ($this->no_session != true) { - if (isset($_SESSION['securimage_code_value']) && is_scalar($_SESSION['securimage_code_value'])) { - // fix for migration from v2 - v3 - unset($_SESSION['securimage_code_value']); - unset($_SESSION['securimage_code_ctime']); - } - - $_SESSION['securimage_code_disp'] [$this->namespace] = $this->code_display; - $_SESSION['securimage_code_value'][$this->namespace] = $this->code; - $_SESSION['securimage_code_ctime'][$this->namespace] = time(); - } - - $this->saveCodeToDatabase(); - } - - /** - * Saves the code to the sqlite database - */ - protected function saveCodeToDatabase() - { - $success = false; - - $this->openDatabase(); - - if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - $id = $this->getCaptchaId(false); - $ip = $_SERVER['REMOTE_ADDR']; - - if (empty($id)) { - $id = $ip; - } - - $time = time(); - $code = $this->code; - $code_disp = $this->code_display; - - $query = "INSERT OR REPLACE INTO codes(id, ip, code, code_display," - ."namespace, created) VALUES('$id', '$ip', '$code', " - ."'$code_disp', '{$this->namespace}', $time)"; - - $success = sqlite_query($this->sqlite_handle, $query); - } - - return $success !== false; - } - - /** - * Open sqlite database - */ - protected function openDatabase() - { - $this->sqlite_handle = false; - - if ($this->use_sqlite_db == true && !function_exists('sqlite_open')) { - trigger_error('Securimage use_sqlite_db option is enable, but SQLIte is not supported by this PHP installation', E_USER_WARNING); - } - - if ($this->use_sqlite_db && function_exists('sqlite_open')) { - if (!file_exists($this->sqlite_database)) { - $fp = fopen($this->sqlite_database, 'w+'); - if (!$fp) { - trigger_error('Securimage failed to open sqlite database "' . $this->sqlite_database, E_USER_WARNING); - return false; - } - fclose($fp); - chmod($this->sqlite_database, 0666); - } - - $this->sqlite_handle = sqlite_open($this->sqlite_database, 0666, $error); - - if ($this->sqlite_handle !== false) { - $res = sqlite_query($this->sqlite_handle, "PRAGMA table_info(codes)"); - - if (sqlite_num_rows($res) == 0) { - $res = sqlite_query( - $this->sqlite_handle, - "CREATE TABLE codes (id VARCHAR(40) PRIMARY KEY, ip VARCHAR(32), - code VARCHAR(32) NOT NULL, code_display VARCHAR(32) NOT NULL, - namespace VARCHAR(32) NOT NULL, created INTEGER)" - ); - } - - if (mt_rand(0, 100) / 100.0 == 1.0) { - // randomly purge old codes - $this->purgeOldCodesFromDatabase(); - } - } - - return $this->sqlite_handle != false; - } - - return $this->sqlite_handle; - } - - /** - * Get a code from the sqlite database for ip address/captchaId. - * - * @return string|array Empty string if no code was found or has expired, - * otherwise returns the stored captcha code. If a captchaId is set, this - * returns an array with indices "code" and "code_disp" - */ - protected function getCodeFromDatabase() - { - $code = ''; - - if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - if (Securimage::$_captchaId !== null) { - $query = "SELECT * FROM codes WHERE id = '" . sqlite_escape_string(Securimage::$_captchaId) . "'"; - } else { - $ip = $_SERVER['REMOTE_ADDR']; - $ns = sqlite_escape_string($this->namespace); - $query = "SELECT * FROM codes WHERE ip = '$ip' AND namespace = '$ns'"; - } - - $res = sqlite_query($this->sqlite_handle, $query); - if ($res && sqlite_num_rows($res) > 0) { - $res = sqlite_fetch_array($res); - - if ($this->isCodeExpired($res['created']) == false) { - if (Securimage::$_captchaId !== null) { - // return an array when using captchaId - $code = array('code' => $res['code'], - 'code_disp' => $res['code_display']); - } else { - // return only the code if no captchaId specified - $code = $res['code']; - } - } - } - } - return $code; - } - - /** - * Remove an entered code from the database - */ - protected function clearCodeFromDatabase() - { - if (is_resource($this->sqlite_handle)) { - $ip = $_SERVER['REMOTE_ADDR']; - $ns = sqlite_escape_string($this->namespace); - - sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE ip = '$ip' AND namespace = '$ns'"); - } - } - - /** - * Deletes old codes from sqlite database - */ - protected function purgeOldCodesFromDatabase() - { - if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - $now = time(); - $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time; - - sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE $now - created > $limit"); - } - } - - /** - * Checks to see if the captcha code has expired and cannot be used - * @param unknown_type $creation_time - */ - protected function isCodeExpired($creation_time) - { - $expired = true; - - if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) { - $expired = false; - } else if (time() - $creation_time < $this->expiry_time) { - $expired = false; - } - - return $expired; - } - - /** - * Generate a wav file given the $letters in the code - * @todo Add ability to merge 2 sound files together to have random background sounds - * @param array $letters - * @return string The binary contents of the wav file - */ - protected function generateWAV($letters) - { - $wavCaptcha = new WavFile(); - $first = true; // reading first wav file - - foreach ($letters as $letter) { - $letter = strtoupper($letter); - - try { - $l = new WavFile($this->audio_path . '/' . $letter . '.wav'); - - if ($first) { - // set sample rate, bits/sample, and # of channels for file based on first letter - $wavCaptcha->setSampleRate($l->getSampleRate()) - ->setBitsPerSample($l->getBitsPerSample()) - ->setNumChannels($l->getNumChannels()); - $first = false; - } - - // append letter to the captcha audio - $wavCaptcha->appendWav($l); - - // random length of silence between $audio_gap_min and $audio_gap_max - if ($this->audio_gap_max > 0 && $this->audio_gap_max > $this->audio_gap_min) { - $wavCaptcha->insertSilence( mt_rand($this->audio_gap_min, $this->audio_gap_max) / 1000.0 ); - } - } catch (Exception $ex) { - // failed to open file, or the wav file is broken or not supported - // 2 wav files were not compatible, different # channels, bits/sample, or sample rate - throw $ex; - } - } - - /********* Set up audio filters *****************************/ - $filters = array(); - - if ($this->audio_use_noise == true) { - // use background audio - find random file - $noiseFile = $this->getRandomNoiseFile(); - - if ($noiseFile !== false && is_readable($noiseFile)) { - try { - $wavNoise = new WavFile($noiseFile, false); - } catch(Exception $ex) { - throw $ex; - } - - // start at a random offset from the beginning of the wavfile - // in order to add more randomness - $randOffset = 0; - if ($wavNoise->getNumBlocks() > 2 * $wavCaptcha->getNumBlocks()) { - $randBlock = rand(0, $wavNoise->getNumBlocks() - $wavCaptcha->getNumBlocks()); - $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $wavCaptcha->getNumBlocks() * $wavNoise->getBlockAlign()); - } else { - $wavNoise->readWavData(); - $randOffset = rand(0, $wavNoise->getNumBlocks() - 1); - } - - - $mixOpts = array('wav' => $wavNoise, - 'loop' => true, - 'blockOffset' => $randOffset); - - $filters[WavFile::FILTER_MIX] = $mixOpts; - $filters[WavFile::FILTER_NORMALIZE] = $this->audio_mix_normalization; - } - } - - if ($this->degrade_audio == true) { - // add random noise. - // any noise level below 95% is intensely distorted and not pleasant to the ear - $filters[WavFile::FILTER_DEGRADE] = rand(95, 98) / 100.0; - } - - if (!empty($filters)) { - $wavCaptcha->filter($filters); // apply filters to captcha audio - } - - return $wavCaptcha->__toString(); - } - - public function getRandomNoiseFile() - { - $return = false; - - if ( ($dh = opendir($this->audio_noise_path)) !== false ) { - $list = array(); - - while ( ($file = readdir($dh)) !== false ) { - if ($file == '.' || $file == '..') continue; - if (strtolower(substr($file, -4)) != '.wav') continue; - - $list[] = $file; - } - - closedir($dh); - - if (sizeof($list) > 0) { - $file = $list[array_rand($list, 1)]; - $return = $this->audio_noise_path . DIRECTORY_SEPARATOR . $file; - } - } - - return $return; - } - - /** - * Return a wav file saying there was an error generating file - * - * @return string The binary audio contents - */ - protected function audioError() - { - return @file_get_contents(dirname(__FILE__) . '/audio/error.wav'); - } - - /** - * Checks to see if headers can be sent and if any error has been output to the browser - * - * @return bool true if headers haven't been sent and no output/errors will break audio/images, false if unsafe - */ - protected function canSendHeaders() - { - if (headers_sent()) { - // output has been flushed and headers have already been sent - return false; - } else if (strlen((string)ob_get_contents()) > 0) { - // headers haven't been sent, but there is data in the buffer that will break image and audio data - return false; - } - - return true; - } - - /** - * Return a random float between 0 and 0.9999 - * - * @return float Random float between 0 and 0.9999 - */ - function frand() - { - return 0.0001 * rand(0,9999); - } - - /** - * Convert an html color code to a Securimage_Color - * @param string $color - * @param Securimage_Color $default The defalt color to use if $color is invalid - */ - protected function initColor($color, $default) - { - if ($color == null) { - return new Securimage_Color($default); - } else if (is_string($color)) { - try { - return new Securimage_Color($color); - } catch(Exception $e) { - return new Securimage_Color($default); - } - } else if (is_array($color) && sizeof($color) == 3) { - return new Securimage_Color($color[0], $color[1], $color[2]); - } else { - return new Securimage_Color($default); - } - } - - /** - * Error handler used when outputting captcha image or audio. - * This error handler helps determine if any errors raised would - * prevent captcha image or audio from displaying. If they have - * no effect on the output buffer or headers, true is returned so - * the script can continue processing. - * See https://github.com/dapphp/securimage/issues/15 - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - * @return boolean true if handled, false if PHP should handle - */ - public function errorHandler($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array()) - { - // get the current error reporting level - $level = error_reporting(); - - // if error was supressed or $errno not set in current error level - if ($level == 0 || ($level & $errno) == 0) { - return true; - } - - return false; - } -} - - -/** - * Color object for Securimage CAPTCHA - * - * @version 3.0 - * @since 2.0 - * @package Securimage - * @subpackage classes - * - */ -class Securimage_Color -{ - public $r; - public $g; - public $b; - - /** - * Create a new Securimage_Color object.
- * Constructor expects 1 or 3 arguments.
- * When passing a single argument, specify the color using HTML hex format,
- * when passing 3 arguments, specify each RGB component (from 0-255) individually.
- * $color = new Securimage_Color('#0080FF') or
- * $color = new Securimage_Color(0, 128, 255) - * - * @param string $color - * @throws Exception - */ - public function __construct($color = '#ffffff') - { - $args = func_get_args(); - - if (sizeof($args) == 0) { - $this->r = 255; - $this->g = 255; - $this->b = 255; - } else if (sizeof($args) == 1) { - // set based on html code - if (substr($color, 0, 1) == '#') { - $color = substr($color, 1); - } - - if (strlen($color) != 3 && strlen($color) != 6) { - throw new InvalidArgumentException( - 'Invalid HTML color code passed to Securimage_Color' - ); - } - - $this->constructHTML($color); - } else if (sizeof($args) == 3) { - $this->constructRGB($args[0], $args[1], $args[2]); - } else { - throw new InvalidArgumentException( - 'Securimage_Color constructor expects 0, 1 or 3 arguments; ' . sizeof($args) . ' given' - ); - } - } - - /** - * Construct from an rgb triplet - * @param int $red The red component, 0-255 - * @param int $green The green component, 0-255 - * @param int $blue The blue component, 0-255 - */ - protected function constructRGB($red, $green, $blue) - { - if ($red < 0) $red = 0; - if ($red > 255) $red = 255; - if ($green < 0) $green = 0; - if ($green > 255) $green = 255; - if ($blue < 0) $blue = 0; - if ($blue > 255) $blue = 255; - - $this->r = $red; - $this->g = $green; - $this->b = $blue; - } - - /** - * Construct from an html hex color code - * @param string $color - */ - protected function constructHTML($color) - { - if (strlen($color) == 3) { - $red = str_repeat(substr($color, 0, 1), 2); - $green = str_repeat(substr($color, 1, 1), 2); - $blue = str_repeat(substr($color, 2, 1), 2); - } else { - $red = substr($color, 0, 2); - $green = substr($color, 2, 2); - $blue = substr($color, 4, 2); - } - - $this->r = hexdec($red); - $this->g = hexdec($green); - $this->b = hexdec($blue); - } -} diff --git a/captcha/securimage_play.php b/captcha/securimage_play.php deleted file mode 100644 index 4f4ffa3..0000000 --- a/captcha/securimage_play.php +++ /dev/null @@ -1,47 +0,0 @@ - - * File: securimage_play.php
- * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version.

- * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details.

- * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

- * - * Any modifications to the library should be indicated clearly in the source code - * to inform users that the changes are not a part of the original software.

- * - * If you found this script useful, please take a quick moment to rate it.
- * http://www.hotscripts.com/rate/49400.html Thanks. - * - * @link http://www.phpcaptcha.org Securimage PHP CAPTCHA - * @link http://www.phpcaptcha.org/latest.zip Download Latest Version - * @link http://www.phpcaptcha.org/Securimage_Docs/ Online Documentation - * @copyright 2012 Drew Phillips - * @author Drew Phillips - * @version 3.2RC2 (April 2012) - * @package Securimage - * - */ - -require_once dirname(__FILE__) . '/securimage.php'; - -$img = new Securimage(); - -// To use an alternate language, uncomment the following and download the files from phpcaptcha.org -// $img->audio_path = $img->securimage_path . '/audio/es/'; - -// If you have more than one captcha on a page, one must use a custom namespace -// $img->namespace = 'form2'; - -$img->outputAudioFile(); diff --git a/captcha/securimage_play.swf b/captcha/securimage_play.swf deleted file mode 100644 index e749bc5..0000000 Binary files a/captcha/securimage_play.swf and /dev/null differ diff --git a/captcha/securimage_show.php b/captcha/securimage_show.php deleted file mode 100644 index c54a4cb..0000000 --- a/captcha/securimage_show.php +++ /dev/null @@ -1,77 +0,0 @@ - - * File: securimage_show.php
- * - * Copyright (c) 2011, Drew Phillips - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Any modifications to the library should be indicated clearly in the source code - * to inform users that the changes are not a part of the original software.

- * - * If you found this script useful, please take a quick moment to rate it.
- * http://www.hotscripts.com/rate/49400.html Thanks. - * - * @link http://www.phpcaptcha.org Securimage PHP CAPTCHA - * @link http://www.phpcaptcha.org/latest.zip Download Latest Version - * @link http://www.phpcaptcha.org/Securimage_Docs/ Online Documentation - * @copyright 2012 Drew Phillips - * @author Drew Phillips - * @version 3.2RC2 (April 2012) - * @package Securimage - * - */ - -// Remove the "//" from the following line for debugging problems -// error_reporting(E_ALL); ini_set('display_errors', 1); - -require_once dirname(__FILE__) . '/securimage.php'; - -$img = new Securimage(); - -// You can customize the image by making changes below, some examples are included - remove the "//" to uncomment - -//$img->ttf_file = './Quiff.ttf'; -//$img->captcha_type = Securimage::SI_CAPTCHA_MATHEMATIC; // show a simple math problem instead of text -//$img->case_sensitive = true; // true to use case sensitve codes - not recommended -//$img->image_height = 90; // width in pixels of the image -//$img->image_width = $img->image_height * M_E; // a good formula for image size -//$img->perturbation = .75; // 1.0 = high distortion, higher numbers = more distortion -//$img->image_bg_color = new Securimage_Color("#0099CC"); // image background color -//$img->text_color = new Securimage_Color("#EAEAEA"); // captcha text color -//$img->num_lines = 8; // how many lines to draw over the image -//$img->line_color = new Securimage_Color("#0000CC"); // color of lines over the image -//$img->image_type = SI_IMAGE_JPEG; // render as a jpeg image -//$img->signature_color = new Securimage_Color(rand(0, 64), -// rand(64, 128), -// rand(128, 255)); // random signature color - -// see securimage.php for more options that can be set - - - -$img->show(); // outputs the image and content headers to the browser -// alternate use: -// $img->show('/path/to/background_image.jpg'); diff --git a/captcha/words/words.txt b/captcha/words/words.txt deleted file mode 100644 index 9a444ce..0000000 --- a/captcha/words/words.txt +++ /dev/null @@ -1,15457 +0,0 @@ -aahing -aaliis -aarrgh -abacas -abacus -abakas -abamps -abased -abaser -abases -abasia -abated -abater -abates -abatis -abator -abayas -abbacy -abbess -abbeys -abbots -abduce -abduct -abeles -abelia -abhors -abided -abider -abides -abject -abjure -ablate -ablaut -ablaze -ablest -ablins -abloom -ablush -abmhos -aboard -aboded -abodes -abohms -abolla -abomas -aboral -aborts -abound -aboves -abrade -abroad -abrupt -abseil -absent -absorb -absurd -abulia -abulic -abvolt -abwatt -abying -abysms -acacia -acajou -acarid -acarus -accede -accent -accept -access -accord -accost -accrue -accuse -acedia -acetal -acetic -acetin -acetum -acetyl -achene -achier -aching -acidic -acidly -acinar -acinic -acinus -ackees -acnode -acorns -acquit -across -acting -actins -action -active -actors -actual -acuate -acuity -aculei -acumen -acuter -acutes -adages -adagio -adapts -addend -adders -addict -adding -addled -addles -adduce -adduct -adeems -adenyl -adepts -adhere -adieus -adieux -adipic -adjoin -adjure -adjust -admass -admire -admits -admixt -adnate -adnexa -adnoun -adobes -adobos -adonis -adopts -adored -adorer -adores -adorns -adrift -adroit -adsorb -adults -advect -advent -adverb -advert -advice -advise -adytum -adzing -adzuki -aecial -aecium -aedile -aedine -aeneus -aeonic -aerate -aerial -aeried -aerier -aeries -aerify -aerily -aerobe -aerugo -aether -afeard -affair -affect -affine -affirm -afflux -afford -affray -afghan -afield -aflame -afloat -afraid -afreet -afresh -afrits -afters -aftosa -agamas -agamic -agamid -agapae -agapai -agapes -agaric -agates -agaves -agedly -ageing -ageism -ageist -agency -agenda -agenes -agents -aggada -aggers -aggies -aggros -aghast -agings -agisms -agists -agitas -aglare -agleam -aglets -agnail -agnate -agnize -agonal -agones -agonic -agorae -agoras -agorot -agouti -agouty -agrafe -agreed -agrees -agrias -aguish -ahchoo -ahimsa -aholds -ahorse -aiders -aidful -aiding -aidman -aidmen -aiglet -aigret -aikido -ailing -aimers -aimful -aiming -aiolis -airbag -airbus -airers -airest -airier -airily -airing -airman -airmen -airted -airths -airway -aisled -aisles -aivers -ajivas -ajowan -ajugas -akelas -akenes -akimbo -alamos -alands -alanin -alants -alanyl -alarms -alarum -alaska -alated -alates -albata -albedo -albeit -albino -albite -albums -alcade -alcaic -alcids -alcove -alders -aldols -aldose -aldrin -alegar -alephs -alerts -alevin -alexia -alexin -alfaki -algins -algoid -algors -algums -alibis -alible -alidad -aliens -alight -aligns -alined -aliner -alines -aliped -aliyah -aliyas -aliyos -aliyot -alkali -alkane -alkene -alkies -alkine -alkoxy -alkyds -alkyls -alkyne -allays -allees -allege -allele -alleys -allied -allies -allium -allods -allots -allows -alloys -allude -allure -allyls -almahs -almehs -almner -almond -almost -almuce -almude -almuds -almugs -alnico -alodia -alohas -aloins -alpaca -alphas -alphyl -alpine -alsike -altars -alters -althea -aludel -alulae -alular -alumin -alumna -alumni -alvine -always -amadou -amarna -amatol -amazed -amazes -amazon -ambage -ambari -ambary -ambeer -ambers -ambery -ambits -ambled -ambler -ambles -ambush -amebae -ameban -amebas -amebic -ameers -amends -aments -amerce -amices -amicus -amides -amidic -amidin -amidol -amidst -amigas -amigos -amines -aminic -ammine -ammino -ammono -amnion -amnios -amoeba -amoles -amoral -amount -amours -ampere -amping -ampler -ampule -ampuls -amrita -amtrac -amucks -amulet -amused -amuser -amuses -amusia -amylic -amylum -anabas -anadem -analog -ananke -anarch -anatto -anchor -anchos -ancone -andros -anears -aneled -aneles -anemia -anemic -anenst -anergy -angary -angels -angers -angina -angled -angler -angles -anglos -angora -angsts -anilin -animal -animas -animes -animis -animus -anions -anises -anisic -ankled -ankles -anklet -ankush -anlace -anlage -annals -anneal -annexe -annona -annoys -annual -annuli -annuls -anodal -anodes -anodic -anoint -anoles -anomic -anomie -anonym -anopia -anorak -anoxia -anoxic -ansate -answer -anteed -anthem -anther -antiar -antick -antics -anting -antler -antral -antres -antrum -anural -anuran -anuria -anuric -anvils -anyhow -anyone -anyons -anyway -aorist -aortae -aortal -aortas -aortic -aoudad -apache -apathy -apercu -apexes -aphids -aphtha -apiary -apical -apices -apiece -aplite -aplomb -apneal -apneas -apneic -apnoea -apodal -apogee -apollo -apolog -aporia -appall -appals -appeal -appear -appels -append -apples -applet -appose -aprons -aptest -arabic -arable -arames -aramid -arbors -arbour -arbute -arcade -arcana -arcane -arched -archer -arches -archil -archly -archon -arcing -arcked -arctic -ardebs -ardent -ardors -ardour -arecas -arenas -arenes -areola -areole -arepas -aretes -argala -argali -argals -argent -argils -argled -argles -argols -argons -argosy -argots -argued -arguer -argues -argufy -argyle -argyll -arhats -ariary -arider -aridly -ariels -aright -ariled -ariose -ariosi -arioso -arisen -arises -arista -aristo -arkose -armada -armers -armets -armful -armies -arming -armlet -armors -armory -armour -armpit -armure -arnica -aroids -aroint -aromas -around -arouse -aroynt -arpens -arpent -arrack -arrant -arrays -arrear -arrest -arriba -arrive -arroba -arrows -arrowy -arroyo -arseno -arshin -arsine -arsino -arsons -artels -artery -artful -artier -artily -artist -asanas -asarum -ascend -ascent -ascots -asdics -ashcan -ashier -ashing -ashlar -ashler -ashman -ashmen -ashore -ashram -asides -askant -askers -asking -aslant -asleep -aslope -aslosh -aspect -aspens -aspers -aspics -aspire -aspish -asrama -astern -asters -asthma -astony -astral -astray -astute -aswarm -aswirl -aswoon -asylum -atabal -ataman -atavic -ataxia -ataxic -atelic -atlatl -atmans -atolls -atomic -atonal -atoned -atoner -atones -atonia -atonic -atopic -atrial -atrium -attach -attack -attain -attars -attend -attent -attest -attics -attire -attorn -attrit -attune -atwain -atween -atypic -aubade -auburn -aucuba -audads -audial -audile -auding -audios -audits -augend -augers -aughts -augite -augurs -augury -august -auklet -aulder -auntie -auntly -aurate -aureus -aurist -aurora -aurous -aurums -auspex -ausubo -auteur -author -autism -autist -autoed -autumn -auxins -avails -avatar -avaunt -avenge -avenue -averse -averts -avians -aviary -aviate -avidin -avidly -avions -avisos -avocet -avoids -avoset -avouch -avowal -avowed -avower -avulse -awaits -awaked -awaken -awakes -awards -aweary -aweigh -aweing -awhile -awhirl -awless -awmous -awning -awoken -axeman -axemen -axenic -axilla -axioms -axions -axised -axises -axites -axlike -axonal -axones -axonic -axseed -azalea -azides -azines -azlons -azoles -azonal -azonic -azoted -azotes -azoths -azotic -azukis -azures -azygos -baaing -baalim -baases -babble -babels -babied -babier -babies -babkas -babool -baboon -baboos -babuls -baccae -bached -baches -backed -backer -backup -bacons -bacula -badass -badder -baddie -badged -badger -badges -badman -badmen -baffed -baffle -bagels -bagful -bagged -bagger -baggie -bagman -bagmen -bagnio -baguet -bagwig -bailed -bailee -bailer -bailey -bailie -bailor -bairns -baited -baiter -baizas -baizes -bakers -bakery -baking -balata -balboa -balded -balder -baldly -baleen -balers -baling -balked -balker -ballad -ballet -ballon -ballot -balsam -balsas -bamboo -bammed -banana -bancos -bandas -banded -bander -bandit -bandog -banged -banger -bangle -banian -baning -banish -banjax -banjos -banked -banker -bankit -banned -banner -bannet -bantam -banter -banyan -banzai -baobab -barbal -barbed -barbel -barber -barbes -barbet -barbie -barbut -barcas -barded -bardes -bardic -barege -barely -barest -barfed -barfly -barged -bargee -barges -barhop -baring -barite -barium -barked -barker -barley -barlow -barman -barmen -barmie -barned -barney -barong -barons -barony -barque -barred -barrel -barren -barres -barret -barrio -barrow -barter -baryes -baryon -baryta -baryte -basalt -basely -basest -bashaw -bashed -basher -bashes -basics -basify -basils -basing -basins -basion -basked -basket -basque -basted -baster -bastes -batboy -bateau -bathed -bather -bathes -bathos -batiks -bating -batman -batmen -batons -batted -batten -batter -battik -battle -battue -baubee -bauble -baulks -baulky -bawbee -bawdry -bawled -bawler -bawtie -bayamo -bayard -baying -bayman -baymen -bayous -bazaar -bazars -bazoos -beachy -beacon -beaded -beader -beadle -beagle -beaked -beaker -beamed -beaned -beanie -beanos -beards -bearer -beaten -beater -beauts -beauty -bebops -becalm -became -becaps -becked -becket -beckon -beclog -become -bedamn -bedaub -bedbug -bedded -bedder -bedeck -bedell -bedels -bedews -bedims -bedlam -bedpan -bedrid -bedrug -bedsit -beduin -bedumb -beebee -beechy -beefed -beeped -beeper -beetle -beeves -beezer -befall -befell -befits -beflag -beflea -befogs -befool -before -befoul -befret -begall -begaze -begets -beggar -begged -begins -begird -begirt -beglad -begone -begrim -begulf -begums -behalf -behave -behead -beheld -behest -behind -behold -behoof -behove -behowl -beiges -beigne -beings -bekiss -beknot -belady -belaud -belays -beldam -beleap -belfry -belgas -belied -belief -belier -belies -belike -belive -belled -belles -bellow -belong -belons -belows -belted -belter -beluga -bemata -bemean -bemire -bemist -bemixt -bemoan -bemock -bemuse -bename -benday -bended -bendee -bender -bendys -benign -bennes -bennet -bennis -bentos -benumb -benzal -benzin -benzol -benzyl -berake -berate -bereft -berets -berime -berlin -bermed -bermes -bertha -berths -beryls -beseem -besets -beside -besmut -besnow -besoms -besots -bested -bestir -bestow -bestud -betake -betels -bethel -betide -betime -betise -betons -betony -betook -betray -bettas -betted -better -bettor -bevels -bevies -bevors -bewail -beware -beweep -bewept -bewigs -beworm -bewrap -bewray -beylic -beylik -beyond -bezant -bezazz -bezels -bezils -bezoar -bhakta -bhakti -bhangs -bharal -bhoots -bialis -bialys -biased -biases -biaxal -bibbed -bibber -bibles -bicarb -biceps -bicker -bicorn -bicron -bidden -bidder -biders -bidets -biding -bields -biface -biffed -biffin -biflex -bifold -biform -bigamy -bigeye -bigger -biggie -biggin -bights -bigots -bigwig -bijous -bijoux -bikers -bikies -biking -bikini -bilboa -bilbos -bilged -bilges -bilked -bilker -billed -biller -billet -billie -billon -billow -bimahs -bimbos -binary -binate -binder -bindis -bindle -biners -binged -binger -binges -bingos -binits -binned -binocs -biogas -biogen -biomes -bionic -bionts -biopic -biopsy -biotas -biotic -biotin -bipack -bipeds -bipods -birded -birder -birdie -bireme -birkie -birled -birler -birles -birred -birses -births -bisect -bishop -bisons -bisque -bister -bistre -bistro -biters -biting -bitmap -bitted -bitten -bitter -bizone -bizzes -blabby -blacks -bladed -blader -blades -blaffs -blains -blamed -blamer -blames -blanch -blanks -blared -blares -blasts -blasty -blawed -blazed -blazer -blazes -blazon -bleach -bleaks -blears -bleary -bleats -blebby -bleeds -bleeps -blench -blende -blends -blenny -blight -blimey -blimps -blinds -blinis -blinks -blintz -blites -blithe -bloats -blocks -blocky -blokes -blonde -blonds -bloods -bloody -blooey -blooie -blooms -bloomy -bloops -blotch -blotto -blotty -blouse -blousy -blowby -blowed -blower -blowsy -blowup -blowzy -bludge -bluely -bluest -bluesy -bluets -blueys -bluffs -bluing -bluish -blumed -blumes -blunge -blunts -blurbs -blurry -blurts -blypes -boards -boarts -boasts -boated -boatel -boater -bobbed -bobber -bobbin -bobble -bobcat -bocces -boccia -boccie -boccis -boches -bodega -bodice -bodied -bodies -bodily -boding -bodkin -boffed -boffin -boffos -bogans -bogart -bogeys -bogged -boggle -bogies -bogles -boheas -bohunk -boiled -boiler -boings -boinks -boites -bolder -boldly -bolero -bolete -boleti -bolide -bolled -bolshy -bolson -bolted -bolter -bombax -bombed -bomber -bombes -bombyx -bonaci -bonbon -bonded -bonder -bonduc -bongos -bonier -boning -bonita -bonito -bonnes -bonnet -bonnie -bonobo -bonsai -bonzer -bonzes -boobed -boobie -booboo -boocoo -boodle -booger -boogey -boogie -boohoo -booing -boojum -booked -booker -bookie -bookoo -boomed -boomer -boosts -booted -bootee -booths -bootie -boozed -boozer -boozes -bopeep -bopped -bopper -borage -borals -borane -borate -bordel -border -boreal -boreas -boreen -borers -boride -boring -borked -borons -borrow -borsch -borsht -borzoi -boshes -bosker -bosket -bosons -bosque -bossed -bosses -boston -bosuns -botany -botchy -botels -botfly -bother -bottle -bottom -boubou -boucle -boudin -bouffe -boughs -bought -bougie -boules -boulle -bounce -bouncy -bounds -bounty -bourgs -bourne -bourns -bourse -boused -bouses -bouton -bovids -bovine -bowers -bowery -bowfin -bowing -bowled -bowleg -bowler -bowman -bowmen -bowpot -bowsed -bowses -bowwow -bowyer -boxcar -boxers -boxful -boxier -boxily -boxing -boyard -boyars -boyish -boylas -braced -bracer -braces -brachs -bracts -braggy -brahma -braids -brails -brains -brainy -braise -braize -braked -brakes -branch -brands -brandy -branks -branny -brants -brashy -brasil -brassy -bratty -bravas -braved -braver -braves -bravos -brawer -brawls -brawly -brawns -brawny -brayed -brayer -brazas -brazed -brazen -brazer -brazes -brazil -breach -breads -bready -breaks -breams -breath -bredes -breech -breeds -breeks -breeze -breezy -bregma -brents -breves -brevet -brewed -brewer -brewis -briard -briars -briary -bribed -bribee -briber -bribes -bricks -bricky -bridal -brides -bridge -bridle -briefs -briers -briery -bright -brillo -brills -brined -briner -brines -brings -brinks -briony -brises -brisks -briths -britts -broach -broads -broche -brocks -brogan -brogue -broils -broken -broker -brolly -bromal -bromes -bromic -bromid -bromin -bromos -bronco -broncs -bronze -bronzy -brooch -broods -broody -brooks -brooms -broomy -broses -broths -brothy -browed -browns -browny -browse -brucin -brughs -bruins -bruise -bruits -brulot -brumal -brumby -brumes -brunch -brunet -brunts -brushy -brutal -bruted -brutes -bruxed -bruxes -bryony -bubale -bubals -bubbas -bubble -bubbly -bubkes -buboed -buboes -buccal -bucked -bucker -bucket -buckle -buckos -buckra -budded -budder -buddha -buddle -budged -budger -budges -budget -budgie -buffed -buffer -buffet -buffos -bugeye -bugged -bugger -bugled -bugler -bugles -bugout -bugsha -builds -bulbar -bulbed -bulbel -bulbil -bulbul -bulged -bulger -bulges -bulgur -bulked -bullae -bulled -bullet -bumble -bumkin -bumped -bumper -bumphs -bunchy -buncos -bundle -bundts -bunged -bungee -bungle -bunion -bunked -bunker -bunkos -bunkum -bunted -bunter -bunyas -buoyed -bupkes -bupkus -buppie -buqsha -burans -burble -burbly -burbot -burden -burdie -bureau -burets -burgee -burger -burghs -burgle -burgoo -burial -buried -burier -buries -burins -burkas -burked -burker -burkes -burlap -burled -burler -burley -burned -burner -burnet -burnie -burped -burqas -burred -burrer -burros -burrow -bursae -bursal -bursar -bursas -burses -bursts -burton -busbar -busboy -bushed -bushel -busher -bushes -bushwa -busied -busier -busies -busily -busing -busked -busker -buskin -busman -busmen -bussed -busses -busted -buster -bustic -bustle -butane -butene -buteos -butled -butler -butles -butted -butter -buttes -button -bututs -butyls -buyers -buying -buyoff -buyout -buzuki -buzzed -buzzer -buzzes -bwanas -byelaw -bygone -bylaws -byline -byname -bypass -bypast -bypath -byplay -byrled -byrnie -byroad -byssal -byssus -bytalk -byways -byword -bywork -byzant -cabala -cabals -cabana -cabbed -cabbie -cabers -cabins -cabled -cabler -cables -cablet -cabman -cabmen -cabobs -cacaos -cached -caches -cachet -cachou -cackle -cactus -caddie -caddis -cadent -cadets -cadged -cadger -cadges -cadmic -cadres -caecal -caecum -caeoma -caesar -caftan -cagers -cagier -cagily -caging -cahier -cahoot -cahows -caiman -caique -cairds -cairns -cairny -cajole -cakier -caking -calami -calash -calcar -calces -calcic -calesa -calico -califs -caliph -calked -calker -calkin -callan -callas -called -callee -caller -callet -callow -callus -calmed -calmer -calmly -calory -calpac -calque -calved -calves -calxes -camail -camber -cambia -camels -cameos -camera -camion -camisa -camise -camlet -cammie -camped -camper -campos -campus -canals -canape -canard -canary -cancan -cancel -cancer -cancha -candid -candle -candor -caners -canful -cangue -canids -canine -caning -canker -cannas -canned -cannel -canner -cannie -cannon -cannot -canoed -canoer -canoes -canola -canons -canopy -cansos -cantal -canted -canter -canthi -cantic -cantle -canton -cantor -cantos -cantus -canula -canvas -canyon -capers -capful -capias -capita -caplet -caplin -capons -capote -capped -capper -capric -capris -capsid -captan -captor -carack -carafe -carate -carats -carbon -carbos -carboy -carcel -carded -carder -cardia -cardio -cardon -careen -career -carers -caress -carets -carful -cargos -carhop -caribe -caried -caries -carina -caring -carked -carles -carlin -carman -carmen -carnal -carnet -carney -carnie -carobs -caroch -caroli -carols -caroms -carpal -carped -carpel -carper -carpet -carpus -carrel -carrom -carrot -carses -carted -cartel -carter -cartes -carton -cartop -carved -carvel -carven -carver -carves -casaba -casava -casbah -casefy -caseic -casein -casern -cashaw -cashed -cashes -cashew -cashoo -casing -casini -casino -casita -casked -casket -casque -caster -castes -castle -castor -casual -catalo -catchy -catena -caters -catgut -cation -catkin -catlin -catnap -catnip -catsup -catted -cattie -cattle -caucus -caudad -caudal -caudex -caudle -caught -caulds -caules -caulis -caulks -causal -caused -causer -causes -causey -caveat -cavern -cavers -caviar -cavies -cavils -caving -cavity -cavort -cawing -cayman -cayuse -ceased -ceases -cebids -ceboid -cecity -cedarn -cedars -cedary -ceders -ceding -cedula -ceibas -ceiled -ceiler -ceilis -celebs -celery -celiac -cellae -cellar -celled -cellos -celoms -cement -cenote -censed -censer -censes -censor -census -centai -cental -centas -center -centos -centra -centre -centum -ceorls -cerate -cercal -cercis -cercus -cereal -cereus -cerias -cering -ceriph -cerise -cerite -cerium -cermet -cerous -certes -ceruse -cervid -cervix -cesium -cessed -cesses -cestas -cestoi -cestos -cestus -cesura -cetane -chabuk -chacma -chadar -chador -chadri -chaeta -chafed -chafer -chafes -chaffs -chaffy -chaine -chains -chairs -chaise -chakra -chalah -chaleh -chalet -chalks -chalky -challa -chally -chalot -chammy -champs -champy -chance -chancy -change -changs -chants -chanty -chapel -chapes -charas -chards -chared -chares -charge -charka -charks -charms -charro -charrs -charry -charts -chased -chaser -chases -chasms -chasmy -chasse -chaste -chatty -chaunt -chawed -chawer -chazan -cheapo -cheaps -cheats -chebec -checks -cheder -cheeks -cheeky -cheeps -cheero -cheers -cheery -cheese -cheesy -chefed -chegoe -chelae -chelas -chemic -chemos -cheque -cherry -cherts -cherty -cherub -chests -chesty -chetah -cheths -chevre -chewed -chewer -chiasm -chiaus -chicas -chicer -chichi -chicks -chicle -chicly -chicos -chided -chider -chides -chiefs -chield -chiels -chigoe -childe -chiles -chilis -chilli -chills -chilly -chimar -chimbs -chimed -chimer -chimes -chimla -chimps -chinas -chinch -chined -chines -chinks -chinky -chinos -chints -chintz -chippy -chiral -chirks -chirms -chiros -chirps -chirpy -chirre -chirrs -chirus -chisel -chital -chitin -chiton -chitty -chives -chivvy -choana -chocks -choice -choirs -choked -choker -chokes -chokey -cholas -choler -cholla -cholos -chomps -chooks -choose -choosy -chopin -choppy -choral -chords -chorea -chored -chores -choric -chorus -chosen -choses -chotts -chough -chouse -choush -chowed -chowse -chrism -chroma -chrome -chromo -chromy -chubby -chucks -chucky -chufas -chuffs -chuffy -chukar -chukka -chummy -chumps -chunks -chunky -chuppa -church -churls -churns -churro -churrs -chuted -chutes -chyles -chymes -chymic -cibols -cicada -cicala -cicale -cicely -cicero -ciders -cigars -cilice -cilium -cinder -cinema -cineol -cinque -cipher -circle -circus -cirque -cirrus -ciscos -cisted -cistus -citers -cither -citied -cities -citify -citing -citola -citole -citral -citric -citrin -citron -citrus -civets -civics -civies -civism -clachs -clacks -clades -claims -clammy -clamor -clamps -clangs -clanks -clanky -claque -claret -claros -clasps -claspt -classy -clasts -clause -claver -claves -clavus -clawed -clawer -claxon -clayed -clayey -cleans -clears -cleats -cleave -cleeks -clefts -clench -cleome -cleped -clepes -clergy -cleric -clerid -clerks -clever -clevis -clewed -cliche -clicks -client -cliffs -cliffy -clifts -climax -climbs -climes -clinal -clinch -clines -clings -clingy -clinic -clinks -clique -cliquy -clitic -clivia -cloaca -cloaks -cloche -clocks -cloddy -cloggy -clomps -clonal -cloned -cloner -clones -clonic -clonks -clonus -cloots -cloque -closed -closer -closes -closet -clothe -cloths -clotty -clouds -cloudy -clough -clours -clouts -cloven -clover -cloves -clowns -cloyed -clozes -clubby -clucks -cluing -clumps -clumpy -clumsy -clunks -clunky -clutch -clypei -cnidae -coacts -coalas -coaled -coaler -coapts -coarse -coasts -coated -coatee -coater -coatis -coaxal -coaxed -coaxer -coaxes -cobalt -cobber -cobble -cobias -cobles -cobnut -cobras -cobweb -cocain -coccal -coccic -coccid -coccus -coccyx -cochin -cocoas -cocoon -codded -codder -coddle -codecs -codeia -codens -coders -codify -coding -codlin -codons -coedit -coelom -coempt -coerce -coeval -coffee -coffer -coffin -coffle -cogent -cogged -cogito -cognac -cogons -cogway -cohead -coheir -cohere -cohogs -cohort -cohosh -cohost -cohune -coifed -coiffe -coigne -coigns -coiled -coiler -coined -coiner -coital -coitus -cojoin -coking -colbys -colder -coldly -colead -coleus -colics -colies -colins -collar -collet -collie -collop -colobi -cologs -colone -coloni -colons -colony -colors -colour -colter -colugo -column -colure -colzas -comade -comake -comate -combat -combed -comber -combes -combos -comedo -comedy -comely -comers -cometh -comets -comfit -comics -coming -comity -commas -commie -commit -commix -common -comose -comous -compas -comped -compel -comply -compos -compts -comtes -concha -concho -conchs -conchy -concur -condor -condos -coneys -confab -confer -confit -congas -congee -conger -conges -congii -congos -congou -conics -conies -conine -coning -conins -conium -conked -conker -conned -conner -conoid -consol -consul -contes -contos -contra -convex -convey -convoy -coocoo -cooeed -cooees -cooers -cooeys -cooing -cooked -cooker -cookey -cookie -cooled -cooler -coolie -coolly -coolth -coombe -coombs -cooped -cooper -coopts -cooter -cootie -copalm -copals -copays -copeck -copens -copers -copied -copier -copies -coping -coplot -copout -copped -copper -coppra -coprah -copras -copses -copter -copula -coquet -corals -corban -corbel -corbie -corded -corder -cordon -corers -corgis -coring -corium -corked -corker -cormel -cornea -corned -cornel -corner -cornet -cornua -cornus -corody -corona -corpse -corpus -corral -corrie -corsac -corses -corset -cortex -cortin -corvee -corves -corvet -corvid -corymb -coryza -cosecs -cosets -coseys -coshed -cosher -coshes -cosied -cosier -cosies -cosign -cosily -cosine -cosmic -cosmid -cosmos -cosset -costae -costal -costar -costed -coster -costly -cotans -coteau -coting -cottae -cottar -cottas -cotter -cotton -cotype -cougar -coughs -coulee -coulis -counts -county -couped -coupes -couple -coupon -course -courts -cousin -couter -couths -covary -covens -covers -covert -covets -coveys -coving -covins -cowage -coward -cowboy -cowers -cowier -cowing -cowled -cowman -cowmen -cowpat -cowpea -cowpie -cowpox -cowrie -coxing -coydog -coyest -coying -coyish -coyote -coypou -coypus -cozens -cozeys -cozied -cozier -cozies -cozily -cozzes -craals -crabby -cracks -cracky -cradle -crafts -crafty -craggy -crakes -crambe -crambo -cramps -crampy -cranch -craned -cranes -crania -cranks -cranky -cranny -crapes -crappy -crases -crasis -cratch -crated -crater -crates -craton -cravat -craved -craven -craver -craves -crawls -crawly -crayon -crazed -crazes -creaks -creaky -creams -creamy -crease -creasy -create -creche -credal -credit -credos -creeds -creeks -creels -creeps -creepy -creese -creesh -cremes -crenel -creole -creped -crepes -crepey -crepon -cresol -cressy -crests -cresyl -cretic -cretin -crewed -crewel -cricks -criers -crikey -crimes -crimps -crimpy -cringe -crinum -cripes -crises -crisic -crisis -crisps -crispy -crissa -crista -critic -croaks -croaky -crocks -crocus -crofts -crojik -crones -crooks -croons -crores -crosse -crotch -croton -crouch -croupe -croups -croupy -crouse -croute -crowds -crowdy -crowed -crower -crowns -crozer -crozes -cruces -crucks -cruddy -cruder -crudes -cruets -cruise -crumbs -crumby -crummy -crumps -crunch -cruors -crural -cruses -cruset -crusts -crusty -crutch -cruxes -crwths -crying -crypto -crypts -cuatro -cubage -cubebs -cubers -cubics -cubing -cubism -cubist -cubiti -cubits -cuboid -cuckoo -cuddie -cuddle -cuddly -cudgel -cueing -cuesta -cuffed -cuisse -culets -cullay -culled -culler -cullet -cullis -culmed -culpae -cultch -cultic -cultus -culver -cumber -cumbia -cumins -cummer -cummin -cumuli -cundum -cuneal -cunner -cupels -cupful -cupids -cupola -cuppas -cupped -cupper -cupric -cuprum -cupula -cupule -curacy -curagh -curara -curare -curari -curate -curbed -curber -curded -curdle -curers -curets -curfew -curiae -curial -curies -curing -curios -curite -curium -curled -curler -curlew -curran -curred -currie -cursed -curser -curses -cursor -curtal -curter -curtly -curtsy -curule -curved -curves -curvet -curvey -cuscus -cusecs -cushat -cushaw -cuspal -cusped -cuspid -cuspis -cussed -cusser -cusses -cussos -custom -custos -cutely -cutest -cutesy -cuteys -cuties -cutins -cutlas -cutler -cutlet -cutoff -cutout -cutter -cuttle -cutups -cuvees -cyanic -cyanid -cyanin -cyborg -cycads -cycled -cycler -cycles -cyclic -cyclin -cyclos -cyders -cyeses -cyesis -cygnet -cymars -cymbal -cymene -cymlin -cymoid -cymols -cymose -cymous -cynics -cypher -cypres -cyprus -cystic -cytons -dabbed -dabber -dabble -dachas -dacite -dacker -dacoit -dacron -dactyl -daddle -dadgum -dadoed -dadoes -daedal -daemon -daffed -dafter -daftly -daggas -dagger -daggle -dagoba -dagoes -dahlia -dahoon -daiker -daikon -daimen -daimio -daimon -daimyo -dainty -daises -dakoit -dalasi -daledh -daleth -dalles -dalton -damage -damans -damars -damask -dammar -dammed -dammer -dammit -damned -damner -damped -dampen -damper -damply -damsel -damson -danced -dancer -dances -dander -dandle -danged -danger -dangle -dangly -danios -danish -danker -dankly -daphne -dapped -dapper -dapple -darbar -darers -darics -daring -darked -darken -darker -darkey -darkie -darkle -darkly -darned -darnel -darner -darted -darter -dartle -dashed -dasher -dashes -dashis -dassie -datary -datcha -daters -dating -dative -dattos -datums -datura -daubed -dauber -daubes -daubry -daunts -dauted -dautie -davens -davies -davits -dawdle -dawing -dawned -dawted -dawtie -daybed -dayfly -daylit -dazing -dazzle -deacon -deaden -deader -deadly -deafen -deafer -deafly -deairs -dealer -deaned -dearer -dearie -dearly -dearth -deasil -deaths -deathy -deaved -deaves -debags -debark -debars -debase -debate -debeak -debits -debone -debris -debtor -debugs -debunk -debuts -debyes -decade -decafs -decals -decamp -decane -decant -decare -decays -deceit -decent -decern -decide -decile -decked -deckel -decker -deckle -declaw -decoct -decode -decors -decoys -decree -decury -dedans -deduce -deduct -deeded -deejay -deemed -deepen -deeper -deeply -deewan -deface -defame -defang -defats -defeat -defect -defend -defers -deffer -defied -defier -defies -defile -define -deflea -defoam -defogs -deform -defrag -defray -defter -deftly -defuel -defund -defuse -defuze -degage -degame -degami -degerm -degree -degums -degust -dehorn -dehort -deiced -deicer -deices -deific -deigns -deisms -deists -deixis -deject -dekare -deking -dekkos -delate -delays -delead -delete -delfts -delict -delime -delish -delist -deltas -deltic -delude -deluge -deluxe -delved -delver -delves -demand -demark -demast -demean -dement -demies -demise -demits -demobs -demode -demoed -demons -demote -demure -demurs -denari -denars -denary -dengue -denial -denied -denier -denies -denims -denned -denote -denser -dental -dented -dentil -dentin -denude -deodar -depart -depend -deperm -depict -deploy -depone -deport -depose -depots -depths -depute -deputy -derail -derate -derats -derays -deride -derive -dermal -dermas -dermic -dermis -derris -desalt -desand -descry -desert -design -desire -desist -desman -desmid -desorb -desoxy -despot -detach -detail -detain -detect -detent -deters -detest -detick -detour -deuced -deuces -devein -devels -devest -device -devils -devise -devoid -devoir -devons -devote -devour -devout -dewans -dewars -dewier -dewily -dewing -dewlap -dewool -deworm -dexies -dexter -dextro -dezinc -dharma -dharna -dhobis -dholes -dhooly -dhoora -dhooti -dhotis -dhurna -dhutis -diacid -diadem -dialed -dialer -dialog -diamin -diaper -diapir -diatom -diazin -dibbed -dibber -dibble -dibbuk -dicast -dicers -dicier -dicing -dicots -dictum -didact -diddle -diddly -didies -didoes -dieing -dienes -dieoff -diesel -dieses -diesis -dieted -dieter -differ -digamy -digest -digged -digger -dights -digits -diglot -dikdik -dikers -diking -diktat -dilate -dildoe -dildos -dilled -dilute -dimers -dimity -dimmed -dimmer -dimout -dimple -dimply -dimwit -dinars -dindle -dinero -diners -dinged -dinger -dinges -dingey -dinghy -dingle -dingus -dining -dinked -dinkey -dinkly -dinkum -dinned -dinner -dinted -diobol -diodes -dioecy -dioxan -dioxid -dioxin -diplex -diploe -dipnet -dipody -dipole -dipped -dipper -dipsas -dipsos -diquat -dirams -dirdum -direct -direly -direst -dirges -dirham -dirked -dirled -dirndl -disarm -disbar -disbud -disced -discos -discus -diseur -dished -dishes -disked -dismal -dismay -dismes -disown -dispel -dissed -disses -distal -distil -disuse -dither -dittos -ditzes -diuron -divans -divers -divert -divest -divide -divine -diving -divots -diwans -dixits -dizens -djebel -djinni -djinns -djinny -doable -doated -dobber -dobbin -dobies -doblas -doblon -dobras -dobros -dobson -docent -docile -docked -docker -docket -doctor -dodder -dodged -dodgem -dodger -dodges -dodoes -doffed -doffer -dogdom -dogear -dogeys -dogged -dogger -doggie -dogies -dogleg -dogmas -dognap -doiled -doings -doited -doling -dollar -dolled -dollop -dolman -dolmas -dolmen -dolors -dolour -domain -domine -doming -domino -donate -donees -dongle -donjon -donkey -donnas -donned -donnee -donors -donsie -donuts -donzel -doobie -doodad -doodle -doodoo -doofus -doolee -doolie -doomed -doowop -doozer -doozie -dopant -dopers -dopier -dopily -doping -dorado -dorbug -dories -dormer -dormie -dormin -dorper -dorsad -dorsal -dorsel -dorser -dorsum -dosage -dosers -dosing -dossal -dossed -dossel -dosser -dosses -dossil -dotage -dotard -doters -dotier -doting -dotted -dottel -dotter -dottle -double -doubly -doubts -doughs -dought -doughy -doulas -doumas -dourah -douras -dourer -dourly -doused -douser -douses -dovens -dovish -dowels -dowers -dowery -dowing -downed -downer -dowsed -dowser -dowses -doxies -doyens -doyley -dozens -dozers -dozier -dozily -dozing -drably -drachm -draffs -draffy -drafts -drafty -dragee -draggy -dragon -drails -drains -drakes -dramas -drawee -drawer -drawls -drawly -drayed -dreads -dreams -dreamt -dreamy -drears -dreary -drecks -drecky -dredge -dreggy -dreich -dreidl -dreigh -drench -dressy -driegh -driers -driest -drifts -drifty -drills -drinks -drippy -drivel -driven -driver -drives -drogue -droids -droits -drolls -drolly -dromon -droned -droner -drones -drongo -drools -drooly -droops -droopy -dropsy -drosky -drossy -drouks -drouth -droved -drover -droves -drownd -drowns -drowse -drowsy -drudge -druggy -druids -drumly -drunks -drupes -druses -dryads -dryers -dryest -drying -dryish -drylot -dually -dubbed -dubber -dubbin -ducats -ducked -ducker -duckie -ductal -ducted -duddie -dudeen -duding -dudish -dueled -dueler -duelli -duello -duende -duenna -dueted -duffel -duffer -duffle -dugong -dugout -duiker -duking -dulcet -dulias -dulled -duller -dulses -dumbed -dumber -dumbly -dumbos -dumdum -dumped -dumper -dunams -dunces -dunged -dunite -dunked -dunker -dunlin -dunned -dunner -dunted -duolog -duomos -dupers -dupery -duping -duplex -dupped -durbar -duress -durian -during -durion -durned -durocs -durras -durrie -durums -dusked -dusted -duster -dustup -duties -duvets -dwarfs -dweebs -dweeby -dwells -dwined -dwines -dyable -dyadic -dybbuk -dyeing -dyings -dyking -dynamo -dynast -dynein -dynels -dynode -dyvour -eagers -eagled -eagles -eaglet -eagres -earbud -earful -earing -earlap -earned -earner -earths -earthy -earwax -earwig -easels -easier -easies -easily -easing -easter -eaters -eatery -eating -ebbets -ebbing -ebooks -ecarte -ecesic -ecesis -echard -eching -echini -echoed -echoer -echoes -echoey -echoic -eclair -eclats -ectype -eczema -eddied -eddies -eddoes -edemas -edenic -edgers -edgier -edgily -edging -edible -edicts -ediles -edited -editor -educed -educes -educts -eelier -eerier -eerily -efface -effect -effete -effigy -efflux -effort -effuse -egesta -egests -eggars -eggcup -eggers -egging -eggnog -egises -egoism -egoist -egress -egrets -eiders -eidola -eighth -eights -eighty -eikons -either -ejecta -ejects -ekuele -elains -elands -elapid -elapse -elated -elater -elates -elbows -elders -eldest -elects -elegit -elemis -eleven -elevon -elfins -elfish -elicit -elided -elides -elints -elites -elixir -elmier -elodea -eloign -eloins -eloped -eloper -elopes -eluant -eluate -eluded -eluder -eludes -eluent -eluted -elutes -eluvia -elvers -elvish -elytra -emails -embalm -embank -embark -embars -embays -embeds -embers -emblem -embody -emboli -emboly -embosk -emboss -embows -embrue -embryo -emceed -emcees -emdash -emeers -emends -emerge -emerod -emeses -emesis -emetic -emetin -emeute -emigre -emmers -emmets -emodin -emoted -emoter -emotes -empale -empery -empire -employ -emydes -enable -enacts -enamel -enamor -enates -enatic -encage -encamp -encase -encash -encina -encode -encore -encyst -endash -endear -enders -ending -endite -endive -endows -endrin -endued -endues -endure -enduro -energy -enface -enfold -engage -engild -engine -engird -engirt -englut -engram -engulf -enhalo -enigma -enisle -enjoin -enjoys -enlace -enlist -enmesh -enmity -ennead -ennuis -ennuye -enokis -enolic -enosis -enough -enrage -enrapt -enrich -enrobe -enroll -enrols -enroot -enserf -ensign -ensile -ensoul -ensued -ensues -ensure -entail -entera -enters -entice -entire -entity -entoil -entomb -entrap -entree -enured -enures -envied -envier -envies -enviro -envois -envoys -enwind -enwomb -enwrap -enzyme -enzyms -eocene -eolian -eolith -eonian -eonism -eosine -eosins -epacts -eparch -ephahs -ephebe -ephebi -ephods -ephori -ephors -epical -epigon -epilog -epimer -epizoa -epochs -epodes -eponym -epopee -eposes -equals -equate -equids -equine -equips -equity -erased -eraser -erases -erbium -erects -erenow -ergate -ergots -ericas -eringo -ermine -eroded -erodes -eroses -erotic -errand -errant -errata -erring -errors -ersatz -eructs -erugos -erupts -ervils -eryngo -escape -escarp -escars -eschar -eschew -escort -escots -escrow -escudo -eskars -eskers -espial -espied -espies -esprit -essays -essoin -estate -esteem -esters -estops -estral -estray -estrin -estrum -estrus -etalon -etamin -etapes -etched -etcher -etches -eterne -ethane -ethene -ethers -ethics -ethion -ethnic -ethnos -ethoxy -ethyls -ethyne -etoile -etudes -etwees -etymon -euchre -eulogy -eunuch -eupnea -eureka -euripi -euroky -eutaxy -evaded -evader -evades -evened -evener -evenly -events -everts -evicts -eviler -evilly -evince -evited -evites -evoked -evoker -evokes -evolve -evulse -evzone -exacta -exacts -exalts -examen -exarch -exceed -excels -except -excess -excide -excise -excite -excuse -exedra -exempt -exequy -exerts -exeunt -exhale -exhort -exhume -exiled -exiler -exiles -exilic -exines -exists -exited -exodoi -exodos -exodus -exogen -exonic -exonym -exotic -expand -expats -expect -expels -expend -expert -expire -expiry -export -expose -exsect -exsert -extant -extend -extent -extern -extoll -extols -extort -extras -exuded -exudes -exults -exurbs -exuvia -eyases -eyebar -eyecup -eyeful -eyeing -eyelet -eyelid -eyries -fabber -fabled -fabler -fables -fabric -facade -facers -facete -facets -faceup -facial -facile -facing -factor -facula -fadein -faders -fading -faenas -faerie -failed -faille -fainer -faints -faired -fairer -fairly -faiths -fajita -fakeer -fakers -fakery -faking -fakirs -falces -falcon -fallal -fallen -faller -fallow -falser -falsie -falter -family -famine -faming -famish -famous -famuli -fandom -fanega -fanfic -fangas -fanged -fanion -fanjet -fanned -fanner -fanons -fantod -fantom -fanums -faqirs -faquir -farads -farced -farcer -farces -farcie -farded -fardel -farers -farfal -farfel -farina -faring -farles -farmed -farmer -farrow -farted -fasces -fascia -fashed -fashes -fasted -fasten -faster -father -fathom -fating -fatwas -faucal -fauces -faucet -faulds -faults -faulty -faunae -faunal -faunas -fauves -favela -favism -favors -favour -fawned -fawner -faxing -faying -fazing -fealty -feared -fearer -feased -feases -feasts -feater -featly -feazed -feazes -feckly -fecund -fedora -feeble -feebly -feeder -feeing -feeler -feezed -feezes -feigns -feijoa -feints -feirie -feists -feisty -felids -feline -fellah -fellas -felled -feller -felloe -fellow -felons -felony -felsic -felted -female -femmes -femora -femurs -fenced -fencer -fences -fended -fender -fennec -fennel -feoffs -ferals -ferbam -feriae -ferial -ferias -ferine -ferity -ferlie -fermis -ferrel -ferret -ferric -ferrum -ferula -ferule -fervid -fervor -fescue -fessed -fesses -festal -fester -fetial -fetich -feting -fetish -fetors -fetted -fetter -fettle -feuars -feudal -feuded -feuing -fevers -fewest -feyest -fezzed -fezzes -fiacre -fiance -fiasco -fibbed -fibber -fibers -fibres -fibril -fibrin -fibula -fiches -fichus -ficins -fickle -fickly -ficoes -fiddle -fiddly -fidged -fidges -fidget -fields -fiends -fierce -fiesta -fifers -fifing -fifths -figged -fights -figure -filers -filets -filial -filing -filled -filler -filles -fillet -fillip -fillos -filmed -filmer -filmic -filmis -filose -filter -filths -filthy -fimble -finale -finals -fincas -finder -finely -finery -finest -finger -finial -fining -finish -finite -finito -finked -finned -fiords -fipple -fiques -firers -firing -firkin -firman -firmed -firmer -firmly -firsts -firths -fiscal -fished -fisher -fishes -fistic -fitchy -fitful -fitted -fitter -fivers -fixate -fixers -fixing -fixity -fixure -fizgig -fizzed -fizzer -fizzes -fizzle -fjelds -fjords -flabby -flacks -flacon -flaggy -flagon -flails -flairs -flaked -flaker -flakes -flakey -flambe -flamed -flamen -flamer -flames -flanes -flanks -flappy -flared -flares -flashy -flasks -flatly -flatus -flaunt -flauta -flavin -flavor -flawed -flaxen -flaxes -flayed -flayer -fleams -fleche -flecks -flecky -fledge -fledgy -fleece -fleech -fleecy -fleers -fleets -flench -flense -fleshy -fletch -fleury -flexed -flexes -flexor -fleyed -flicks -fliers -fliest -flight -flimsy -flinch -flings -flints -flinty -flippy -flirts -flirty -flitch -flited -flites -floats -floaty -flocci -flocks -flocky -flongs -floods -flooey -flooie -floors -floosy -floozy -floppy -florae -floral -floras -floret -florid -florin -flossy -flotas -flours -floury -flouts -flowed -flower -fluent -fluffs -fluffy -fluids -fluish -fluked -flukes -flukey -flumed -flumes -flumps -flunks -flunky -fluors -flurry -fluted -fluter -flutes -flutey -fluxed -fluxes -fluyts -flyboy -flybys -flyers -flying -flyman -flymen -flyoff -flysch -flyted -flytes -flyway -foaled -foamed -foamer -fobbed -fodder -fodgel -foehns -foeman -foemen -foetal -foetid -foetor -foetus -fogbow -fogdog -fogeys -fogged -fogger -fogies -foible -foiled -foined -foison -foists -folate -folded -folder -foldup -foleys -foliar -folios -folium -folkie -folksy -folles -follis -follow -foment -fomite -fonded -fonder -fondle -fondly -fondue -fondus -fontal -foodie -fooled -footed -footer -footie -footle -footsy -foozle -fopped -forage -forams -forays -forbad -forbid -forbye -forced -forcer -forces -forded -fordid -foreby -foredo -forego -forest -forgat -forged -forger -forges -forget -forgot -forint -forked -forker -formal -format -formed -formee -former -formes -formic -formol -formyl -fornix -forrit -fortes -fortis -forums -forwhy -fossae -fossas -fosses -fossil -foster -fought -fouled -fouler -foully -founds -founts -fourth -foveae -foveal -foveas -fowled -fowler -foxier -foxily -foxing -foyers -fozier -fracas -fracti -fraena -frails -fraise -framed -framer -frames -francs -franks -frappe -frater -frauds -frayed -frazil -freaks -freaky -freely -freers -freest -freeze -french -frenum -frenzy -freres -fresco -fretty -friars -friary -fridge -friend -friers -frieze -friges -fright -frigid -frijol -frills -frilly -fringe -fringy -frisee -frises -frisks -frisky -frites -friths -fritts -frivol -frized -frizer -frizes -frizzy -frocks -froggy -frolic -fronds -fronts -frosts -frosty -froths -frothy -frouzy -frowns -frowst -frowsy -frowzy -frozen -frugal -fruits -fruity -frumps -frumpy -frusta -fryers -frying -frypan -fubbed -fucoid -fucose -fucous -fuddle -fudged -fudges -fueled -fueler -fugato -fugged -fugios -fugled -fugles -fugued -fugues -fuhrer -fulcra -fulfil -fulgid -fulham -fullam -fulled -fuller -fulmar -fumble -fumers -fumets -fumier -fuming -fumuli -funded -funder -fundus -funest -fungal -fungic -fungus -funked -funker -funkia -funned -funnel -funner -furane -furans -furfur -furies -furled -furler -furore -furors -furred -furrow -furzes -fusain -fusees -fusels -fusile -fusils -fusing -fusion -fussed -fusser -fusses -fustic -fusuma -futile -futons -future -futzed -futzes -fuzees -fuzils -fuzing -fuzzed -fuzzes -fylfot -fynbos -fyttes -gabbed -gabber -gabble -gabbro -gabies -gabion -gabled -gables -gaboon -gadded -gadder -gaddis -gadfly -gadget -gadids -gadoid -gaeing -gaffed -gaffer -gaffes -gagaku -gagers -gagged -gagger -gaggle -gaging -gagman -gagmen -gaiety -gaijin -gained -gainer -gainly -gainst -gaited -gaiter -galago -galahs -galaxy -galeae -galeas -galena -galere -galiot -galled -gallet -galley -gallic -gallon -gallop -gallus -galoot -galops -galore -galosh -galyac -galyak -gamays -gambas -gambes -gambia -gambir -gambit -gamble -gambol -gamely -gamers -gamest -gamete -gamier -gamily -gamine -gaming -gamins -gammas -gammed -gammer -gammon -gamuts -gander -ganefs -ganevs -ganged -ganger -gangly -gangue -ganjah -ganjas -gannet -ganofs -ganoid -gantry -gaoled -gaoler -gapers -gaping -gapped -garage -garbed -garble -garcon -gardai -garden -garget -gargle -garish -garlic -garner -garnet -garote -garred -garret -garron -garter -garths -garvey -gasbag -gascon -gashed -gasher -gashes -gasify -gasket -gaskin -gaslit -gasman -gasmen -gasped -gasper -gassed -gasser -gasses -gasted -gaster -gateau -gaters -gather -gating -gators -gauche -gaucho -gauged -gauger -gauges -gaults -gaumed -gauzes -gavage -gavels -gavial -gavots -gawked -gawker -gawped -gawper -gawsie -gayals -gazabo -gazars -gazebo -gazers -gazing -gazoos -gazump -geared -gecked -geckos -geegaw -geeing -geeked -geests -geezer -geisha -gelada -gelant -gelate -gelati -gelato -gelcap -gelded -gelder -gelees -gelled -gemmae -gemmed -gemote -gemots -gender -genera -genets -geneva -genial -genies -genips -genius -genoas -genome -genoms -genres -genros -gentes -gentil -gentle -gently -gentoo -gentry -geodes -geodic -geoids -gerahs -gerbil -gerent -german -germen -gerund -gestes -gestic -getter -getups -gewgaw -geyser -gharri -gharry -ghauts -ghazis -gherao -ghetto -ghibli -ghosts -ghosty -ghouls -ghylls -giants -giaour -gibbed -gibber -gibbet -gibbon -gibers -gibing -giblet -gibson -giddap -gieing -gifted -giftee -gigged -giggle -giggly -giglet -giglot -gigolo -gigots -gigues -gilded -gilder -gilled -giller -gillie -gimbal -gimels -gimlet -gimmal -gimmes -gimmie -gimped -gingal -ginger -gingko -ginkgo -ginned -ginner -gipons -gipped -gipper -girded -girder -girdle -girlie -girned -girons -girted -girths -gismos -gitano -gitted -gittin -givens -givers -giving -gizmos -glaces -glacis -glades -gladly -glaire -glairs -glairy -glaive -glamor -glance -glands -glared -glares -glassy -glazed -glazer -glazes -gleams -gleamy -gleans -glebae -glebes -gledes -gleeds -gleeks -gleets -gleety -glegly -gleyed -glibly -glided -glider -glides -gliffs -glimed -glimes -glints -glinty -glioma -glitch -glitzy -gloams -gloats -global -globby -globed -globes -globin -gloggs -glomus -glooms -gloomy -gloppy -gloria -glossa -glossy -glosts -glouts -gloved -glover -gloves -glowed -glower -glozed -glozes -glucan -gluers -gluier -gluily -gluing -glumes -glumly -glumpy -glunch -gluons -glutei -gluten -glutes -glycan -glycin -glycol -glycyl -glyphs -gnarls -gnarly -gnarrs -gnatty -gnawed -gnawer -gneiss -gnomes -gnomic -gnomon -gnoses -gnosis -goaded -goaled -goalie -goanna -goatee -gobang -gobans -gobbed -gobbet -gobble -gobies -goblet -goblin -goboes -gobony -godets -godown -godson -gofers -goffer -goggle -goggly -goglet -goings -golden -golder -golems -golfed -golfer -golosh -gombos -gomers -gomuti -gonefs -goners -gonged -goniff -gonifs -gonion -gonium -gonofs -gonoph -goodby -goodie -goodly -goofed -googly -googol -gooier -gooney -goonie -gooral -goosed -gooses -goosey -gopher -gorals -gorged -gorger -gorges -gorget -gorgon -gorhen -gorier -gorily -goring -gormed -gorses -gospel -gossan -gossip -gotcha -gothic -gotten -gouged -gouger -gouges -gourde -gourds -govern -gowans -gowany -gowned -goyish -graals -grabby -graben -graced -graces -graded -grader -grades -gradin -gradus -grafts -graham -grails -grains -grainy -gramas -gramma -gramme -grampa -gramps -grands -grange -granny -grants -granum -grapes -grapey -graphs -grappa -grasps -grassy -grated -grater -grates -gratin -gratis -graved -gravel -graven -graver -graves -gravid -grayed -grayer -grayly -grazed -grazer -grazes -grease -greasy -greats -greave -grebes -greeds -greedy -greens -greeny -greets -gregos -greige -gremmy -greyed -greyer -greyly -grided -grides -griefs -grieve -griffe -griffs -grifts -grigri -grille -grills -grilse -grimed -grimes -grimly -grinch -grinds -gringa -gringo -griots -griped -griper -gripes -gripey -grippe -grippy -grisly -grison -grists -griths -gritty -grivet -groans -groats -grocer -groggy -grooms -groove -groovy -groped -groper -gropes -grosze -groszy -grotto -grotty -grouch -ground -groups -grouse -grouts -grouty -groved -grovel -groves -grower -growls -growly -growth -groyne -grubby -grudge -gruels -gruffs -gruffy -grugru -grumes -grumps -grumpy -grunge -grungy -grunts -grutch -guacos -guaiac -guanay -guanin -guanos -guards -guavas -guenon -guests -guffaw -guggle -guglet -guided -guider -guides -guidon -guilds -guiled -guiles -guilts -guilty -guimpe -guinea -guiros -guised -guises -guitar -gulags -gulden -gulfed -gulled -gullet -gulley -gulped -gulper -gumbos -gummas -gummed -gummer -gundog -gunite -gunman -gunmen -gunned -gunnel -gunnen -gunner -gunsel -gurged -gurges -gurgle -gurnet -gurney -gushed -gusher -gushes -gusset -gussie -gusted -guttae -gutted -gutter -guttle -guying -guyots -guzzle -gweduc -gybing -gyozas -gypped -gypper -gypsum -gyrase -gyrate -gyrene -gyring -gyrons -gyrose -gyttja -gyving -habile -habits -haboob -haceks -hacked -hackee -hackie -hackle -hackly -hading -hadith -hadjee -hadjes -hadjis -hadron -haeing -haemal -haemic -haemin -haeres -haffet -haffit -hafted -hafter -hagbut -hagdon -hagged -haggis -haggle -haikus -hailed -hailer -haints -hairdo -haired -hajjes -hajjis -hakeem -hakims -halala -halals -halers -haleru -halest -halide -halids -haling -halite -hallah -hallal -hallel -halloa -halloo -hallos -hallot -hallow -hallux -halmas -haloed -haloes -haloid -halons -halted -halter -halutz -halvah -halvas -halved -halves -hamada -hamals -hamate -hamaul -hamlet -hammal -hammam -hammed -hammer -hamper -hamuli -hamzah -hamzas -hances -handax -handed -hander -handle -hangar -hanger -hangul -hangup -haniwa -hanked -hanker -hankie -hansas -hansel -hanses -hansom -hanted -hantle -haoles -happed -happen -hapten -haptic -harbor -harden -harder -hardly -hareem -harems -haring -harked -harken -harlot -harmed -harmer -harmin -harped -harper -harpin -harrow -hartal -hashed -hashes -haslet -hasped -hassel -hassle -hasted -hasten -hastes -hatbox -haters -hatful -hating -hatpin -hatred -hatted -hatter -haughs -hauled -hauler -haulms -haulmy -haunch -haunts -hausen -havens -havers -having -havior -havocs -hawala -hawing -hawked -hawker -hawkey -hawkie -hawser -hawses -hayers -haying -haymow -hazans -hazard -hazels -hazers -hazier -hazily -hazing -hazmat -hazzan -headed -header -healed -healer -health -heaped -heaper -hearer -hearse -hearth -hearts -hearty -heated -heater -heaths -heathy -heaume -heaved -heaven -heaver -heaves -heckle -hectic -hector -heddle -heders -hedged -hedger -hedges -heeded -heeder -heehaw -heeled -heeler -heezed -heezes -hefted -hefter -hegari -hegira -heifer -height -heiled -heinie -heired -heishi -heists -hejira -heliac -helios -helium -helled -heller -hellos -helmed -helmet -helots -helped -helper -helved -helves -hemins -hemmed -hemmer -hemoid -hempen -hempie -henbit -henges -henley -hennas -henrys -hented -hepcat -hepper -heptad -herald -herbal -herbed -herded -herder -herdic -hereat -hereby -herein -hereof -hereon -heresy -hereto -heriot -hermae -hermai -hermit -hernia -heroes -heroic -herons -herpes -hetero -hetman -heuchs -heughs -hewers -hewing -hexade -hexads -hexane -hexers -hexing -hexone -hexose -hexyls -heyday -heydey -hiatal -hiatus -hiccup -hickey -hickie -hidden -hiders -hiding -hieing -hiemal -higgle -higher -highly -highth -hights -hijabs -hijack -hijrah -hijras -hikers -hiking -hilled -hiller -hilloa -hillos -hilted -hinder -hinged -hinger -hinges -hinted -hinter -hipped -hipper -hippos -hirees -hirers -hiring -hirple -hirsel -hirsle -hispid -hissed -hisser -hisses -histed -hither -hitman -hitmen -hitter -hiving -hoagie -hoards -hoarse -hoaxed -hoaxer -hoaxes -hobbed -hobber -hobbit -hobble -hobnob -hoboed -hoboes -hocked -hocker -hockey -hodads -hodden -hoddin -hoeing -hogans -hogged -hogger -hogget -hognut -hogtie -hoicks -hoiden -hoised -hoises -hoists -hokier -hokily -hoking -hokums -holard -holden -holder -holdup -holier -holies -holily -holing -holism -holist -holked -hollas -holler -holloa -holloo -hollos -hollow -holmic -holpen -homage -hombre -homely -homers -homily -homing -hominy -hommos -honans -honcho -hondas -hondle -honers -honest -honied -honing -honked -honker -honors -honour -hooded -hoodoo -hooeys -hoofed -hoofer -hooked -hookey -hookup -hoolie -hooped -hooper -hoopla -hoopoe -hoopoo -hoorah -hooray -hootch -hooted -hooter -hooved -hoover -hooves -hopers -hoping -hopped -hopper -hopple -horahs -horary -horded -hordes -horned -hornet -horrid -horror -horsed -horses -horsey -horste -horsts -hosels -hosers -hoseys -hosier -hosing -hostas -hosted -hostel -hostly -hotbed -hotbox -hotdog -hotels -hotrod -hotted -hotter -hottie -houdah -hounds -houris -hourly -housed -housel -houser -houses -hovels -hovers -howdah -howdie -howffs -howked -howled -howler -howlet -hoyden -hoyles -hryvna -hubbly -hubbub -hubcap -hubris -huckle -huddle -huffed -hugely -hugest -hugged -hugger -huipil -hulked -hulled -huller -hulloa -hulloo -hullos -humane -humans -humate -humble -humbly -humbug -humeri -hummed -hummer -hummus -humors -humour -humped -humper -humphs -humvee -hunger -hungry -hunker -hunkey -hunkie -hunted -hunter -huppah -hurdle -hurled -hurler -hurley -hurrah -hurray -hursts -hurter -hurtle -hushed -hushes -husked -husker -hussar -hustle -hutted -hutzpa -huzzah -huzzas -hyaena -hyalin -hybrid -hybris -hydrae -hydras -hydria -hydric -hydrid -hydros -hyenas -hyenic -hyetal -hymens -hymnal -hymned -hyoids -hypers -hyphae -hyphal -hyphen -hyping -hypnic -hypoed -hysons -hyssop -iambic -iambus -iatric -ibexes -ibices -ibidem -ibises -icebox -icecap -iceman -icemen -ichors -icicle -iciest -icings -ickers -ickier -ickily -icones -iconic -ideals -ideate -idiocy -idioms -idiots -idlers -idlest -idling -idylls -iffier -igging -igloos -ignify -ignite -ignore -iguana -ihrams -ilexes -iliads -illest -illite -illude -illume -imaged -imager -images -imagos -imaret -imaums -imbalm -imbark -imbeds -imbibe -imbody -imbrue -imbued -imbues -imides -imidic -imines -immane -immesh -immies -immune -immure -impact -impair -impala -impale -impark -impart -impawn -impede -impels -impend -imphee -imping -impish -impled -impone -import -impose -impost -improv -impugn -impure -impute -inaner -inanes -inarch -inarms -inborn -inbred -incage -incant -incase -incent -incept -incest -inched -incher -inches -incise -incite -inclip -incogs -income -incony -incubi -incult -incurs -incuse -indaba -indeed -indene -indent -indict -indies -indign -indigo -indite -indium -indole -indols -indoor -indows -indris -induce -induct -indued -indues -indult -inerts -infall -infamy -infant -infare -infect -infers -infest -infill -infirm -inflow -influx -infold -inform -infuse -ingate -ingest -ingles -ingots -ingulf -inhale -inhaul -inhere -inhume -inions -inject -injure -injury -inkers -inkier -inking -inkjet -inkles -inkpot -inlace -inlaid -inland -inlays -inlets -inlier -inmate -inmesh -inmost -innage -innate -inners -inning -inpour -inputs -inroad -inruns -inrush -insane -inseam -insect -insert -insets -inside -insist -insole -insoul -inspan -instal -instar -instep -instil -insult -insure -intact -intake -intend -intent -intern -inters -intima -intime -intine -intomb -intone -intort -intown -intron -intros -intuit -inturn -inulin -inured -inures -inurns -invade -invars -invent -invert -invest -invite -invoke -inwall -inward -inwind -inwove -inwrap -iodate -iodide -iodids -iodine -iodins -iodise -iodism -iodize -iodous -iolite -ionics -ionise -ionium -ionize -ionone -ipecac -irades -irater -ireful -irenic -irides -iridic -irised -irises -iritic -iritis -irking -irokos -ironed -ironer -irones -ironic -irreal -irrupt -isatin -ischia -island -islets -isling -isobar -isogon -isohel -isolog -isomer -isopod -isseis -issued -issuer -issues -isthmi -istles -italic -itched -itches -itemed -iterum -itself -ixodid -ixoras -ixtles -izzard -jabbed -jabber -jabiru -jabots -jacals -jacana -jackal -jacked -jacker -jacket -jading -jadish -jaeger -jagers -jagged -jagger -jagras -jaguar -jailed -jailer -jailor -jalaps -jalops -jalopy -jambed -jambes -jammed -jammer -jangle -jangly -japans -japers -japery -japing -jarful -jargon -jarina -jarrah -jarred -jarvey -jasmin -jasper -jassid -jauked -jaunce -jaunts -jaunty -jauped -jawans -jawing -jaygee -jayvee -jazzbo -jazzed -jazzer -jazzes -jeaned -jebels -jeeing -jeeped -jeered -jeerer -jehads -jejuna -jejune -jelled -jellos -jennet -jerboa -jereed -jerids -jerked -jerrid -jersey -jessed -jesses -jested -jester -jesuit -jetlag -jetons -jetsam -jetsom -jetted -jetton -jetway -jewels -jezail -jibbed -jibber -jibers -jibing -jicama -jigged -jigger -jiggle -jiggly -jigsaw -jihads -jilted -jilter -jiminy -jimmie -jimper -jimply -jingal -jingko -jingle -jingly -jinked -jinker -jinnee -jinnis -jitney -jitter -jivers -jivier -jiving -jnanas -jobbed -jobber -jockey -jockos -jocose -jocund -jogged -jogger -joggle -johnny -joined -joiner -joints -joists -jojoba -jokers -jokier -jokily -joking -jolted -jolter -jorams -jordan -jorums -joseph -joshed -josher -joshes -josses -jostle -jotted -jotter -jouals -jouked -joules -jounce -jouncy -journo -jousts -jovial -jowars -jowing -jowled -joyful -joying -joyous -joypop -jubbah -jubhah -jubile -judder -judged -judger -judges -judoka -jugate -jugful -jugged -juggle -jugula -jugums -juiced -juicer -juices -jujube -juking -juleps -jumbal -jumble -jumbos -jumped -jumper -juncos -jungle -jungly -junior -junked -junker -junket -juntas -juntos -jupons -jurant -jurats -jurels -juried -juries -jurist -jurors -justed -juster -justle -justly -jutted -kababs -kabaka -kabala -kabars -kabaya -kabiki -kabobs -kabuki -kaffir -kafirs -kaftan -kahuna -kaiaks -kainit -kaiser -kakapo -kalams -kalian -kalifs -kaliph -kalium -kalmia -kalong -kalpac -kalpak -kalpas -kamala -kamiks -kamsin -kanaka -kanban -kanjis -kantar -kanzus -kaolin -kaonic -kapoks -kappas -kaputt -karate -karats -karmas -karmic -karoos -kaross -karroo -karsts -kasbah -kashas -kasher -kation -kauris -kavass -kayaks -kayles -kayoed -kayoes -kazoos -kebabs -kebars -kebbie -keblah -kebobs -kecked -keckle -keddah -kedged -kedges -keeked -keeled -keened -keener -keenly -keeper -keeves -kefirs -kegged -kegger -kegler -keleps -kelims -keloid -kelped -kelpie -kelson -kelter -kelvin -kenafs -kendos -kenned -kennel -kentes -kepped -keppen -kerbed -kerfed -kermes -kermis -kerned -kernel -kernes -kerria -kersey -ketene -ketols -ketone -ketose -kettle -kevels -kevils -kewpie -keying -keypad -keypal -keyset -keyway -khadis -khakis -khalif -khaphs -khazen -khedah -khedas -kheths -khoums -kiangs -kiaugh -kibbeh -kibbes -kibbis -kibble -kibeis -kibitz -kiblah -kiblas -kibosh -kicked -kicker -kickup -kidded -kidder -kiddie -kiddos -kidnap -kidney -kidvid -kilims -killed -killer -killie -kilned -kilted -kilter -kiltie -kimchi -kimono -kinara -kinase -kinder -kindle -kindly -kinema -kinged -kingly -kinins -kinked -kiosks -kipped -kippen -kipper -kirned -kirsch -kirtle -kishka -kishke -kismat -kismet -kissed -kisser -kisses -kitbag -kiters -kithed -kithes -kiting -kitsch -kitted -kittel -kitten -kittle -klatch -klaxon -klepht -klepto -klicks -klongs -kloofs -kludge -kludgy -kluged -kluges -klutzy -knacks -knarry -knaurs -knaves -knawel -knawes -kneads -kneels -knells -knifed -knifer -knifes -knight -knives -knobby -knocks -knolls -knolly -knosps -knotty -knouts -knower -knowns -knubby -knurls -knurly -koalas -kobold -koines -kolhoz -kolkoz -kombus -konked -koodoo -kookie -kopeck -kopeks -kopjes -koppas -koppie -korats -kormas -koruna -koruny -kosher -kotows -koumis -koumys -kouroi -kouros -kousso -kowtow -kraals -krafts -kraits -kraken -krater -krauts -kreeps -krewes -krills -krises -kronen -kroner -kronor -kronur -krooni -kroons -krubis -krubut -kuchen -kudzus -kugels -kukris -kulaki -kulaks -kultur -kumiss -kummel -kurgan -kurtas -kussos -kuvasz -kvases -kvells -kvetch -kwacha -kwanza -kyacks -kybosh -kyries -kythed -kythes -laager -labara -labels -labile -labium -labors -labour -labret -labrum -lacers -laches -lacier -lacily -lacing -lacked -lacker -lackey -lactam -lactic -lacuna -lacune -ladder -laddie -ladens -laders -ladies -lading -ladino -ladled -ladler -ladles -ladron -lagans -lagend -lagers -lagged -lagger -lagoon -laguna -lagune -lahars -laical -laichs -laighs -lairds -laired -lakers -lakier -laking -lallan -lalled -lambda -lambed -lamber -lambie -lamedh -lameds -lamely -lament -lamest -lamiae -lamias -lamina -laming -lammed -lampad -lampas -lamped -lanais -lanate -lanced -lancer -lances -lancet -landau -landed -lander -lanely -langue -langur -lanker -lankly -lanner -lanose -lanugo -laogai -lapdog -lapels -lapful -lapins -lapped -lapper -lappet -lapsed -lapser -lapses -lapsus -laptop -larded -larder -lardon -larees -larger -larges -largos -lariat -larine -larked -larker -larrup -larums -larvae -larval -larvas -larynx -lascar -lasers -lashed -lasher -lashes -lasing -lasses -lassie -lassis -lassos -lasted -laster -lastly -lateen -lately -latens -latent -latest -lathed -lather -lathes -lathis -latigo -latina -latino -latish -latkes -latria -latten -latter -lattes -lattin -lauans -lauded -lauder -laughs -launce -launch -laurae -lauras -laurel -lavabo -lavage -lavash -laveer -lavers -laving -lavish -lawful -lawine -lawing -lawman -lawmen -lawyer -laxest -laxity -layers -laying -layins -layman -laymen -layoff -layout -layups -lazars -lazied -lazier -lazies -lazily -lazing -lazuli -leachy -leaded -leaden -leader -leafed -league -leaked -leaker -leally -lealty -leaned -leaner -leanly -leaped -leaper -learns -learnt -leased -leaser -leases -leasts -leaved -leaven -leaver -leaves -lebens -leched -lecher -leches -lechwe -lectin -lector -ledger -ledges -leered -leeway -lefter -legacy -legals -legate -legato -legend -legers -legged -leggin -legion -legist -legits -legman -legmen -legong -legume -lehuas -lekked -lekvar -lemans -lemmas -lemons -lemony -lemurs -lender -length -lenite -lenity -lensed -lenses -lenten -lentic -lentil -lentos -leones -lepers -leptin -lepton -lesion -lessee -lessen -lesser -lesson -lessor -lethal -lethes -letted -letter -letups -leucin -leudes -leukon -levant -leveed -levees -levels -levers -levied -levier -levies -levins -levity -lewder -lewdly -lexeme -lexica -lezzes -lezzie -liable -liaise -lianas -lianes -liangs -liards -libber -libels -libers -libido -liblab -librae -libras -lichee -lichen -liches -lichis -lichts -licked -licker -lictor -lidars -lidded -lieder -liefer -liefly -lieges -lienal -lierne -liever -lifers -lifted -lifter -ligand -ligans -ligase -ligate -ligers -lights -lignan -lignin -ligula -ligule -ligure -likely -likens -likers -likest -liking -likuta -lilacs -lilied -lilies -lilted -limans -limbas -limbed -limber -limbic -limbos -limbus -limens -limeys -limier -limina -liming -limits -limmer -limned -limner -limnic -limpas -limped -limper -limpet -limpid -limply -limpsy -limuli -linacs -linage -linden -lineal -linear -linens -lineny -liners -lineup -lingam -lingas -linger -lingua -linier -lining -linins -linked -linker -linkup -linnet -linsey -linted -lintel -linter -lintol -linums -lipase -lipide -lipids -lipins -lipoid -lipoma -lipped -lippen -lipper -liquid -liquor -liroth -lisles -lisped -lisper -lissom -listed -listee -listel -listen -lister -litany -litchi -liters -lither -lithia -lithic -lithos -litmus -litres -litten -litter -little -lively -livens -livers -livery -livest -livier -living -livres -livyer -lizard -llamas -llanos -loaded -loader -loafed -loafer -loamed -loaned -loaner -loathe -loaves -lobate -lobbed -lobber -lobule -locale -locals -locate -lochan -lochia -locked -locker -locket -lockup -locoed -locoes -locule -loculi -locums -locust -lodens -lodged -lodger -lodges -lofted -lofter -logans -logged -logger -loggia -loggie -logics -logier -logily -logins -logion -logjam -logons -logway -loided -loiter -lolled -loller -lollop -lomein -loment -lonely -loners -longan -longed -longer -longes -longly -looeys -loofah -loofas -looies -looing -looked -looker -lookup -loomed -looped -looper -loosed -loosen -looser -looses -looted -looter -lopers -loping -lopped -lopper -loquat -lorans -lorded -lordly -loreal -lorica -lories -losels -losers -losing -losses -lotahs -lotion -lotted -lotter -lottes -lottos -louche -louden -louder -loudly -loughs -louies -loumas -lounge -loungy -louped -loupen -loupes -loured -loused -louses -louted -louver -louvre -lovage -lovats -lovely -lovers -loving -lowboy -lowers -lowery -lowest -lowing -lowish -loxing -lubber -lubing -lubric -lucent -lucern -lucite -lucked -luckie -lucres -luetic -luffas -luffed -lugers -lugged -lugger -luggie -luging -lulled -luller -lumbar -lumber -lumens -lumina -lummox -lumped -lumpen -lumper -lunacy -lunars -lunate -lunets -lungan -lunged -lungee -lunger -lunges -lungis -lungyi -lunier -lunies -lunker -lunted -lunula -lunule -lupine -lupins -lupous -lurdan -lurers -luring -lurked -lurker -lushed -lusher -lushes -lushly -lusted -luster -lustra -lustre -luteal -lutein -luteum -luting -lutist -lutzes -luxate -luxury -lyases -lycees -lyceum -lychee -lyches -lycras -lyings -lymphs -lynxes -lyrate -lyrics -lyrism -lyrist -lysate -lysine -lysing -lysins -lyssas -lyttae -lyttas -macaco -macaws -macers -maches -machos -macing -mackle -macled -macles -macons -macron -macros -macula -macule -madame -madams -madcap -madded -madden -madder -madras -madres -madtom -maduro -maenad -maffia -mafias -maftir -maggot -magian -magics -magilp -maglev -magmas -magnet -magnum -magots -magpie -maguey -mahoes -mahout -mahzor -maiden -maigre -maihem -mailed -mailer -mailes -maills -maimed -maimer -mainly -maists -maizes -majors -makars -makers -makeup -making -makuta -malady -malars -malate -malfed -malgre -malice -malign -maline -malkin -malled -mallee -mallei -mallet -mallow -maloti -malted -maltha -maltol -mambas -mambos -mameys -mamies -mamluk -mammae -mammal -mammas -mammee -mammer -mammet -mammey -mammie -mammon -mamzer -manage -manana -manats -manche -manege -manful -mangas -mangel -manger -manges -mangey -mangle -mangos -maniac -manias -manics -manila -manioc -manito -manitu -mannan -mannas -manned -manner -manors -manque -manses -mantas -mantel -mantes -mantic -mantid -mantis -mantle -mantra -mantua -manual -manure -maples -mapped -mapper -maquis -maraca -maraud -marble -marbly -marcel -margay -marges -margin -marina -marine -marish -markas -marked -marker -market -markka -markup -marled -marlin -marmot -maroon -marque -marram -marred -marrer -marron -marrow -marses -marshy -marted -marten -martin -martyr -marvel -masala -mascon -mascot -masers -mashed -masher -mashes -mashie -masjid -masked -maskeg -masker -masons -masque -massif -masted -master -mastic -mastix -maters -mateys -matier -mating -matins -matres -matrix -matron -matsah -matted -matter -mattes -mattin -mature -matzah -matzas -matzoh -matzos -matzot -mauger -maugre -mauled -mauler -maumet -maunds -maundy -mauves -mavens -mavies -mavins -mawing -maxima -maxims -maxing -maxixe -maybes -mayday -mayest -mayfly -mayhap -mayhem -maying -mayors -maypop -mayvin -mazard -mazers -mazier -mazily -mazing -mazuma -mbiras -meadow -meager -meagre -mealie -meaner -meanie -meanly -measle -measly -meatal -meated -meatus -meccas -medaka -medals -meddle -medfly -mediad -mediae -medial -median -medias -medick -medico -medics -medina -medium -medius -medlar -medley -medusa -meeker -meekly -meeter -meetly -megara -megilp -megohm -megrim -mehndi -meikle -meinie -melded -melder -melees -melena -melled -mellow -melody -meloid -melons -melted -melter -melton -member -memoir -memory -menace -menads -menage -mended -mender -menhir -menial -meninx -mensae -mensal -mensas -mensch -mensed -menses -mental -mentee -mentor -mentum -menudo -meoued -meowed -mercer -merces -merdes -merely -merest -merged -mergee -merger -merges -merino -merits -merles -merlin -merlon -merlot -merman -mermen -mescal -meshed -meshes -mesial -mesian -mesnes -mesons -messan -messed -messes -mestee -metage -metals -metate -meteor -metepa -meters -method -methyl -metier -meting -metols -metope -metred -metres -metric -metros -mettle -metump -mewing -mewled -mewler -mezcal -mezuza -mezzos -miaous -miaows -miasma -miasms -miauls -micell -miched -miches -mickey -mickle -micron -micros -midair -midcap -midday -midden -middle -midges -midget -midgut -midleg -midrib -midsts -midway -miffed -miggle -mights -mighty -mignon -mihrab -mikado -miking -mikron -mikvah -mikveh -mikvos -mikvot -miladi -milady -milage -milded -milden -milder -mildew -mildly -milers -milieu -milium -milked -milker -milled -miller -milles -millet -milneb -milord -milpas -milted -milter -mimbar -mimeos -mimers -mimics -miming -mimosa -minced -minder -miners -mingle -minify -minima -minims -mining -minion -minish -minium -minkes -minnow -minors -minted -minter -minuet -minute -minxes -minyan -mioses -miosis -miotic -mirage -mirier -miring -mirins -mirker -mirror -mirths -mirzas -misact -misadd -misaim -misate -miscue -miscut -misdid -miseat -misers -misery -misfed -misfit -mishap -miskal -mislay -misled -mislie -mislit -mismet -mispen -missal -missay -missed -missel -misses -misset -missis -missus -misted -mister -misuse -miters -mither -mitier -mitral -mitred -mitres -mitten -mixers -mixing -mixups -mizens -mizuna -mizzen -mizzle -mizzly -moaned -moaner -moated -mobbed -mobber -mobcap -mobile -mobled -mochas -mocked -mocker -mockup -modals -models -modems -modern -modest -modica -modify -modish -module -moduli -modulo -mogged -moggie -moghul -moguls -mohair -mohawk -mohels -mohurs -moiety -moiled -moiler -moirai -moires -mojoes -molars -molded -molder -molies -moline -mollah -mollie -moloch -molted -molten -molter -moment -mommas -momser -momzer -monads -mondes -mondos -moneys -monger -mongoe -mongol -mongos -mongst -monied -monies -monish -monism -monist -monkey -monody -montes -months -mooing -moolah -moolas -mooley -mooned -mooner -moored -mooted -mooter -mopeds -mopers -mopery -mopier -moping -mopish -mopoke -mopped -mopper -moppet -morale -morals -morays -morbid -moreen -morels -morgan -morgen -morgue -morion -morose -morpho -morphs -morris -morros -morrow -morsel -mortal -mortar -morula -mosaic -moseys -moshav -moshed -mosher -moshes -mosque -mossed -mosser -mosses -mostly -motels -motets -mother -motifs -motile -motion -motive -motley -motmot -motors -mottes -mottle -mottos -moujik -moulds -mouldy -moulin -moults -mounds -mounts -mourns -moused -mouser -mouses -mousey -mousse -mouths -mouthy -mouton -movers -movies -moving -mowers -mowing -moxies -muches -muchly -mucins -mucked -mucker -muckle -mucluc -mucoid -mucors -mucosa -mucose -mucous -mudbug -mudcap -mudcat -mudded -mudder -muddle -muddly -mudhen -mudras -muesli -muffed -muffin -muffle -muftis -mugful -muggar -mugged -muggee -mugger -muggur -mughal -mujiks -mukluk -muktuk -mulcts -muleta -muleys -muling -mulish -mullah -mullas -mulled -mullen -muller -mullet -mulley -mumble -mumbly -mummed -mummer -mumped -mumper -mungos -muntin -muonic -murals -murder -murein -murids -murine -muring -murker -murkly -murmur -murphy -murras -murres -murrey -murrha -muscae -muscat -muscid -muscle -muscly -musers -museum -mushed -musher -mushes -musick -musics -musing -musjid -muskeg -musket -muskie -muskit -muskox -muslin -mussed -mussel -musses -musted -mustee -muster -musths -mutant -mutase -mutate -mutely -mutest -mutine -muting -mutiny -mutism -mutons -mutter -mutton -mutual -mutuel -mutule -muumuu -muzhik -muzjik -muzzle -myases -myasis -mycele -myelin -mylars -mynahs -myomas -myopes -myopia -myopic -myoses -myosin -myosis -myotic -myriad -myrica -myrrhs -myrtle -myself -mysids -mysost -mystic -mythic -mythoi -mythos -myxoid -myxoma -nabbed -nabber -nabobs -nachas -naches -nachos -nacred -nacres -nadirs -naevus -naffed -nagana -nagged -nagger -naiads -nailed -nailer -nairas -nairus -naiver -naives -nakfas -naleds -namely -namers -naming -nances -nandin -nanism -nankin -nannie -napalm -napery -napkin -nappas -napped -napper -nappes -nappie -narcos -narial -narine -narked -narrow -narwal -nasals -nasial -nasion -nastic -natant -nation -native -natron -natter -nature -naught -nausea -nautch -navaid -navars -navels -navies -nawabs -naysay -nazify -nearby -neared -nearer -nearly -neaten -neater -neatly -nebula -nebule -nebuly -necked -necker -nectar -needed -needer -needle -negate -neighs -nekton -nellie -nelson -neocon -neoned -nepeta -nephew -nereid -nereis -neroli -nerols -nerved -nerves -nesses -nested -nester -nestle -nestor -nether -netops -netted -netter -nettle -nettly -neumes -neumic -neural -neuron -neuter -nevoid -newbie -newels -newest -newies -newish -newsie -newton -niacin -nibbed -nibble -nicads -nicely -nicest -nicety -niched -niches -nicked -nickel -nicker -nickle -nicols -nidate -nidget -nidify -niding -nieces -nielli -niello -nieves -niffer -niggle -niggly -nighed -nigher -nights -nighty -nihils -nilgai -nilgau -nilled -nimble -nimbly -nimbus -nimmed -nimrod -ninety -ninjas -ninons -ninths -niobic -nipped -nipper -niseis -niters -nitery -nitons -nitres -nitric -nitrid -nitril -nitros -nitwit -nixies -nixing -nizams -nobble -nobler -nobles -nobody -nocent -nocked -nodded -nodder -noddle -nodose -nodous -nodule -noesis -noetic -nogged -noggin -noised -noises -nomads -nomina -nomism -nonage -nonart -nonces -noncom -nonego -nonets -nonfan -nonfat -nongay -nonman -nonmen -nonpar -nontax -nonuse -nonwar -nonyls -noodge -noodle -noogie -nookie -noosed -nooser -nooses -nopals -nordic -norias -norite -normal -normed -norths -noshed -nosher -noshes -nosier -nosily -nosing -nostoc -notary -notate -noters -nother -notice -notify -noting -notion -nougat -nought -nounal -nouses -novels -novena -novice -noways -nowise -noyade -nozzle -nuance -nubbin -nubble -nubbly -nubias -nubile -nubuck -nuchae -nuchal -nuclei -nudely -nudest -nudged -nudger -nudges -nudies -nudism -nudist -nudity -nudnik -nugget -nuking -nullah -nulled -numbat -numbed -number -numbly -numina -nuncio -nuncle -nurled -nursed -nurser -nurses -nutant -nutate -nutlet -nutmeg -nutria -nuzzle -nyalas -oafish -oakier -oakums -oaring -oaters -obeahs -obelia -obelus -obento -obeyed -obeyer -obiism -object -objets -oblast -oblate -oblige -oblong -oboist -oboles -obolus -obsess -obtain -obtect -obtest -obtund -obtuse -obvert -occult -occupy -occurs -oceans -ocelli -ocelot -ochers -ochery -ochone -ochrea -ochred -ochres -ocicat -ockers -ocreae -octads -octane -octans -octant -octave -octavo -octets -octopi -octroi -octyls -ocular -oculus -oddest -oddish -oddity -odeons -odeums -odious -odists -odiums -odored -odours -odyles -oedema -oeuvre -offals -offcut -offend -offers -office -offing -offish -offkey -offset -oftest -ogdoad -oghams -ogival -ogives -oglers -ogling -ogress -ogrish -ogrism -ohmage -oidium -oilcan -oilcup -oilers -oilier -oilily -oiling -oilman -oilmen -oilway -oinked -okapis -okayed -oldest -oldies -oldish -oleate -olefin -oleine -oleins -oleums -olingo -olives -omasum -ombers -ombres -omegas -omelet -omened -omenta -onager -onagri -onions -oniony -onlays -online -onload -onrush -onsets -onside -onuses -onward -onyxes -oocyst -oocyte -oodles -oogamy -oogeny -oohing -oolite -oolith -oology -oolong -oomiac -oomiak -oompah -oomphs -oorali -ootids -oozier -oozily -oozing -opaque -opened -opener -openly -operas -operon -ophite -opiate -opined -opines -opioid -opiums -oppose -oppugn -opsins -optics -optima -optime -opting -option -opuses -orache -oracle -orally -orange -orangs -orangy -orated -orates -orator -orbier -orbing -orbits -orcein -orchid -orchil -orchis -orcins -ordain -ordeal -orders -ordure -oreads -oreide -orfray -organs -orgone -oribis -oriels -orient -origan -origin -oriole -orisha -orison -orlons -orlops -ormers -ormolu -ornate -ornery -oroide -orphan -orphic -orpine -orpins -orrery -orrice -oryxes -oscine -oscula -oscule -osetra -osiers -osmics -osmium -osmole -osmols -osmose -osmous -osmund -osprey -ossein -ossify -osteal -ostium -ostler -ostomy -otalgy -others -otiose -otitic -otitis -ottars -ottava -otters -ouched -ouches -oughts -ounces -ouphes -ourang -ourari -ourebi -ousels -ousted -ouster -outact -outadd -outage -outask -outate -outbeg -outbid -outbox -outbuy -outbye -outcry -outdid -outeat -outers -outfit -outfly -outfox -outgas -outgun -outhit -outing -outjut -outlaw -outlay -outled -outlet -outlie -outman -output -outran -outrig -outrow -outrun -outsat -outsaw -outsay -outsee -outset -outsin -outsit -outvie -outwar -outwit -ouzels -ovally -overdo -overed -overly -ovibos -ovines -ovisac -ovoids -ovolos -ovonic -ovular -ovules -owlets -owlish -owners -owning -oxalic -oxalis -oxbows -oxcart -oxeyes -oxford -oxides -oxidic -oximes -oxlike -oxlips -oxtail -oxters -oxygen -oyezes -oyster -ozalid -ozones -ozonic -pablum -pacers -pachas -pacier -pacify -pacing -packed -packer -packet -packly -padauk -padded -padder -paddle -padles -padnag -padouk -padres -paeans -paella -paeons -paesan -pagans -pagers -paging -pagoda -pagods -paiked -painch -pained -paints -painty -paired -paisan -paisas -pajama -pakeha -pakora -palace -palais -palapa -palate -paleae -paleal -palely -palest -palets -palier -paling -palish -palled -pallet -pallia -pallid -pallor -palmar -palmed -palmer -palpal -palped -palpus -palter -paltry -pampas -pamper -panada -panama -pandas -pander -pandit -panels -panfry -panful -pangas -panged -pangen -panics -panier -panini -panino -panned -panner -pannes -panted -pantie -pantos -pantry -panzer -papacy -papain -papaws -papaya -papers -papery -papism -papist -pappus -papula -papule -papyri -parade -paramo -parang -paraph -parcel -pardah -pardee -pardie -pardon -parent -pareos -parers -pareus -pareve -parged -parges -parget -pargos -pariah -parian -paries -paring -parish -parity -parkas -parked -parker -parlay -parled -parles -parley -parlor -parody -parole -parols -parous -parral -parred -parrel -parrot -parsec -parsed -parser -parses -parson -partan -parted -partly -parton -parura -parure -parvis -parvos -pascal -paseos -pashas -pashed -pashes -pastas -pasted -pastel -paster -pastes -pastie -pastil -pastis -pastor -pastry -pataca -patchy -patens -patent -paters -pathos -patina -patine -patins -patios -patois -patrol -patron -patted -pattee -patten -patter -pattie -patzer -paulin -paunch -pauper -pausal -paused -pauser -pauses -pavane -pavans -paveed -pavers -paving -pavins -pavior -pavise -pawers -pawing -pawned -pawnee -pawner -pawnor -pawpaw -paxwax -payday -payees -payers -paying -paynim -payoff -payola -payors -payout -pazazz -peaced -peaces -peachy -peages -peahen -peaked -pealed -peanut -pearls -pearly -peasen -peases -peavey -pebble -pebbly -pecans -pechan -peched -pecked -pecten -pectic -pectin -pedalo -pedals -pedant -pedate -peddle -pedlar -pedler -pedros -peeing -peeked -peeled -peeler -peened -peered -peerie -pegged -peined -peised -peises -pekans -pekins -pekoes -pelage -pelite -pellet -pelmet -pelota -pelted -pelter -peltry -pelves -pelvic -pelvis -penang -pencel -pencil -pended -pengos -penman -penmen -pennae -penned -penner -pennon -pensee -pensil -pentad -pentyl -penult -penury -peones -people -pepino -peplos -peplum -peplus -pepped -pepper -pepsin -peptic -peptid -perdie -perdue -perdus -pereia -pereon -perils -period -perish -periti -perked -permed -permit -pernio -pernod -peroxy -perron -perses -person -perter -pertly -peruke -peruse -pesade -peseta -pesewa -pester -pestle -pestos -petals -petard -peters -petite -petnap -petrel -petrol -petsai -petted -petter -pettle -pewees -pewits -pewter -phages -pharos -phased -phases -phasic -phasis -phatic -phenix -phenol -phenom -phenyl -phials -phizes -phlegm -phloem -phobia -phobic -phoebe -phonal -phoned -phones -phoney -phonic -phonon -phonos -phooey -photic -photog -photon -photos -phrase -phreak -phylae -phylar -phylic -phyllo -phylon -phylum -physed -physes -physic -physis -phytin -phytol -phyton -piaffe -pianic -pianos -piazza -piazze -pibals -picara -picaro -pickax -picked -picker -picket -pickle -pickup -picnic -picots -picric -piculs -piddle -piddly -pidgin -pieced -piecer -pieces -pieing -pierce -pietas -piffle -pigeon -pigged -piggie -piggin -piglet -pignus -pignut -pigout -pigpen -pigsty -pikake -pikers -piking -pilaff -pilafs -pilaus -pilaws -pileum -pileup -pileus -pilfer -piling -pillar -pilled -pillow -pilose -pilots -pilous -pilule -pimped -pimple -pimply -pinang -pinata -pincer -pinder -pineal -pinene -pinery -pineta -pinged -pinger -pingos -pinier -pining -pinion -pinite -pinked -pinken -pinker -pinkey -pinkie -pinkly -pinkos -pinnae -pinnal -pinnas -pinned -pinner -pinole -pinons -pinots -pintas -pintle -pintos -pinups -pinyin -pinyon -piolet -pionic -pipage -pipals -pipers -pipets -pipier -piping -pipits -pipkin -pipped -pippin -piqued -piques -piquet -piracy -pirana -pirate -piraya -pirogi -piscos -pistil -pistol -piston -pistou -pitaya -pitchy -pithed -pitied -pitier -pities -pitman -pitmen -pitons -pitsaw -pittas -pitted -pivots -pixels -pixies -pizazz -pizzas -pizzaz -pizzle -placed -placer -places -placet -placid -placks -plagal -plages -plague -plaguy -plaice -plaids -plains -plaint -plaits -planar -planch -planed -planer -planes -planet -planks -plants -plaque -plashy -plasma -plasms -platan -plated -platen -plater -plates -platys -playas -played -player -plazas -pleach -pleads -please -pleats -plebes -pledge -pleiad -plench -plenty -plenum -pleons -pleura -plexal -plexes -plexor -plexus -pliant -plicae -plical -pliers -plight -plinks -plinth -plisky -plisse -ploidy -plonks -plotty -plough -plover -plowed -plower -ployed -plucks -plucky -plumbs -plumed -plumes -plummy -plumps -plunge -plunks -plunky -plural -pluses -plushy -plutei -pluton -plyers -plying -pneuma -poachy -poboys -pocked -pocket -podded -podite -podium -podsol -podzol -poetic -poetry -pogeys -pogies -pogrom -poilus -poinds -pointe -points -pointy -poised -poiser -poises -poisha -poison -pokers -pokeys -pokier -pokies -pokily -poking -polars -polder -poleax -poleis -polers -poleyn -police -policy -polies -poling -polios -polish -polite -polity -polkas -polled -pollee -pollen -poller -pollex -polyol -polypi -polyps -pomace -pomade -pomelo -pommee -pommel -pommie -pompom -pompon -ponced -ponces -poncho -ponded -ponder -ponent -ponged -pongee -pongid -ponied -ponies -pontes -pontil -ponton -popery -popgun -popish -poplar -poplin -poppas -popped -popper -poppet -popple -popsie -poring -porism -porked -porker -pornos -porose -porous -portal -ported -porter -portly -posada -posers -poseur -posher -poshly -posies -posing -posits -posole -posses -posset -possum -postal -posted -poster -postie -postin -postop -potage -potash -potato -potboy -poteen -potent -potful -pother -pothos -potion -potman -potmen -potpie -potsie -potted -potter -pottle -pottos -potzer -pouchy -poufed -pouffe -pouffs -pouffy -poults -pounce -pounds -poured -pourer -pouted -pouter -powder -powers -powter -powwow -poxier -poxing -poyous -pozole -praams -prahus -praise -prajna -prance -prangs -pranks -prases -prated -prater -prates -prawns -praxes -praxis -prayed -prayer -preach -preact -preamp -prearm -prebid -prebuy -precis -precut -predry -preens -prefab -prefer -prefix -prelaw -prelim -preman -premed -premen -premie -premix -preops -prepay -preppy -preset -presto -prests -pretax -pretor -pretty -prevue -prewar -prexes -preyed -preyer -prezes -priapi -priced -pricer -prices -pricey -prided -prides -priers -priest -prills -primal -primas -primed -primer -primes -primly -primos -primps -primus -prince -prinks -prints -prions -priors -priory -prised -prises -prisms -prison -prissy -privet -prized -prizer -prizes -probed -prober -probes -probit -proems -profit -progun -projet -prolan -proleg -proles -prolix -prolog -promos -prompt -prongs -pronto -proofs -propel -proper -propyl -prosed -proser -proses -prosit -prosos -protea -protei -proton -protyl -proved -proven -prover -proves -prowar -prower -prowls -prudes -pruned -pruner -prunes -prunus -prutah -prutot -pryers -prying -psalms -pseudo -pseuds -pshaws -psocid -psyche -psycho -psychs -psylla -psyops -psywar -pterin -ptisan -ptooey -ptoses -ptosis -ptotic -public -pucker -puddle -puddly -pueblo -puffed -puffer -puffin -pugged -puggry -pugree -puisne -pujahs -puking -pulers -puling -pulled -puller -pullet -pulley -pullup -pulpal -pulped -pulper -pulpit -pulque -pulsar -pulsed -pulser -pulses -pumelo -pumice -pummel -pumped -pumper -punchy -pundit -pungle -punier -punily -punish -punjis -punkah -punkas -punker -punkey -punkie -punkin -punned -punner -punnet -punted -punter -puntos -pupate -pupils -pupped -puppet -purana -purdah -purdas -pureed -purees -purely -purest -purfle -purged -purger -purges -purify -purine -purins -purism -purist -purity -purled -purlin -purple -purply -purred -pursed -purser -purses -pursue -purvey -pushed -pushes -pushup -pusley -putlog -putoff -putons -putout -putrid -putsch -putted -puttee -putter -puttie -putzed -putzes -puzzle -pyemia -pyemic -pyjama -pyknic -pylons -pylori -pyoses -pyosis -pyrans -pyrene -pyrite -pyrola -pyrone -pyrope -pyrrol -python -pyuria -pyxies -qabala -qanats -qindar -qintar -qiviut -quacks -quacky -quaere -quaffs -quagga -quaggy -quahog -quaich -quaigh -quails -quaint -quaked -quaker -quakes -qualia -qualms -qualmy -quango -quanta -quants -quarks -quarry -quarte -quarto -quarts -quartz -quasar -quatre -quaver -qubits -qubyte -queans -queasy -queazy -queens -queers -quelea -quells -quench -querns -quests -queued -queuer -queues -quezal -quiche -quicks -quiets -quiffs -quills -quilts -quince -quinic -quinin -quinoa -quinol -quinsy -quinta -quinte -quints -quippu -quippy -quipus -quired -quires -quirks -quirky -quirts -quitch -quiver -quohog -quoins -quoits -quokka -quolls -quorum -quotas -quoted -quoter -quotes -quotha -qurush -qwerty -rabato -rabats -rabbet -rabbin -rabbis -rabbit -rabble -rabies -raceme -racers -rachet -rachis -racier -racily -racing -racked -racker -racket -rackle -racons -racoon -radars -radded -raddle -radial -radian -radios -radish -radium -radius -radome -radons -radula -raffia -raffle -rafted -rafter -ragbag -ragees -ragged -raggee -raggle -raging -raglan -ragman -ragmen -ragout -ragtag -ragtop -raided -raider -railed -railer -rained -raised -raiser -raises -raisin -raitas -rajahs -rakees -rakers -raking -rakish -rallye -ralphs -ramada -ramate -rambla -ramble -ramees -ramets -ramies -ramify -ramjet -rammed -rammer -ramona -ramose -ramous -ramped -ramrod -ramson -ramtil -rances -rancho -rancid -rancor -randan -random -ranees -ranged -ranger -ranges -ranids -ranked -ranker -rankle -rankly -ransom -ranted -ranter -ranula -rarefy -rarely -rarest -rarify -raring -rarity -rascal -rasers -rasher -rashes -rashly -rasing -rasped -rasper -rassle -raster -rasure -ratals -ratans -ratany -ratbag -ratels -raters -rather -ratify -ratine -rating -ration -ratios -ratite -ratlin -ratoon -rattan -ratted -ratten -ratter -rattle -rattly -ratton -raunch -ravage -ravels -ravens -ravers -ravine -raving -ravins -ravish -rawest -rawins -rawish -raxing -rayahs -raying -rayons -razeed -razees -razers -razing -razors -razzed -razzes -reacts -readds -reader -reagin -realer -reales -realia -really -realms -realty -reamed -reamer -reaped -reaper -reared -rearer -rearms -reason -reatas -reaved -reaver -reaves -reavow -rebait -rebars -rebate -rebato -rebbes -rebeck -rebecs -rebels -rebids -rebill -rebind -rebody -reboil -rebook -reboot -rebops -rebore -reborn -rebozo -rebred -rebuff -rebuke -rebury -rebuts -rebuys -recall -recane -recant -recaps -recast -recces -recede -recent -recept -recess -rechew -recipe -recite -recits -recked -reckon -reclad -recoal -recoat -recode -recoil -recoin -recomb -recons -recook -recopy -record -recork -recoup -rectal -rector -rectos -recurs -recuse -recuts -redact -redans -redate -redbay -redbud -redbug -redcap -redded -redden -redder -reddle -redear -redeem -redefy -redeny -redeye -redfin -rediae -redial -redias -reding -redips -redipt -redleg -redock -redoes -redone -redons -redout -redowa -redraw -redrew -redtop -redubs -reduce -redyed -redyes -reearn -reecho -reechy -reeded -reedit -reefed -reeled -reeler -reemit -reests -reeved -reeves -reface -refall -refect -refeed -refeel -refell -refels -refelt -refers -reffed -refile -refill -refilm -refind -refine -refire -refits -reflag -reflet -reflew -reflex -reflow -reflux -refold -reform -refuel -refuge -refund -refuse -refute -regain -regale -regard -regave -regear -regent -reggae -regild -regilt -regime -regina -region -regius -regive -reglet -reglow -reglue -regnal -regnum -regret -regrew -regrow -reguli -rehabs -rehang -rehash -rehear -reheat -reheel -rehems -rehire -rehung -reigns -reined -reinks -reived -reiver -reives -reject -rejigs -rejoin -rekeys -reknit -reknot -relace -relaid -reland -relate -relays -relend -relent -relets -releve -relics -relict -relied -relief -relier -relies -reline -relink -relish -relist -relive -reload -reloan -relock -relook -reluct -relume -remade -remail -remain -remake -remand -remans -remaps -remark -remate -remedy -remeet -remelt -remend -remind -remint -remise -remiss -remits -remixt -remold -remora -remote -remove -remuda -renail -rename -rended -render -renege -renest -renews -renigs -renins -rennet -rennin -renown -rental -rented -renter -rentes -renvoi -reoils -reopen -repack -repaid -repair -repand -repark -repass -repast -repave -repays -repeal -repeat -repegs -repels -repent -reperk -repine -repins -replan -replay -repled -replot -replow -repoll -report -repose -repots -repour -repped -repros -repugn -repump -repute -requin -rerack -reread -rerent -rerigs -rerise -reroll -reroof -rerose -reruns -resaid -resail -resale -resawn -resaws -resays -rescue -reseal -reseat -reseau -resect -reseda -reseed -reseek -reseen -resees -resell -resend -resent -resets -resewn -resews -reshes -reship -reshod -reshoe -reshot -reshow -reside -resids -resift -resign -resile -resins -resiny -resist -resite -resits -resize -resoak -resods -resold -resole -resorb -resort -resown -resows -respot -rested -rester -result -resume -retack -retags -retail -retain -retake -retape -reteam -retear -retell -retems -retene -retest -retial -retied -reties -retile -retime -retina -retine -retint -retire -retold -retook -retool -retore -retorn -retort -retral -retrim -retros -retted -retune -return -retuse -retype -reused -reuses -revamp -reveal -revels -reverb -revere -revers -revert -revery -revest -revets -review -revile -revise -revive -revoke -revolt -revote -revues -revved -rewake -reward -rewarm -rewash -rewear -reweds -reweld -rewets -rewind -rewins -rewire -rewoke -reword -rewore -rework -reworn -rewove -rewrap -rexine -rezero -rezone -rhaphe -rhebok -rhemes -rhesus -rhetor -rheums -rheumy -rhinal -rhinos -rhodic -rhombi -rhombs -rhotic -rhumba -rhumbs -rhuses -rhymed -rhymer -rhymes -rhythm -rhyton -rialto -riatas -ribald -riband -ribbed -ribber -ribbon -ribier -riblet -ribose -ricers -richen -richer -riches -richly -ricing -ricins -ricked -rickey -ricrac -rictal -rictus -ridded -ridden -ridder -riddle -rident -riders -ridged -ridgel -ridges -ridgil -riding -ridley -riever -rifely -rifest -riffed -riffle -rifled -rifler -rifles -riflip -rifted -rigged -rigger -righto -rights -righty -rigors -rigour -riling -rilled -rilles -rillet -rimers -rimier -rimose -rimous -rimple -rinded -ringed -ringer -rinsed -rinser -rinses -riojas -rioted -rioter -ripely -ripens -ripest -riping -ripoff -ripost -ripped -ripper -ripple -ripply -riprap -ripsaw -risers -rishis -rising -risked -risker -risque -ristra -ritard -ritter -ritual -ritzes -rivage -rivals -rivers -rivets -riving -riyals -roadeo -roadie -roamed -roamer -roared -roarer -roasts -robalo -roband -robbed -robber -robbin -robing -robins -robles -robots -robust -rochet -rocked -rocker -rocket -rococo -rodded -rodent -rodeos -rodman -rodmen -rogers -rogued -rogues -roiled -rolfed -rolfer -rolled -roller -romaji -romano -romans -romeos -rondel -rondos -ronion -ronnel -ronyon -roofed -roofer -roofie -rooked -rookie -roomed -roomer -roomie -roosed -rooser -rooses -roosts -rooted -rooter -rootle -ropers -ropery -ropier -ropily -roping -roques -roquet -rosary -roscoe -rosery -rosets -roshis -rosier -rosily -rosing -rosins -rosiny -roster -rostra -rotary -rotate -rotche -rotgut -rotors -rotund -rouble -rouche -rouens -rouged -rouges -roughs -roughy -rounds -rouped -roupet -roused -rouser -rouses -rousts -routed -router -routes -rouths -rovers -roving -rowans -rowels -rowens -rowers -rowing -rowths -royals -rozzer -ruanas -rubace -rubati -rubato -rubbed -rubber -rubble -rubbly -rubels -rubied -rubier -rubies -rubigo -rubles -ruboff -rubout -rubric -ruched -ruches -rucked -ruckle -ruckus -rudder -ruddle -rudely -rudery -rudest -rueful -ruffed -ruffes -ruffle -ruffly -rufous -rugate -rugged -rugger -rugola -rugosa -rugose -rugous -ruined -ruiner -rulers -rulier -ruling -rumaki -rumbas -rumble -rumbly -rumens -rumina -rummer -rumors -rumour -rumple -rumply -rumpus -rundle -runkle -runlet -runnel -runner -runoff -runout -runway -rupees -rupiah -rurban -rushed -rushee -rusher -rushes -rusine -russet -rusted -rustic -rustle -rutile -rutins -rutted -ryking -ryokan -sabals -sabbat -sabbed -sabers -sabine -sabins -sabirs -sables -sabots -sabras -sabred -sabres -sacbut -sachem -sachet -sacked -sacker -sacque -sacral -sacred -sacrum -sadden -sadder -saddhu -saddle -sadhes -sadhus -safari -safely -safest -safety -safrol -sagbut -sagely -sagest -saggar -sagged -sagger -sagier -sahibs -saices -saigas -sailed -sailer -sailor -saimin -sained -saints -saithe -saiyid -sajous -sakers -salaam -salads -salals -salami -salary -saleps -salify -salina -saline -saliva -sallet -sallow -salmis -salmon -salols -salons -saloon -saloop -salpae -salpas -salpid -salsas -salted -salter -saltie -saluki -salute -salved -salver -salves -salvia -salvor -salvos -samara -sambal -sambar -sambas -sambos -sambur -samech -samekh -sameks -samiel -samite -samlet -samosa -sampan -sample -samshu -sancta -sandal -sanded -sander -sandhi -sanely -sanest -sangar -sangas -sanger -sanghs -sanies -saning -sanity -sanjak -sannop -sannup -sansar -sansei -santir -santol -santos -santur -sapors -sapota -sapote -sapour -sapped -sapper -sarans -sarape -sardar -sarees -sarges -sargos -sarins -sarode -sarods -sarong -sarsar -sarsen -sartor -sashay -sashed -sashes -sasins -sassed -sasses -satang -satara -satays -sateen -sating -satins -satiny -satire -satori -satrap -satyrs -sauced -saucer -sauces -sauchs -sauger -saughs -saughy -saults -saunas -saurel -sauted -sautes -savage -savant -savate -savers -savine -saving -savins -savior -savors -savory -savour -savoys -sawers -sawfly -sawing -sawlog -sawney -sawyer -saxony -sayeds -sayers -sayest -sayids -saying -sayyid -scabby -scalar -scalds -scaled -scaler -scales -scalls -scalps -scampi -scamps -scants -scanty -scaped -scapes -scarab -scarce -scared -scarer -scares -scarey -scarfs -scarph -scarps -scarry -scarts -scathe -scatts -scatty -scaups -scaurs -scenas -scends -scenes -scenic -scents -schavs -schema -scheme -schism -schist -schlep -schlub -schmoe -schmos -schnoz -school -schorl -schrik -schrod -schtik -schuit -schuln -schuls -schuss -schwas -scilla -scions -sclaff -sclera -scoffs -scolds -scolex -sconce -scones -scooch -scoops -scoots -scoped -scopes -scorch -scored -scorer -scores -scoria -scorns -scotch -scoter -scotia -scours -scouse -scouth -scouts -scowed -scowls -scrags -scrams -scrape -scraps -scrawl -screak -scream -screed -screen -screes -screws -screwy -scribe -scried -scries -scrimp -scrims -scrips -script -scrive -scrods -scroll -scroop -scrota -scrubs -scruff -scrums -scubas -scuffs -sculch -sculks -sculls -sculps -sculpt -scurfs -scurfy -scurry -scurvy -scutch -scutes -scutum -scyphi -scythe -seabag -seabed -seadog -sealed -sealer -seaman -seamed -seamer -seance -search -seared -searer -season -seated -seater -seawan -seaway -sebums -secant -seccos -secede -secern -second -secpar -secret -sector -secund -secure -sedans -sedate -seders -sedges -sedile -seduce -sedums -seeded -seeder -seeing -seeker -seeled -seemed -seemer -seemly -seeped -seesaw -seethe -seggar -segnos -segued -segues -seiche -seidel -seined -seiner -seines -seised -seiser -seises -seisin -seisms -seisor -seitan -seized -seizer -seizes -seizin -seizor -sejant -selahs -seldom -select -selfed -selkie -seller -selles -selsyn -selvas -selves -sememe -semple -sempre -senary -senate -sendal -sended -sender -sendup -seneca -senega -senhor -senile -senior -seniti -sennas -sennet -sennit -senora -senors -senryu -sensed -sensei -senses -sensor -sensum -sentry -sepals -sepias -sepoys -sepses -sepsis -septal -septet -septic -septum -sequel -sequin -seracs -serail -serais -serape -seraph -serdab -serein -serene -serest -serged -serger -serges -serial -series -serifs -serine -sering -serins -sermon -serosa -serous -serows -serums -serval -served -server -serves -servos -sesame -sestet -setoff -setons -setose -setous -setout -settee -setter -settle -setups -sevens -severe -severs -sewage -sewans -sewars -sewers -sewing -shabby -shacko -shacks -shaded -shader -shades -shadow -shaduf -shafts -shaggy -shaird -shairn -shaken -shaker -shakes -shakos -shaled -shales -shaley -shalom -shaman -shamas -shamed -shames -shammy -shamos -shamoy -shamus -shandy -shanks -shanny -shanti -shanty -shaped -shapen -shaper -shapes -shards -shared -sharer -shares -sharia -sharif -sharks -sharns -sharny -sharps -sharpy -shaugh -shauls -shaved -shaven -shaver -shaves -shavie -shawed -shawls -shawms -shazam -sheafs -sheals -shears -sheath -sheave -sheens -sheeny -sheers -sheesh -sheets -sheeve -sheikh -sheiks -sheila -shekel -shells -shelly -shelta -shelty -shelve -shelvy -shends -sheols -sheqel -sherds -sherif -sherpa -sherry -sheuch -sheugh -shewed -shewer -shibah -shield -shiels -shiers -shiest -shifts -shifty -shikar -shiksa -shikse -shills -shimmy -shindy -shined -shiner -shines -shinny -shires -shirks -shirrs -shirts -shirty -shists -shivah -shivas -shiver -shives -shlepp -shleps -shlock -shlubs -shlump -shmear -shmoes -shmuck -shnaps -shnook -shoals -shoaly -shoats -shocks -shoddy -shoers -shofar -shogis -shogun -shojis -sholom -shooed -shooks -shools -shoots -shoppe -shoran -shored -shores -shorls -shorts -shorty -shotes -shotts -should -shouts -shoved -shovel -shover -shoves -showed -shower -shoyus -shrank -shreds -shrewd -shrews -shriek -shrift -shrike -shrill -shrimp -shrine -shrink -shrive -shroff -shroud -shrove -shrubs -shrugs -shrunk -shtetl -shtick -shtiks -shucks -shunts -shuted -shutes -shyers -shyest -shying -sialic -sialid -sibyls -siccan -sicced -sicked -sickee -sicken -sicker -sickie -sickle -sickly -sickos -siddur -siding -sidled -sidler -sidles -sieged -sieges -sienna -sierra -siesta -sieurs -sieved -sieves -sifaka -sifted -sifter -sighed -sigher -sights -sigils -sigloi -siglos -siglum -sigmas -signal -signed -signee -signer -signet -signor -silage -silane -sileni -silent -silica -silked -silken -silkie -siller -siloed -silted -silvae -silvan -silvas -silver -silvex -simars -simian -simile -simlin -simmer -simnel -simony -simoom -simoon -simper -simple -simply -sinews -sinewy -sinful -singed -singer -singes -single -singly -sinker -sinned -sinner -sinter -siphon -siping -sipped -sipper -sippet -sirdar -sirees -sirens -siring -sirrah -sirras -sirree -sirups -sirupy -sisals -siskin -sisses -sister -sistra -sitars -sitcom -siting -sitten -sitter -situps -sivers -sixmos -sixtes -sixths -sizars -sizers -sizier -sizing -sizzle -skalds -skated -skater -skates -skatol -skeane -skeans -skeens -skeets -skeigh -skeins -skells -skelms -skelps -skenes -skerry -sketch -skewed -skewer -skibob -skiddy -skidoo -skiers -skiffs -skiing -skills -skimos -skimps -skimpy -skinks -skinny -skirls -skirrs -skirts -skited -skites -skived -skiver -skives -skivvy -sklent -skoals -skorts -skulks -skulls -skunks -skunky -skybox -skycap -skying -skylit -skyman -skymen -skyway -slacks -slaggy -slaked -slaker -slakes -slalom -slangs -slangy -slants -slanty -slatch -slated -slater -slates -slatey -slaved -slaver -slaves -slavey -slayed -slayer -sleave -sleaze -sleazo -sleazy -sledge -sleeks -sleeky -sleeps -sleepy -sleets -sleety -sleeve -sleigh -sleuth -slewed -sliced -slicer -slices -slicks -slider -slides -sliest -slieve -slight -slimed -slimes -slimly -slimsy -slings -slinks -slinky -sliped -slipes -slippy -slipup -slitty -sliver -slobby -slogan -sloids -slojds -sloops -sloped -sloper -slopes -sloppy -sloshy -sloths -slouch -slough -sloven -slowed -slower -slowly -sloyds -sludge -sludgy -sluffs -sluice -sluicy -sluing -slummy -slumps -slurbs -slurps -slurry -slushy -slyest -slypes -smacks -smalls -smalti -smalto -smalts -smarms -smarmy -smarts -smarty -smazes -smears -smeary -smeeks -smegma -smells -smelly -smelts -smerks -smidge -smilax -smiled -smiler -smiles -smiley -smirch -smirks -smirky -smiter -smites -smiths -smithy -smocks -smoggy -smoked -smoker -smokes -smokey -smolts -smooch -smoosh -smooth -smudge -smudgy -smugly -smutch -snacks -snafus -snaggy -snails -snaked -snakes -snakey -snappy -snared -snarer -snares -snarfs -snarks -snarky -snarls -snarly -snatch -snathe -snaths -snawed -snazzy -sneaks -sneaky -sneaps -snecks -sneers -sneery -sneesh -sneeze -sneezy -snells -snicks -snider -sniffs -sniffy -sniped -sniper -snipes -snippy -snitch -snivel -snobby -snoods -snooks -snools -snoops -snoopy -snoots -snooty -snooze -snoozy -snored -snorer -snores -snorts -snotty -snouts -snouty -snowed -snubby -snuffs -snuffy -snugly -soaked -soaker -soaped -soaper -soared -soarer -soaves -sobbed -sobber -sobeit -sobers -sobful -socage -soccer -social -socked -socket -socles -socman -socmen -sodded -sodden -sodium -soever -sofars -soffit -softas -soften -softer -softie -softly -sogged -soigne -soiled -soiree -sokols -solace -soland -solano -solans -solate -soldan -solder -solely -solemn -soleus -solgel -solidi -solids -soling -solion -soloed -solons -solums -solute -solved -solver -solves -somans -somata -somber -sombre -somite -somoni -sonant -sonars -sonata -sonder -sondes -sonics -sonnet -sonsie -sooner -sooted -soothe -sooths -sopite -sopors -sopped -sorbed -sorbet -sorbic -sordid -sordor -sorels -sorely -sorest -sorgho -sorgos -soring -sorned -sorner -sorrel -sorrow -sorted -sorter -sortie -sotols -sotted -souari -soucar -soudan -soughs -sought -souled -sounds -souped -source -soured -sourer -sourly -soused -souses -souter -souths -soviet -sovran -sowans -sowars -sowcar -sowens -sowers -sowing -sozine -sozins -spaced -spacer -spaces -spacey -spaded -spader -spades -spadix -spahee -spahis -spails -spaits -spales -spalls -spanks -spared -sparer -spares -sparge -sparid -sparks -sparky -sparry -sparse -spasms -spates -spathe -spavie -spavin -spawns -spayed -speaks -speans -spears -specie -specks -speech -speedo -speeds -speedy -speels -speers -speils -speirs -speise -speiss -spells -spelts -speltz -spence -spends -spendy -spense -spewed -spewer -sphene -sphere -sphery -sphinx -sphynx -spicae -spicas -spiced -spicer -spices -spicey -spicks -spider -spiels -spiers -spiffs -spiffy -spigot -spiked -spiker -spikes -spikey -spiled -spiles -spills -spilth -spinal -spined -spinel -spines -spinet -spinny -spinor -spinto -spiral -spirea -spired -spirem -spires -spirit -spirts -spital -spited -spites -spivvy -splake -splash -splats -splays -spleen -splent -splice -spline -splint -splits -splore -splosh -spodes -spoils -spoilt -spoked -spoken -spokes -sponge -spongy -spoofs -spoofy -spooks -spooky -spools -spoons -spoony -spoors -sporal -spored -spores -sports -sporty -spotty -spouse -spouts -sprags -sprain -sprang -sprats -sprawl -sprays -spread -sprees -sprent -sprier -sprigs -spring -sprint -sprite -sprits -spritz -sprout -spruce -sprucy -sprues -sprugs -sprung -spryer -spryly -spuing -spumed -spumes -spurns -spurry -spying -squabs -squads -squall -squama -square -squark -squash -squats -squawk -squaws -squeak -squeal -squegs -squibs -squids -squill -squint -squire -squirm -squirt -squish -squush -sradha -stable -stably -stacks -stacte -stades -stadia -staffs -staged -stager -stages -stagey -staggy -staigs -stains -stairs -staked -stakes -stalag -staled -staler -stales -stalks -stalky -stalls -stamen -stamps -stance -stanch -stands -staned -stanes -stangs -stanks -stanol -stanza -stapes -staphs -staple -starch -stared -starer -stares -starry -starts -starve -stases -stasis -statal -stated -stater -states -static -statin -stator -statue -status -staved -staves -stayed -stayer -steads -steady -steaks -steals -steams -steamy -steeds -steeks -steels -steely -steeps -steers -steeve -steins -stelae -stelai -stelar -steles -stelic -stella -stemma -stemmy -stench -stenos -stents -steppe -stereo -steres -steric -sterna -sterns -sterol -stewed -stichs -sticks -sticky -stiffs -stifle -stigma -stiles -stills -stilly -stilts -stimes -stingo -stings -stints -stiped -stipel -stipes -stirks -stirps -stitch -stithy -stiver -stoats -stocks -stocky -stodge -stodgy -stogey -stogie -stoics -stoked -stoker -stokes -stoled -stolen -stoles -stolid -stolon -stomal -stomas -stomps -stoned -stoner -stones -stoney -stooge -stooks -stoops -stoped -stoper -stopes -storax -stored -storer -stores -storey -storks -storms -stormy -stotin -stotts -stound -stoups -stoure -stours -stoury -stouts -stover -stoves -stowed -stowps -strafe -strain -strait -strake -strand -strang -straps -strass -strata -strath -strati -straws -strawy -strays -streak -stream -streek -streel -street -streps -stress -strewn -strews -striae -strick -strict -stride -strife -strike -string -stripe -strips -stript -stripy -strive -strobe -strode -stroke -stroll -stroma -strong -strook -strops -stroud -strove -strown -strows -stroys -struck -struma -strums -strung -strunt -struts -stubby -stucco -studio -studly -stuffs -stuffy -stulls -stumps -stumpy -stunts -stupas -stupes -stupor -sturdy -sturts -stying -stylar -styled -styler -styles -stylet -stylus -stymie -styrax -suable -suably -suaver -subahs -subbed -subdeb -subdue -subers -subfix -subgum -subito -sublet -sublot -submit -subnet -suborn -subpar -subsea -subset -subtle -subtly -suburb -subway -succah -succor -sucres -sudary -sudden -sudors -sudsed -sudser -sudses -sueded -suedes -suffer -suffix -sugars -sugary -sughed -suints -suited -suiter -suites -suitor -sukkah -sukkot -sulcal -sulcus -suldan -sulfas -sulfid -sulfur -sulked -sulker -sullen -sulpha -sultan -sultry -sumach -sumacs -summae -summas -summed -summer -summit -summon -sunbow -sundae -sunder -sundew -sundog -sundry -sunken -sunket -sunlit -sunnah -sunnas -sunned -sunray -sunset -suntan -sunups -superb -supers -supine -supped -supper -supple -supply -surahs -surely -surest -surety -surfed -surfer -surged -surger -surges -surimi -surras -surrey -surtax -survey -sushis -suslik -sussed -susses -sutler -sutras -suttas -suttee -suture -svaraj -svelte -swabby -swaged -swager -swages -swails -swains -swales -swamis -swamps -swampy -swanks -swanky -swanny -swaraj -swards -swarfs -swarms -swarth -swarty -swatch -swathe -swaths -swayed -swayer -swears -sweats -sweaty -swedes -sweeny -sweeps -sweepy -sweets -swells -swerve -sweven -swifts -swills -swimmy -swinge -swings -swingy -swinks -swiped -swipes -swiple -swirls -swirly -swishy -switch -swithe -swived -swivel -swives -swivet -swoons -swoony -swoops -swoopy -swoosh -swords -swound -swouns -syboes -sycees -sylphs -sylphy -sylvae -sylvan -sylvas -sylvin -symbol -synced -synchs -syncom -syndet -syndic -syngas -synods -syntax -synths -synura -sypher -syphon -syrens -syrinx -syrups -syrupy -sysops -system -syzygy -tabard -tabbed -tabbis -tabers -tablas -tabled -tables -tablet -taboos -tabors -tabour -tabued -tabuli -tabuns -taches -tacked -tacker -tacket -tackey -tackle -tactic -taenia -taffia -tafias -tagged -tagger -tagrag -tahini -tahsil -taigas -tailed -tailer -taille -tailor -taints -taipan -takahe -takers -takeup -taking -takins -talars -talced -talcky -talcum -talent -talers -talion -talked -talker -talkie -taller -tallis -tallit -tallol -tallow -talons -taluka -taluks -tamale -tamals -tamari -tambac -tambak -tambur -tamein -tamely -tamers -tamest -taming -tammie -tampan -tamped -tamper -tampon -tandem -tanged -tangle -tangly -tangos -tanist -tankas -tanked -tanker -tanned -tanner -tannic -tannin -tannoy -tanrec -tantra -tanuki -tapalo -tapers -tapeta -taping -tapirs -tapped -tapper -tappet -tarama -targes -target -tariff -taring -tarmac -tarnal -tarocs -taroks -tarots -tarpan -tarpon -tarred -tarres -tarsal -tarsia -tarsus -tartan -tartar -tarted -tarter -tartly -tarzan -tasked -tassel -tasses -tasset -tassie -tasted -taster -tastes -tatami -tatars -taters -tatsoi -tatted -tatter -tattie -tattle -tattoo -taught -taunts -tauons -taupes -tauted -tauten -tauter -tautly -tautog -tavern -tawdry -tawers -tawing -tawney -tawpie -tawsed -tawses -taxeme -taxers -taxied -taxies -taxing -taxite -taxman -taxmen -taxols -taxons -tazzas -teabox -teacup -teamed -teapot -teapoy -teared -tearer -teased -teasel -teaser -teases -teated -teazel -teazle -teched -techie -techno -tectal -tectum -tedded -tedder -tedium -teeing -teemed -teemer -teener -teensy -teepee -teeter -teethe -teflon -tegmen -teguas -teiids -teinds -tekkie -telcos -teledu -telega -telfer -telial -telium -teller -tellys -telnet -telome -telson -temped -tempeh -temper -temple -tempos -tempts -tenace -tenail -tenant -tended -tender -tendon -tendus -tenets -teniae -tenias -tenner -tennis -tenons -tenors -tenour -tenpin -tenrec -tensed -tenser -tenses -tensor -tented -tenter -tenths -tentie -tenues -tenuis -tenure -tenuti -tenuto -teopan -tepals -tepees -tepefy -tephra -tepoys -terais -teraph -terbia -terbic -tercel -terces -tercet -teredo -terete -tergal -tergum -termed -termer -termly -termor -ternes -terrae -terras -terret -territ -terror -terser -teslas -testae -tested -testee -tester -teston -tetany -tetchy -tether -tetrad -tetras -tetris -tetryl -tetter -tewing -thacks -thairm -thaler -thalli -thanes -thanks -tharms -thatch -thawed -thawer -thebes -thecae -thecal -thefts -thegns -theine -theins -theirs -theism -theist -themed -themes -thenal -thenar -thence -theory -theres -therme -therms -theses -thesis -thesps -thetas -thetic -thicks -thieve -thighs -thills -things -thinks -thinly -thiols -thiram -thirds -thirls -thirst -thirty -tholed -tholes -tholoi -tholos -thongs -thorax -thoria -thoric -thorns -thorny -thoron -thorpe -thorps -thoued -though -thrall -thrash -thrave -thrawn -thraws -thread -threap -threat -threep -threes -thresh -thrice -thrift -thrill -thrips -thrive -throat -throbs -throes -throne -throng -throve -thrown -throws -thrums -thrust -thujas -thulia -thumbs -thumps -thunks -thurls -thusly -thuyas -thwack -thwart -thymes -thymey -thymic -thymol -thymus -thyrse -thyrsi -tiaras -tibiae -tibial -tibias -ticals -ticced -ticked -ticker -ticket -tickle -tictac -tictoc -tidbit -tiddly -tidied -tidier -tidies -tidily -tiding -tieing -tiepin -tierce -tiered -tiffed -tiffin -tigers -tights -tiglon -tigons -tikkas -tilaks -tildes -tilers -tiling -tilled -tiller -tilted -tilter -tilths -timbal -timber -timbre -timely -timers -timing -tincal -tincts -tinder -tineal -tineas -tineid -tinful -tinged -tinges -tingle -tingly -tinier -tinily -tining -tinker -tinkle -tinkly -tinman -tinmen -tinned -tinner -tinpot -tinsel -tinted -tinter -tipcat -tipoff -tipped -tipper -tippet -tipple -tiptoe -tiptop -tirade -tiring -tirled -tisane -tissue -titans -tmeses -tmesis -toasts -toasty -tobies -tocher -tocsin -todays -toddle -todies -toecap -toeing -toffee -togaed -togate -togged -toggle -togues -toiled -toiler -toiles -toited -tokays -tokens -tolane -tolans -tolars -toledo -toling -tolled -toller -toluic -toluid -toluol -toluyl -tolyls -tomans -tomato -tombac -tombak -tombal -tombed -tomboy -tomcat -tomcod -tommed -tomtit -tondos -toneme -toners -tongas -tonged -tonger -tongue -tonics -tonier -toning -tonish -tonlet -tonner -tonnes -tonsil -tooled -tooler -toonie -tooted -tooter -tooths -toothy -tootle -tootsy -topees -topers -topful -tophes -tophus -topics -toping -topped -topper -topple -toques -toquet -torahs -torchy -torero -torics -tories -toroid -torose -toroth -torous -torpid -torpor -torque -torrid -torses -torsks -torsos -tortas -torten -tortes -torula -toshes -tossed -tosses -tossup -totals -totems -toters -tother -toting -totted -totter -toucan -touche -touchy -toughs -toughy -toupee -toured -tourer -toused -touses -tousle -touted -touter -touzle -towage -toward -towels -towers -towery -towhee -towies -towing -townee -townie -toxics -toxine -toxins -toxoid -toyers -toying -toyish -toyons -traced -tracer -traces -tracks -tracts -traded -trader -trades -tragic -tragus -traiks -trails -trains -traits -tramel -tramps -trampy -trance -tranks -tranny -tranqs -trapan -trapes -trashy -trauma -travel -traves -trawls -treads -treats -treaty -treble -trebly -treens -trefah -tremor -trench -trends -trendy -trepan -trepid -tressy -trevet -triacs -triads -triage -trials -tribal -tribes -triced -tricep -trices -tricks -tricky -tricot -triene -triens -triers -trifid -trifle -trigly -trigon -trigos -trijet -trikes -trilby -trills -trimer -trimly -trinal -trined -trines -triode -triols -triose -tripes -triple -triply -tripod -tripos -trippy -triste -triter -triton -triune -trivet -trivia -troaks -trocar -troche -trocks -trogon -troika -troked -trokes -trolls -trolly -trompe -tromps -tronas -trones -troops -tropes -trophy -tropic -tropin -troths -trotyl -trough -troupe -trouts -trouty -trover -troves -trowed -trowel -trowth -truant -truced -truces -trucks -trudge -truest -truffe -truing -truism -trulls -trumps -trunks -trusts -trusty -truths -trying -tryout -tryste -trysts -tsades -tsadis -tsetse -tsking -tsktsk -tsores -tsoris -tsuris -tubate -tubbed -tubber -tubers -tubful -tubing -tubist -tubule -tuchun -tucked -tucker -tucket -tuffet -tufoli -tufted -tufter -tugged -tugger -tugrik -tuille -tuladi -tulips -tulles -tumble -tumefy -tumors -tumour -tumped -tumuli -tumult -tundra -tuners -tuneup -tunica -tunics -tuning -tunned -tunnel -tupelo -tupiks -tupped -tuques -turaco -turban -turbid -turbit -turbos -turbot -tureen -turfed -turgid -turgor -turion -turkey -turned -turner -turnip -turnon -turnup -turret -turtle -turves -tusche -tushed -tushes -tushie -tusked -tusker -tussal -tusseh -tusser -tusses -tussis -tussle -tussor -tussur -tutees -tutors -tutted -tuttis -tutued -tuxedo -tuyere -tuyers -twains -twanky -tweaks -tweaky -tweeds -tweedy -tweens -tweeny -tweets -tweeze -twelve -twenty -twerps -twibil -twiers -twiggy -twilit -twills -twined -twiner -twines -twinge -twirls -twirly -twirps -twists -twisty -twitch -twofer -twyers -tycoon -tymbal -tympan -tyning -typhon -typhus -typier -typify -typing -typist -tyrant -tyring -tythed -tythes -tzetze -tzuris -uakari -ubiety -ubique -udders -uglier -uglies -uglify -uglily -ugsome -uhlans -ukases -ulamas -ulcers -ulemas -ullage -ulster -ultima -ultimo -ultras -umamis -umbels -umbers -umbles -umbrae -umbral -umbras -umiack -umiacs -umiaks -umiaqs -umlaut -umping -umpire -unable -unaged -unakin -unarms -unawed -unaxed -unbale -unbans -unbars -unbear -unbelt -unbend -unbent -unbind -unbolt -unborn -unbred -unbusy -uncage -uncake -uncaps -uncase -uncast -unchic -unciae -uncial -uncini -unclad -uncles -unclip -unclog -uncoil -uncool -uncork -uncuff -uncurb -uncurl -uncute -undead -undies -undine -undock -undoer -undoes -undone -undraw -undrew -unduly -undyed -unease -uneasy -uneven -unfair -unfelt -unfits -unfixt -unfold -unfond -unfree -unfurl -ungird -ungirt -unglue -ungual -ungues -unguis -ungula -unhair -unhand -unhang -unhats -unhelm -unhewn -unholy -unhood -unhook -unhung -unhurt -unhusk -unific -unions -unipod -unique -unisex -unison -united -uniter -unites -unjams -unjust -unkend -unkent -unkept -unkind -unkink -unknit -unknot -unlace -unlade -unlaid -unlash -unlays -unlead -unless -unlike -unlink -unlive -unload -unlock -unmade -unmake -unmans -unmask -unmeet -unmesh -unmews -unmixt -unmold -unmoor -unmown -unnail -unopen -unpack -unpaid -unpegs -unpens -unpent -unpick -unpile -unpins -unplug -unpure -unread -unreal -unreel -unrent -unrest -unrigs -unripe -unrips -unrobe -unroll -unroof -unroot -unrove -unruly -unsafe -unsaid -unsawn -unsays -unseal -unseam -unseat -unseen -unsell -unsent -unsets -unsewn -unsews -unsexy -unshed -unship -unshod -unshut -unsnag -unsnap -unsold -unsown -unspun -unstep -unstop -unsung -unsunk -unsure -untack -untame -untidy -untied -unties -untold -untorn -untrim -untrod -untrue -untuck -untune -unused -unveil -unvext -unwary -unwell -unwept -unwind -unwise -unwish -unwits -unworn -unwove -unwrap -unyoke -unzips -upases -upbear -upbeat -upbind -upboil -upbore -upbows -upcast -upcoil -upcurl -updart -update -updive -updove -upends -upflow -upfold -upgaze -upgird -upgirt -upgrew -upgrow -upheap -upheld -uphill -uphold -uphove -uphroe -upkeep -upland -upleap -uplift -uplink -upload -upmost -uppers -uppile -upping -uppish -uppity -upprop -uprate -uprear -uprise -uproar -uproot -uprose -uprush -upsend -upsent -upsets -upshot -upside -upsize -upsoar -upstep -upstir -uptake -uptalk -uptear -uptick -uptilt -uptime -uptore -uptorn -uptoss -uptown -upturn -upwaft -upward -upwell -upwind -uracil -uraeus -urania -uranic -uranyl -urares -uraris -urases -urates -uratic -urbane -urbias -urchin -urease -uredia -uredos -ureide -uremia -uremic -urgent -urgers -urging -urials -uropod -urping -ursids -ursine -urtext -uruses -usable -usably -usages -usance -useful -ushers -usneas -usques -usuals -usurer -usurps -uterus -utmost -utopia -utters -uveous -uvulae -uvular -uvulas -vacant -vacate -vacuum -vadose -vagary -vagile -vagrom -vaguer -vahine -vailed -vainer -vainly -vakeel -vakils -valets -valgus -valine -valise -valkyr -valley -valors -valour -valses -valued -valuer -values -valuta -valval -valvar -valved -valves -vamose -vamped -vamper -vandal -vandas -vanish -vanity -vanman -vanmen -vanned -vanner -vapors -vapory -vapour -varias -varied -varier -varies -varlet -varnas -varoom -varved -varves -vassal -vaster -vastly -vatful -vatted -vaults -vaulty -vaunts -vaunty -vaward -vealed -vealer -vector -veejay -veenas -veepee -veered -vegans -vegete -vegged -veggie -vegies -veiled -veiler -veinal -veined -veiner -velars -velate -velcro -veldts -vellum -veloce -velour -velure -velvet -vended -vendee -vender -vendor -vendue -veneer -venene -venery -venged -venges -venial -venine -venins -venire -venoms -venose -venous -vented -venter -venues -venule -verbal -verbid -verdin -verged -verger -verges -verier -verify -verily -verism -verist -verite -verity -vermes -vermin -vermis -vernal -vernix -versal -versed -verser -verses -verset -versos -verste -versts -versus -vertex -vertus -verves -vervet -vesica -vesper -vespid -vessel -vestal -vestas -vested -vestee -vestry -vetoed -vetoer -vetoes -vetted -vetter -vexers -vexils -vexing -viable -viably -vialed -viands -viatic -viator -vibist -vibrio -vicars -vicing -victim -victor -vicuna -videos -viewed -viewer -vigias -vigils -vigors -vigour -viking -vilely -vilest -vilify -villae -villas -villus -vimina -vinals -vincas -vineal -vinery -vinier -vinify -vining -vinous -vinyls -violas -violet -violin -vipers -virago -vireos -virgas -virgin -virile -virion -viroid -virtue -virtus -visaed -visage -visard -viscid -viscus -viseed -vising -vision -visits -visive -visors -vistas -visual -vitals -vitric -vittae -vittle -vivace -vivary -vivers -vivify -vixens -vizard -vizier -vizirs -vizors -vizsla -vocabs -vocals -vodkas -vodoun -vodous -voduns -vogued -voguer -vogues -voiced -voicer -voices -voided -voider -voiles -volant -volery -voling -volley -volost -voltes -volume -volute -volvas -volvox -vomers -vomica -voodoo -vortex -votary -voters -voting -votive -voudon -vowels -vowers -vowing -voyage -voyeur -vrooms -vrouws -wabble -wabbly -wadded -wadder -waddie -waddle -waddly -waders -wadies -wading -wadmal -wadmel -wadmol -wadset -waeful -wafers -wafery -waffed -waffie -waffle -waffly -wafted -wafter -wagers -wagged -wagger -waggle -waggly -waggon -waging -wagons -wahine -wahoos -waifed -wailed -wailer -waired -waists -waited -waiter -waived -waiver -waives -wakame -wakens -wakers -wakiki -waking -walers -walies -waling -walked -walker -walkup -wallah -wallas -walled -wallet -wallie -wallop -wallow -walnut -walrus -wamble -wambly -wammus -wampum -wampus -wander -wandle -wanier -waning -wanion -wanned -wanner -wanted -wanter -wanton -wapiti -wapped -warble -warded -warden -warder -warier -warily -waring -warked -warmed -warmer -warmly -warmth -warmup -warned -warner -warped -warper -warred -warren -warsaw -warsle -warted -wasabi -washed -washer -washes -washup -wastes -wastry -watape -wataps -waters -watery -watter -wattle -waucht -waught -wauked -wauled -wavers -wavery -waveys -wavier -wavies -wavily -waving -wawled -waxers -waxier -waxily -waxing -waylay -wazoos -weaken -weaker -weakly -weakon -wealds -wealth -weaned -weaner -weapon -wearer -weasel -weason -weaved -weaver -weaves -webbed -webcam -webers -webfed -weblog -wechts -wedded -wedder -wedeln -wedels -wedged -wedges -wedgie -weeded -weeder -weekly -weened -weenie -weensy -weeper -weepie -weeted -weever -weevil -weewee -weighs -weight -weirds -weirdy -welded -welder -weldor -welkin -welled -wellie -welted -welter -wended -weskit -wester -wether -wetted -whacks -whacky -whaled -whaler -whales -whammo -whammy -whangs -wharfs -wharve -whaups -wheals -wheats -wheels -wheens -wheeps -wheeze -wheezy -whelks -whelky -whelms -whelps -whenas -whence -wheres -wherry -wherve -wheyey -whidah -whiffs -whiled -whiles -whilom -whilst -whimsy -whined -whiner -whines -whiney -whinge -whinny -whippy -whirls -whirly -whirrs -whirry -whisht -whisks -whisky -whists -whited -whiten -whiter -whites -whitey -whizzy -wholes -wholly -whomps -whomso -whoofs -whoops -whoosh -whorls -whorts -whosis -whumps -whydah -wiccan -wiccas -wiches -wicked -wicker -wicket -wicopy -widder -widdie -widdle -widely -widens -widest -widget -widish -widows -widths -wields -wieldy -wiener -wienie -wifely -wifeys -wifing -wigans -wigeon -wigged -wiggle -wiggly -wights -wiglet -wigwag -wigwam -wikiup -wilded -wilder -wildly -wilful -wilier -wilily -wiling -willed -willer -willet -willie -willow -wilted -wimble -wimmin -wimped -wimple -winced -wincer -winces -wincey -winded -winder -windle -window -windup -winery -winged -winger -winier -wining -winish -winked -winker -winkle -winned -winner -winnow -winoes -winter -wintle -wintry -winzes -wipers -wiping -wirers -wirier -wirily -wiring -wisdom -wisely -wisent -wisest -wished -wisher -wishes -wising -wisped -wissed -wisses -wisted -witans -witchy -withal -withed -wither -withes -within -witing -witney -witted -wittol -wivern -wivers -wiving -wizard -wizens -wizzen -wizzes -woaded -woalds -wobble -wobbly -wodges -woeful -wolfed -wolfer -wolver -wolves -womans -wombat -wombed -womera -wonder -wonned -wonner -wonted -wonton -wooded -wooden -woodie -woodsy -wooers -woofed -woofer -wooing -wooled -woolen -wooler -woolie -woolly -worded -worked -worker -workup -worlds -wormed -wormer -wormil -worrit -worsen -worser -worses -worset -worsts -worths -worthy -wotted -wounds -wovens -wowing -wowser -wracks -wraith -wrangs -wrasse -wraths -wrathy -wreaks -wreath -wrecks -wrench -wrests -wretch -wricks -wriest -wright -wrings -wrists -wristy -writer -writes -writhe -wrongs -wryest -wrying -wursts -wurzel -wusses -wuther -wyches -wyling -wyting -wyvern -xebecs -xenial -xenias -xenons -xylans -xylems -xylene -xyloid -xylols -xylose -xylyls -xyster -xystoi -xystos -xystus -yabber -yabbie -yachts -yacked -yaffed -yagers -yahoos -yairds -yakked -yakker -yakuza -yamens -yammer -yamuns -yanked -yanqui -yantra -yapock -yapoks -yapons -yapped -yapper -yarded -yarder -yarely -yarest -yarned -yarner -yarrow -yasmak -yatter -yauped -yauper -yaupon -yautia -yawing -yawled -yawned -yawner -yawped -yawper -yclept -yeaned -yearly -yearns -yeasts -yeasty -yecchs -yeelin -yelled -yeller -yellow -yelped -yelper -yenned -yentas -yentes -yeoman -yeomen -yerbas -yerked -yessed -yesses -yester -yeuked -yields -yipped -yippee -yippie -yirred -yirths -yobbos -yocked -yodels -yodled -yodler -yodles -yogees -yogini -yogins -yogurt -yoicks -yokels -yoking -yolked -yonder -yonker -youngs -youpon -youths -yowies -yowing -yowled -yowler -yttria -yttric -yuccas -yucked -yukked -yulans -yupons -yuppie -yutzes -zaddik -zaffar -zaffer -zaffir -zaffre -zaftig -zagged -zaikai -zaires -zamias -zanana -zander -zanier -zanies -zanily -zanzas -zapped -zapper -zareba -zariba -zayins -zazens -zealot -zeatin -zebeck -zebecs -zebras -zechin -zenana -zenith -zephyr -zeroed -zeroes -zeroth -zested -zester -zeugma -zibeth -zibets -zigged -zigzag -zillah -zinced -zincic -zincky -zinebs -zinged -zinger -zinnia -zipped -zipper -zirams -zircon -zither -zizith -zizzle -zlotys -zoaria -zocalo -zodiac -zoecia -zoftig -zombie -zombis -zonary -zonate -zoners -zoning -zonked -zonula -zonule -zooids -zooier -zoomed -zoonal -zooned -zorils -zoster -zouave -zounds -zoysia -zydeco -zygoid -zygoma -zygose -zygote -zymase