diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 0000000..f734ea7 --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,25 @@ +name: .NET Core + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.101 + - name: Install dependencies + run: dotnet restore + - name: Build + run: dotnet build --configuration Release --no-restore + - name: Test + run: dotnet test --no-restore --verbosity normal diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41ffa34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,231 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +bin/ +Bin/ +obj/ +Obj/ + +# Visual Studio 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +orleans.codegen.cs + +/node_modules + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ diff --git a/HumanReadableId.ConsoleApp/HumanReadableId.ConsoleApp.csproj b/HumanReadableId.ConsoleApp/HumanReadableId.ConsoleApp.csproj new file mode 100644 index 0000000..850b9ec --- /dev/null +++ b/HumanReadableId.ConsoleApp/HumanReadableId.ConsoleApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + + diff --git a/HumanReadableId.ConsoleApp/Program.cs b/HumanReadableId.ConsoleApp/Program.cs new file mode 100644 index 0000000..fdc20b2 --- /dev/null +++ b/HumanReadableId.ConsoleApp/Program.cs @@ -0,0 +1,39 @@ +using System; + +namespace HumanReadableId.ConsoleApp +{ + public class Program + { + static void Main(string[] args) + { + Console.WriteLine($"Default: {HumanReadableId.Generate()}"); + + var id = HumanReadableId.Generate(new[] + { + WordType.Adjective, WordType.Verb, WordType.Verb, WordType.Animal + }); + + Console.WriteLine($"Custom pattern: {id}"); + + id = HumanReadableId.Generate(new Config + { + SeparationChar = "", + LowerCasePassphrase = false + }, WordType.Verb, WordType.Adjective, WordType.Animal); + + Console.WriteLine($"Custom pattern w/ config: {id}"); + + for (int i = 0; i < 100; i++) + { + Console.WriteLine(HumanReadableId.Generate(new Config + { + SeparationChar = string.Empty, + LowerCasePassphrase = false + }, WordType.Verb, WordType.Adjective, WordType.Animal)); + } + + + Console.ReadLine(); + } + } +} diff --git a/HumanReadableId.Core/HumanReadableId.cs b/HumanReadableId.Core/HumanReadableId.cs new file mode 100644 index 0000000..2c9f11b --- /dev/null +++ b/HumanReadableId.Core/HumanReadableId.cs @@ -0,0 +1,105 @@ +using System; +using System.Text; +using System.Threading; + +namespace HumanReadableId +{ + public enum WordType + { + Adjective, + Verb, + Animal + } + + public class Config + { + public bool LowerCasePassphrase { get; set; } = true; + public string SeparationChar { get; set; } = "-"; + } + + /// + /// Generate human readable IDs. + /// + public static class HumanReadableId + { + // Thread-safe random number generator + private static readonly ThreadLocal _rnd = new ThreadLocal(() => new Random()); + + /// + /// Default pattern is: + /// adjective-adjective-animal-verb-adjective + /// E.g. WordType[] DefaultPattern = { WordType.Adjective, WordType.Adjective, WordType.Animal, WordType.Verb, WordType.Adjective }; + /// + public static readonly WordType[] DefaultPattern = { WordType.Adjective, WordType.Adjective, WordType.Animal, WordType.Verb, WordType.Adjective }; + + /// + /// Overload method for Generate to use default configuration. + /// Default behavior returns an ID in the format: adjective-adjective-animal-verb-adjective + /// + /// Array of WordType + /// Generated passphrase string + public static string Generate(params WordType[] pattern) => Generate(null, pattern); + + /// + /// Default behavior returns an ID in the format: adjective-adjective-animal-verb-adjective + /// E.g. + /// happy-energetic-dog-runs-quickly + /// Override "pattern" param to customize order and/or number of words to generate. + /// + /// Configuration options for passphrase generation + /// Defaults to "DefaultPattern" which is: adjective-adjective-animal-verb-adjective + /// Generated passphrase string + public static string Generate(Config config = null, params WordType[] pattern) + { + pattern = GetPatternOrDefault(pattern); + config = config ?? new Config(); + + var idBuilder = new StringBuilder(); + + for (int i = 0; i < pattern.Length; i++) + { + AppendRandomWord(idBuilder, pattern[i]); + if (i + 1 < pattern.Length) + { + idBuilder.Append(config.SeparationChar); + } + } + + var result = idBuilder.ToString(); + return config.LowerCasePassphrase ? result.ToLowerInvariant() : result; + } + + /// + /// Gets the default pattern if the provided pattern is null or empty. + /// + /// Array of WordType + /// Default pattern if input is null or empty, otherwise the input pattern + private static WordType[] GetPatternOrDefault(WordType[] pattern) + { + return (pattern == null || pattern.Length == 0) ? DefaultPattern : pattern; + } + + /// + /// Appends a random word of the specified WordType to the StringBuilder. + /// + /// StringBuilder to append the word to + /// Type of word to append + private static void AppendRandomWord(StringBuilder idBuilder, WordType wordType) + { + switch (wordType) + { + case WordType.Adjective: + idBuilder.Append(Words.Adjectives[_rnd.Value.Next(Words.Adjectives.Length)]); + break; + case WordType.Verb: + idBuilder.Append(Words.Verbs[_rnd.Value.Next(Words.Verbs.Length)]); + break; + case WordType.Animal: + idBuilder.Append(Words.Animals[_rnd.Value.Next(Words.Animals.Length)]); + break; + default: + throw new ArgumentOutOfRangeException(nameof(wordType), wordType, null); + } + } + } +} diff --git a/HumanReadableId.Core/HumanReadableId.csproj b/HumanReadableId.Core/HumanReadableId.csproj new file mode 100644 index 0000000..f08a9f7 --- /dev/null +++ b/HumanReadableId.Core/HumanReadableId.csproj @@ -0,0 +1,51 @@ + + + + netstandard1.1 + 1.0.0 + GFoley83 + + true + https://github.com/GFoley83/HumanReadableId + https://github.com/GFoley83/HumanReadableId + https://opensource.org/licenses/MIT + Creates a human readable IDs like "happy-energetic-dog-runs-quickly". Use the default format of adjective-adjective-animal-verb-adjective or a custom format & length of your choosing. + +Example Usage + +https://dotnetfiddle.net/4KGjWQ + +// Create an ID in the default form adjective-adjective-animal-verb-adjective +// id == "pale-swift-hornbill-support-saddlebrown" +var id = HumanReadableId.Generate(); + +// Create an ID in a custom format and length +// id == "walk-horrible-confess-cuestion" +id = HumanReadableId.Generate(WordType.Verb, WordType.Adjective, WordType.Verb, WordType.Verb); + +// Create an ID using a custom separator in pascal case +// id == KickJumpyFruitfly +id = HumanReadableId.Generate(new Config +{ + SeparationChar = string.Empty, + LowerCasePassphrase = false +}, WordType.Verb, WordType.Adjective, WordType.Animal); + + + false + Unique, Ids, Human, Readable, Human-readable, Passphrase, Adjective, Verb, Animal + LICENSE.md + + + true + true + + + + + True + + + + + diff --git a/HumanReadableId.Core/Words.cs b/HumanReadableId.Core/Words.cs new file mode 100644 index 0000000..b17eb9f --- /dev/null +++ b/HumanReadableId.Core/Words.cs @@ -0,0 +1,3921 @@ +using System; +using System.Linq; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("HumanReadableId.UnitTests")] +namespace HumanReadableId +{ + internal static class Words + { + public static string[] Adjectives => new[] + { + "Abandoned", + "Able", + "Absolute", + "Academic", + "Acceptable", + "Acclaimed", + "Accomplished", + "Accurate", + "Aching", + "Acidic", + "Acrobatic", + "Adorable", + "Adventurous", + "Babyish", + "Back", + "Bad", + "Baggy", + "Bare", + "Barren", + "Basic", + "Beautiful", + "Belated", + "Beloved", + "Calculating", + "Calm", + "Candid", + "Canine", + "Capital", + "Carefree", + "Careful", + "Careless", + "Caring", + "Cautious", + "Cavernous", + "Celebrated", + "Charming", + "Damaged", + "Damp", + "Dangerous", + "Dapper", + "Daring", + "Dark", + "Darling", + "Dazzling", + "Dead", + "Deadly", + "Deafening", + "Dear", + "Dearest", + "Each", + "Eager", + "Early", + "Earnest", + "Easy", + "Easygoing", + "Ecstatic", + "Edible", + "Educated", + "Fabulous", + "Failing", + "Faint", + "Fair", + "Faithful", + "Fake", + "Familiar", + "Famous", + "Fancy", + "Fantastic", + "Far", + "Faraway", + "Farflung", + "Faroff", + "Gargantuan", + "Gaseous", + "General", + "Generous", + "Gentle", + "Genuine", + "Giant", + "Giddy", + "Gigantic", + "Hairy", + "Half", + "Handmade", + "Handsome", + "Handy", + "Happy", + "Happygolucky", + "Hard", + "Icky", + "Icy", + "Ideal", + "Idealistic", + "Identical", + "Idiotic", + "Idle", + "Idolized", + "Ignorant", + "Ill", + "Illegal", + "Jaded", + "Jagged", + "Jampacked", + "Kaleidoscopic", + "Keen", + "Lame", + "Lanky", + "Large", + "Last", + "Lasting", + "Late", + "Lavish", + "Lawful", + "Mad", + "Madeup", + "Magnificent", + "Majestic", + "Major", + "Male", + "Mammoth", + "Married", + "Marvelous", + "Naive", + "Narrow", + "Nasty", + "Natural", + "Naughty", + "Obedient", + "Obese", + "Oblong", + "Oblong", + "Obvious", + "Occasional", + "Oily", + "Palatable", + "Pale", + "Paltry", + "Parallel", + "Parched", + "Partial", + "Passionate", + "Past", + "Pastel", + "Peaceful", + "Peppery", + "Perfect", + "Perfumed", + "Quaint", + "Qualified", + "Radiant", + "Ragged", + "Rapid", + "Rare", + "Rash", + "Raw", + "Recent", + "Reckless", + "Rectangular", + "Sad", + "Safe", + "Salty", + "Same", + "Sandy", + "Sane", + "Sarcastic", + "Sardonic", + "Satisfied", + "Scaly", + "Scarce", + "Scared", + "Scary", + "Scented", + "Scholarly", + "Scientific", + "Scornful", + "Scratchy", + "Scrawny", + "Second", + "Secondary", + "Secondhand", + "Secret", + "Selfassured", + "Selfish", + "Selfreliant", + "Sentimental", + "Talkative", + "Tall", + "Tame", + "Tan", + "Tangible", + "Tart", + "Tasty", + "Tattered", + "Taut", + "Tedious", + "Teeming", + "Ugly", + "Ultimate", + "Unacceptable", + "Unaware", + "Uncomfortable", + "Uncommon", + "Unconscious", + "Understated", + "Unequaled", + "Vacant", + "Vague", + "Vain", + "Valid", + "Wan", + "Warlike", + "Warm", + "Warmhearted", + "Warped", + "Wary", + "Wasteful", + "Watchful", + "Waterlogged", + "Watery", + "Wavy", + "Yawning", + "Yearly", + "Zany", + "False", + "Active", + "Actual", + "Adept", + "Admirable", + "Admired", + "Adolescent", + "Adorable", + "Adored", + "Advanced", + "Affectionate", + "Afraid", + "Aged", + "Aggravating", + "Beneficial", + "Best", + "Better", + "Bewitched", + "Big", + "Bighearted", + "Biodegradable", + "Bitesized", + "Bitter", + "Black", + "Cheap", + "Cheerful", + "Cheery", + "Chief", + "Chilly", + "Chubby", + "Circular", + "Classic", + "Clean", + "Clear", + "Clearcut", + "Clever", + "Close", + "Closed", + "Decent", + "Decimal", + "Decisive", + "Deep", + "Defenseless", + "Defensive", + "Defiant", + "Deficient", + "Definite", + "Definitive", + "Delayed", + "Delectable", + "Delicious", + "Elaborate", + "Elastic", + "Elated", + "Elderly", + "Electric", + "Elegant", + "Elementary", + "Elliptical", + "Embarrassed", + "Fast", + "Fat", + "Fatal", + "Fatherly", + "Favorable", + "Favorite", + "Fearful", + "Fearless", + "Feisty", + "Feline", + "Female", + "Feminine", + "Few", + "Fickle", + "Gifted", + "Giving", + "Glamorous", + "Glaring", + "Glass", + "Gleaming", + "Gleeful", + "Glistening", + "Glittering", + "Hardtofind", + "Harmful", + "Harmless", + "Harmonious", + "Harsh", + "Hasty", + "Hateful", + "Haunting", + "Illfated", + "Illinformed", + "Illiterate", + "Illustrious", + "Imaginary", + "Imaginative", + "Immaculate", + "Immaterial", + "Immediate", + "Immense", + "Impassioned", + "Jaunty", + "Jealous", + "Jittery", + "Key", + "Kind", + "Lazy", + "Leading", + "Leafy", + "Lean", + "Left", + "Legal", + "Legitimate", + "Light", + "Masculine", + "Massive", + "Mature", + "Meager", + "Mealy", + "Mean", + "Measly", + "Meaty", + "Medical", + "Mediocre", + "Nautical", + "Near", + "Neat", + "Necessary", + "Needy", + "Odd", + "Oddball", + "Offbeat", + "Offensive", + "Official", + "Old", + "Periodic", + "Perky", + "Personal", + "Pertinent", + "Pesky", + "Pessimistic", + "Petty", + "Phony", + "Physical", + "Piercing", + "Pink", + "Pitiful", + "Plain", + "Quarrelsome", + "Quarterly", + "Ready", + "Real", + "Realistic", + "Reasonable", + "Red", + "Reflecting", + "Regal", + "Regular", + "Separate", + "Serene", + "Serious", + "Serpentine", + "Several", + "Severe", + "Shabby", + "Shadowy", + "Shady", + "Shallow", + "Shameful", + "Shameless", + "Sharp", + "Shimmering", + "Shiny", + "Shocked", + "Shocking", + "Shoddy", + "Short", + "Shortterm", + "Showy", + "Shrill", + "Shy", + "Sick", + "Silent", + "Silky", + "Tempting", + "Tender", + "Tense", + "Tepid", + "Terrible", + "Terrific", + "Testy", + "Thankful", + "That", + "These", + "Uneven", + "Unfinished", + "Unfit", + "Unfolded", + "Unfortunate", + "Unhappy", + "Unhealthy", + "Uniform", + "Unimportant", + "Unique", + "Valuable", + "Vapid", + "Variable", + "Vast", + "Velvety", + "Weak", + "Wealthy", + "Weary", + "Webbed", + "Wee", + "Weekly", + "Weepy", + "Weighty", + "Weird", + "Welcome", + "Welldocumented", + "Yellow", + "Zealous", + "Aggressive", + "Agile", + "Agitated", + "Agonizing", + "Agreeable", + "Ajar", + "Alarmed", + "Alarming", + "Alert", + "Alienated", + "Alive", + "All", + "Altruistic", + "Blackandwhite", + "Bland", + "Blank", + "Blaring", + "Bleak", + "Blind", + "Blissful", + "Blond", + "Blue", + "Blushing", + "Cloudy", + "Clueless", + "Clumsy", + "Cluttered", + "Coarse", + "Cold", + "Colorful", + "Colorless", + "Colossal", + "Comfortable", + "Common", + "Compassionate", + "Competent", + "Complete", + "Delightful", + "Delirious", + "Demanding", + "Dense", + "Dental", + "Dependable", + "Dependent", + "Descriptive", + "Deserted", + "Detailed", + "Determined", + "Devoted", + "Different", + "Embellished", + "Eminent", + "Emotional", + "Empty", + "Enchanted", + "Enchanting", + "Energetic", + "Enlightened", + "Enormous", + "Filthy", + "Fine", + "Finished", + "Firm", + "First", + "Firsthand", + "Fitting", + "Fixed", + "Flaky", + "Flamboyant", + "Flashy", + "Flat", + "Flawed", + "Flawless", + "Flickering", + "Gloomy", + "Glorious", + "Glossy", + "Glum", + "Golden", + "Good", + "Goodnatured", + "Gorgeous", + "Graceful", + "Healthy", + "Heartfelt", + "Hearty", + "Heavenly", + "Heavy", + "Hefty", + "Helpful", + "Helpless", + "Impartial", + "Impeccable", + "Imperfect", + "Imperturbable", + "Impish", + "Impolite", + "Important", + "Impossible", + "Impractical", + "Impressionable", + "Impressive", + "Improbable", + "Joint", + "Jolly", + "Jovial", + "Kindhearted", + "Kindly", + "Lighthearted", + "Likable", + "Likely", + "Limited", + "Limp", + "Limping", + "Linear", + "Lined", + "Liquid", + "Medium", + "Meek", + "Mellow", + "Melodic", + "Memorable", + "Menacing", + "Merry", + "Messy", + "Metallic", + "Mild", + "Negative", + "Neglected", + "Negligible", + "Neighboring", + "Nervous", + "New", + "Oldfashioned", + "Only", + "Open", + "Optimal", + "Optimistic", + "Opulent", + "Plaintive", + "Plastic", + "Playful", + "Pleasant", + "Pleased", + "Pleasing", + "Plump", + "Plush", + "Pointed", + "Pointless", + "Poised", + "Polished", + "Polite", + "Political", + "Queasy", + "Querulous", + "Reliable", + "Relieved", + "Remarkable", + "Remorseful", + "Remote", + "Repentant", + "Required", + "Respectful", + "Responsible", + "Silly", + "Silver", + "Similar", + "Simple", + "Simplistic", + "Sinful", + "Single", + "Sizzling", + "Skeletal", + "Skinny", + "Sleepy", + "Slight", + "Slim", + "Slimy", + "Slippery", + "Slow", + "Slushy", + "Small", + "Smart", + "Smoggy", + "Smooth", + "Smug", + "Snappy", + "Snarling", + "Sneaky", + "Sniveling", + "Snoopy", + "Thick", + "Thin", + "Third", + "Thirsty", + "This", + "Thorny", + "Thorough", + "Those", + "Thoughtful", + "Threadbare", + "United", + "Unkempt", + "Unknown", + "Unlawful", + "Unlined", + "Unlucky", + "Unnatural", + "Unpleasant", + "Unrealistic", + "Venerated", + "Vengeful", + "Verifiable", + "Vibrant", + "Vicious", + "Wellgroomed", + "Wellinformed", + "Welllit", + "Wellmade", + "Welloff", + "Welltodo", + "Wellworn", + "Wet", + "Which", + "Whimsical", + "Whirlwind", + "Whispered", + "Yellowish", + "Zesty", + "Amazing", + "Ambitious", + "Ample", + "Amused", + "Amusing", + "Anchored", + "Ancient", + "Angelic", + "Angry", + "Anguished", + "Animated", + "Annual", + "Another", + "Antique", + "Bogus", + "Boiling", + "Bold", + "Bony", + "Boring", + "Bossy", + "Both", + "Bouncy", + "Bountiful", + "Bowed", + "Complex", + "Complicated", + "Composed", + "Concerned", + "Concrete", + "Confused", + "Conscious", + "Considerate", + "Constant", + "Content", + "Conventional", + "Cooked", + "Cool", + "Cooperative", + "Difficult", + "Digital", + "Diligent", + "Dim", + "Dimpled", + "Dimwitted", + "Direct", + "Disastrous", + "Discrete", + "Disfigured", + "Disgusting", + "Disloyal", + "Dismal", + "Enraged", + "Entire", + "Envious", + "Equal", + "Equatorial", + "Essential", + "Esteemed", + "Ethical", + "Euphoric", + "Flimsy", + "Flippant", + "Flowery", + "Fluffy", + "Fluid", + "Flustered", + "Focused", + "Fond", + "Foolhardy", + "Foolish", + "Forceful", + "Forked", + "Formal", + "Forsaken", + "Gracious", + "Grand", + "Grandiose", + "Granular", + "Grateful", + "Grave", + "Gray", + "Great", + "Greedy", + "Green", + "Hidden", + "Hideous", + "High", + "Highlevel", + "Hilarious", + "Hoarse", + "Hollow", + "Homely", + "Impure", + "Inborn", + "Incomparable", + "Incompatible", + "Incomplete", + "Inconsequential", + "Incredible", + "Indelible", + "Indolent", + "Inexperienced", + "Infamous", + "Infantile", + "Joyful", + "Joyous", + "Jubilant", + "Klutzy", + "Knobby", + "Little", + "Live", + "Lively", + "Livid", + "Loathsome", + "Lone", + "Lonely", + "Long", + "Milky", + "Mindless", + "Miniature", + "Minor", + "Minty", + "Miserable", + "Miserly", + "Misguided", + "Misty", + "Mixed", + "Next", + "Nice", + "Nifty", + "Nimble", + "Nippy", + "Orange", + "Orderly", + "Ordinary", + "Organic", + "Ornate", + "Ornery", + "Poor", + "Popular", + "Portly", + "Posh", + "Positive", + "Possible", + "Potable", + "Powerful", + "Powerless", + "Practical", + "Precious", + "Present", + "Prestigious", + "Questionable", + "Quick", + "Repulsive", + "Revolving", + "Rewarding", + "Rich", + "Right", + "Rigid", + "Ringed", + "Ripe", + "Sociable", + "Soft", + "Soggy", + "Solid", + "Somber", + "Some", + "Sophisticated", + "Sore", + "Sorrowful", + "Soulful", + "Soupy", + "Sour", + "Spanish", + "Sparkling", + "Sparse", + "Specific", + "Spectacular", + "Speedy", + "Spherical", + "Spicy", + "Spiffy", + "Spirited", + "Spiteful", + "Splendid", + "Spotless", + "Spotted", + "Spry", + "Thrifty", + "Thunderous", + "Tidy", + "Tight", + "Timely", + "Tinted", + "Tiny", + "Tired", + "Torn", + "Total", + "Unripe", + "Unruly", + "Unselfish", + "Unsightly", + "Unsteady", + "Unsung", + "Untidy", + "Untimely", + "Untried", + "Victorious", + "Vigilant", + "Vigorous", + "Villainous", + "Violet", + "White", + "Whole", + "Whopping", + "Wicked", + "Wide", + "Wideeyed", + "Wiggly", + "Wild", + "Willing", + "Wilted", + "Winding", + "Windy", + "Young", + "Zigzag", + "Anxious", + "Any", + "Apprehensive", + "Appropriate", + "Apt", + "Arctic", + "Arid", + "Aromatic", + "Artistic", + "Ashamed", + "Assured", + "Astonishing", + "Athletic", + "Brave", + "Breakable", + "Brief", + "Bright", + "Brilliant", + "Brisk", + "Broken", + "Bronze", + "Brown", + "Bruised", + "Coordinated", + "Corny", + "Corrupt", + "Costly", + "Courageous", + "Courteous", + "Crafty", + "Crazy", + "Creamy", + "Creative", + "Creepy", + "Criminal", + "Crisp", + "Dirty", + "Disguised", + "Dishonest", + "Dismal", + "Distant", + "Distant", + "Distinct", + "Distorted", + "Dizzy", + "Dopey", + "Downright", + "Dreary", + "Even", + "Evergreen", + "Everlasting", + "Every", + "Evil", + "Exalted", + "Excellent", + "Excitable", + "Exemplary", + "Exhausted", + "Forthright", + "Fortunate", + "Fragrant", + "Frail", + "Frank", + "Frayed", + "Free", + "French", + "Frequent", + "Fresh", + "Friendly", + "Frightened", + "Frightening", + "Frigid", + "Gregarious", + "Grim", + "Grimy", + "Gripping", + "Grizzled", + "Gross", + "Grotesque", + "Grouchy", + "Grounded", + "Honest", + "Honorable", + "Honored", + "Hopeful", + "Horrible", + "Hospitable", + "Hot", + "Huge", + "Infatuated", + "Inferior", + "Infinite", + "Informal", + "Innocent", + "Insecure", + "Insidious", + "Insignificant", + "Insistent", + "Instructive", + "Insubstantial", + "Judicious", + "Juicy", + "Jumbo", + "Knotty", + "Knowing", + "Knowledgeable", + "Longterm", + "Loose", + "Lopsided", + "Lost", + "Loud", + "Lovable", + "Lovely", + "Loving", + "Modern", + "Modest", + "Moist", + "Monstrous", + "Monthly", + "Monumental", + "Moral", + "Mortified", + "Motherly", + "Motionless", + "Nocturnal", + "Noisy", + "Nonstop", + "Normal", + "Notable", + "Noted", + "Original", + "Other", + "Our", + "Outgoing", + "Outlandish", + "Outlying", + "Precious", + "Pretty", + "Previous", + "Pricey", + "Prickly", + "Primary", + "Prime", + "Pristine", + "Private", + "Prize", + "Probable", + "Productive", + "Profitable", + "Quickwitted", + "Quiet", + "Quintessential", + "Roasted", + "Robust", + "Rosy", + "Rotating", + "Rotten", + "Rough", + "Round", + "Rowdy", + "Square", + "Squeaky", + "Squiggly", + "Stable", + "Staid", + "Stained", + "Stale", + "Standard", + "Starchy", + "Stark", + "Starry", + "Steel", + "Steep", + "Sticky", + "Stiff", + "Stimulating", + "Stingy", + "Stormy", + "Straight", + "Strange", + "Strict", + "Strident", + "Striking", + "Striped", + "Strong", + "Studious", + "Stunning", + "Tough", + "Tragic", + "Trained", + "Traumatic", + "Treasured", + "Tremendous", + "Tremendous", + "Triangular", + "Tricky", + "Trifling", + "Trim", + "Untrue", + "Unused", + "Unusual", + "Unwelcome", + "Unwieldy", + "Unwilling", + "Unwitting", + "Unwritten", + "Upbeat", + "Violent", + "Virtual", + "Virtuous", + "Visible", + "Winged", + "Wiry", + "Wise", + "Witty", + "Wobbly", + "Woeful", + "Wonderful", + "Wooden", + "Woozy", + "Wordy", + "Worldly", + "Worn", + "Youthful", + "Attached", + "Attentive", + "Attractive", + "Austere", + "Authentic", + "Authorized", + "Automatic", + "Avaricious", + "Average", + "Aware", + "Awesome", + "Awful", + "Awkward", + "Bubbly", + "Bulky", + "Bumpy", + "Buoyant", + "Burdensome", + "Burly", + "Bustling", + "Busy", + "Buttery", + "Buzzing", + "Critical", + "Crooked", + "Crowded", + "Cruel", + "Crushing", + "Cuddly", + "Cultivated", + "Cultured", + "Cumbersome", + "Curly", + "Curvy", + "Cute", + "Cylindrical", + "Doting", + "Double", + "Downright", + "Drab", + "Drafty", + "Dramatic", + "Dreary", + "Droopy", + "Dry", + "Dual", + "Dull", + "Dutiful", + "Excited", + "Exciting", + "Exotic", + "Expensive", + "Experienced", + "Expert", + "Extralarge", + "Extraneous", + "Extrasmall", + "Extroverted", + "Frilly", + "Frivolous", + "Frizzy", + "Front", + "Frosty", + "Frozen", + "Frugal", + "Fruitful", + "Full", + "Fumbling", + "Functional", + "Funny", + "Fussy", + "Fuzzy", + "Growing", + "Growling", + "Grown", + "Grubby", + "Gruesome", + "Grumpy", + "Guilty", + "Gullible", + "Gummy", + "Humble", + "Humiliating", + "Humming", + "Humongous", + "Hungry", + "Hurtful", + "Husky", + "Intelligent", + "Intent", + "Intentional", + "Interesting", + "Internal", + "International", + "Intrepid", + "Ironclad", + "Irresponsible", + "Irritating", + "Itchy", + "Jumpy", + "Junior", + "Juvenile", + "Known", + "Kooky", + "Kosher", + "Low", + "Loyal", + "Lucky", + "Lumbering", + "Luminous", + "Lumpy", + "Lustrous", + "Luxurious", + "Mountainous", + "Muddy", + "Muffled", + "Multicolored", + "Mundane", + "Murky", + "Mushy", + "Musty", + "Muted", + "Mysterious", + "Noteworthy", + "Novel", + "Noxious", + "Numb", + "Nutritious", + "Nutty", + "Onerlooked", + "Outrageous", + "Outstanding", + "Oval", + "Overcooked", + "Overdue", + "Overjoyed", + "Profuse", + "Proper", + "Proud", + "Prudent", + "Punctual", + "Pungent", + "Puny", + "Pure", + "Purple", + "Pushy", + "Putrid", + "Puzzled", + "Puzzling", + "Quirky", + "Quixotic", + "Quizzical", + "Royal", + "Rubbery", + "Ruddy", + "Rude", + "Rundown", + "Runny", + "Rural", + "Rusty", + "Stupendous", + "Stupid", + "Sturdy", + "Stylish", + "Subdued", + "Submissive", + "Substantial", + "Subtle", + "Suburban", + "Sudden", + "Sugary", + "Sunny", + "Super", + "Superb", + "Superficial", + "Superior", + "Supportive", + "Surefooted", + "Surprised", + "Suspicious", + "Svelte", + "Sweaty", + "Sweet", + "Sweltering", + "Swift", + "Sympathetic", + "Trivial", + "Troubled", + "Trusting", + "Trustworthy", + "Trusty", + "Truthful", + "Tubby", + "Turbulent", + "Twin", + "Upright", + "Upset", + "Urban", + "Usable", + "Used", + "Useful", + "Useless", + "Utilized", + "Utter", + "Vital", + "Vivacious", + "Vivid", + "Voluminous", + "Worried", + "Worrisome", + "Worse", + "Worst", + "Worthless", + "Worthwhile", + "Worthy", + "Wrathful", + "Wretched", + "Writhing", + "Wrong", + "Wry", + "Yummy", + "True", + "Aliceblue", + "Antiquewhite", + "Aqua", + "Aquamarine", + "Azure", + "Beige", + "Bisque", + "Black", + "Blanchedalmond", + "Blue", + "Blueviolet", + "Brown", + "Burlywood", + "Cadetblue", + "Chartreuse", + "Chocolate", + "Coral", + "Cornflowerblue", + "Cornsilk", + "Crimson", + "Cyan", + "Darkblue", + "Darkcyan", + "Darkgoldenrod", + "Darkgray", + "Darkgreen", + "Darkgrey", + "Darkkhaki", + "Darkmagenta", + "Darkolivegreen", + "Darkorange", + "Darkorchid", + "Darkred", + "Darksalmon", + "Darkseagreen", + "Darkslateblue", + "Darkslategray", + "Darkslategrey", + "Darkturquoise", + "Darkviolet", + "Deeppink", + "Deepskyblue", + "Dimgray", + "Dimgrey", + "Dodgerblue", + "Firebrick", + "Floralwhite", + "Forestgreen", + "Fractal", + "Fuchsia", + "Gainsboro", + "Ghostwhite", + "Gold", + "Goldenrod", + "Gray", + "Green", + "Greenyellow", + "Honeydew", + "Hotpink", + "Indianred", + "Indigo", + "Ivory", + "Khaki", + "Lavender", + "Lavenderblush", + "Lawngreen", + "Lemonchiffon", + "Lightblue", + "Lightcoral", + "Lightcyan", + "Lightgoldenrod", + "Lightgoldenrodyellow", + "Lightgray", + "Lightgreen", + "Lightgrey", + "Lightpink", + "Lightsalmon", + "Lightseagreen", + "Lightskyblue", + "Lightslateblue", + "Lightslategray", + "Lightsteelblue", + "Lightyellow", + "Lime", + "Limegreen", + "Linen", + "Magenta", + "Maroon", + "Mediumaquamarine", + "Mediumblue", + "Mediumforestgreen", + "Mediumgoldenrod", + "Mediumorchid", + "Mediumpurple", + "Mediumseagreen", + "Mediumslateblue", + "Mediumspringgreen", + "Mediumturquoise", + "Mediumvioletred", + "Midnightblue", + "Mintcream", + "Mistyrose", + "Moccasin", + "Navajowhite", + "Navy", + "Navyblue", + "Oldlace", + "Olive", + "Olivedrab", + "Opaque", + "Orange", + "Orangered", + "Orchid", + "Palegoldenrod", + "Palegreen", + "Paleturquoise", + "Palevioletred", + "Papayawhip", + "Peachpuff", + "Peru", + "Pink", + "Plum", + "Powderblue", + "Purple", + "Red", + "Rosybrown", + "Royalblue", + "Saddlebrown", + "Salmon", + "Sandybrown", + "Seagreen", + "Seashell", + "Sienna", + "Silver", + "Skyblue", + "Slateblue", + "Slategray", + "Slategrey", + "Snow", + "Springgreen", + "Steelblue", + "Tan", + "Teal", + "Thistle", + "Tomato", + "Transparent", + "Turquoise", + "Violet", + "Violetred", + "Wheat", + "White", + "Whitesmoke", + "Yellow", + "Yellowgreen" + }; + + public static string[] Verbs => new[] + { + "Accept", + "Add", + "Admire", + "Admit", + "Advise", + "Afford", + "Agree", + "Alert", + "Allow", + "Amuse", + "Analyse", + "Announce", + "Annoy", + "Answer", + "Apologise", + "Appear", + "Applaud", + "Appreciate", + "Approve", + "Argue", + "Arrange", + "Arrest", + "Arrive", + "Ask", + "Attach", + "Attack", + "Attempt", + "Attend", + "Attract", + "Avoid", + "Back", + "Bake", + "Balance", + "Ban", + "Bang", + "Bare", + "Bat", + "Bathe", + "Battle", + "Beam", + "Beg", + "Behave", + "Belong", + "Bleach", + "Bless", + "Blind", + "Blink", + "Blot", + "Blush", + "Boast", + "Boil", + "Bolt", + "Bomb", + "Book", + "Bore", + "Borrow", + "Bounce", + "Bow", + "Box", + "Brake", + "Branch", + "Breathe", + "Bruise", + "Brush", + "Bubble", + "Bump", + "Burn", + "Bury", + "Buzz", + "Calculate", + "Call", + "Camp", + "Care", + "Carry", + "Carve", + "Cause", + "Challenge", + "Change", + "Charge", + "Chase", + "Cheat", + "Check", + "Cheer", + "Chew", + "Choke", + "Chop", + "Claim", + "Clap", + "Clean", + "Clear", + "Clip", + "Close", + "Coach", + "Coil", + "Collect", + "Colour", + "Comb", + "Command", + "Communicate", + "Compare", + "Compete", + "Complain", + "Complete", + "Concentrate", + "Concern", + "Confess", + "Confuse", + "Connect", + "Consider", + "Consist", + "Contain", + "Continue", + "Copy", + "Correct", + "Cough", + "Count", + "Cover", + "Crack", + "Crash", + "Crawl", + "Cross", + "Crush", + "Cry", + "Cure", + "Curl", + "Curve", + "Cycle", + "Dam", + "Damage", + "Dance", + "Dare", + "Decay", + "Deceive", + "Decide", + "Decorate", + "Delay", + "Delight", + "Deliver", + "Depend", + "Describe", + "Desert", + "Deserve", + "Destroy", + "Detect", + "Develop", + "Disagree", + "Disappear", + "Disapprove", + "Disarm", + "Discover", + "Dislike", + "Divide", + "Double", + "Doubt", + "Drag", + "Drain", + "Dream", + "Dress", + "Drip", + "Drop", + "Drown", + "Drum", + "Dry", + "Dust", + "Earn", + "Educate", + "Embarrass", + "Employ", + "Empty", + "Encourage", + "End", + "Enjoy", + "Enter", + "Entertain", + "Escape", + "Examine", + "Excite", + "Excuse", + "Exercise", + "Exist", + "Expand", + "Expect", + "Explain", + "Explode", + "Extend", + "Face", + "Fade", + "Fail", + "Fancy", + "Fasten", + "Fax", + "Fear", + "Fence", + "Fetch", + "File", + "Fill", + "Film", + "Fire", + "Fit", + "Fix", + "Flap", + "Flash", + "Float", + "Flood", + "Flow", + "Flower", + "Fold", + "Follow", + "Fool", + "Force", + "Form", + "Found", + "Frame", + "Frighten", + "Fry", + "Gather", + "Gaze", + "Glow", + "Glue", + "Grab", + "Grate", + "Grease", + "Greet", + "Grin", + "Grip", + "Groan", + "Guarantee", + "Guard", + "Guess", + "Guide", + "Hammer", + "Hand", + "Handle", + "Hang", + "Happen", + "Harass", + "Harm", + "Hate", + "Haunt", + "Head", + "Heal", + "Heap", + "Heat", + "Help", + "Hook", + "Hop", + "Hope", + "Hover", + "Hug", + "Hum", + "Hunt", + "Hurry", + "Identify", + "Ignore", + "Imagine", + "Impress", + "Improve", + "Include", + "Increase", + "Influence", + "Inform", + "Inject", + "Injure", + "Instruct", + "Intend", + "Interest", + "Interfere", + "Interrupt", + "Introduce", + "Invent", + "Invite", + "Irritate", + "Itch", + "Jail", + "Jam", + "Jog", + "Join", + "Joke", + "Judge", + "Juggle", + "Jump", + "Kick", + "Kill", + "Kiss", + "Kneel", + "Knit", + "Knock", + "Knot", + "Label", + "Land", + "Last", + "Laugh", + "Launch", + "Learn", + "Level", + "License", + "Lick", + "Lie", + "Lighten", + "Like", + "List", + "Listen", + "Live", + "Load", + "Lock", + "Long", + "Look", + "Love", + "Man", + "Manage", + "March", + "Mark", + "Marry", + "Match", + "Mate", + "Matter", + "Measure", + "Meddle", + "Melt", + "Memorise", + "Mend", + "MessUp", + "Milk", + "Mine", + "Miss", + "Mix", + "Moan", + "Moor", + "Mourn", + "Move", + "Muddle", + "Mug", + "Multiply", + "Murder", + "Nail", + "Name", + "Need", + "Nest", + "Nod", + "Note", + "Notice", + "Number", + "Obey", + "Object", + "Observe", + "Obtain", + "Occur", + "Offend", + "Offer", + "Open", + "Order", + "Overflow", + "Owe", + "Own", + "Pack", + "Paddle", + "Paint", + "Park", + "Part", + "Pass", + "Paste", + "Pat", + "Pause", + "Peck", + "Pedal", + "Peel", + "Peep", + "Perform", + "Permit", + "Phone", + "Pick", + "Pinch", + "Pine", + "Place", + "Plan", + "Plant", + "Play", + "Please", + "Plug", + "Point", + "Poke", + "Polish", + "Pop", + "Possess", + "Post", + "Pour", + "Practise", + "Pray", + "Preach", + "Precede", + "Prefer", + "Prepare", + "Present", + "Preserve", + "Press", + "Pretend", + "Prevent", + "Prick", + "Print", + "Produce", + "Program", + "Promise", + "Protect", + "Provide", + "Pull", + "Pump", + "Punch", + "Puncture", + "Punish", + "Push", + "Question", + "Queue", + "Race", + "Radiate", + "Rain", + "Raise", + "Reach", + "Realise", + "Receive", + "Recognise", + "Record", + "Reduce", + "Reflect", + "Refuse", + "Regret", + "Reign", + "Reject", + "Rejoice", + "Relax", + "Release", + "Rely", + "Remain", + "Remember", + "Remind", + "Remove", + "Repair", + "Repeat", + "Replace", + "Reply", + "Report", + "Reproduce", + "Request", + "Rescue", + "Retire", + "Return", + "Rhyme", + "Rinse", + "Risk", + "Rob", + "Rock", + "Roll", + "Rot", + "Rub", + "Ruin", + "Rule", + "Rush", + "Sack", + "Sail", + "Satisfy", + "Save", + "Saw", + "Scare", + "Scatter", + "Scold", + "Scorch", + "Scrape", + "Scratch", + "Scream", + "Screw", + "Scribble", + "Scrub", + "Seal", + "Search", + "Separate", + "Serve", + "Settle", + "Shade", + "Share", + "Shave", + "Shelter", + "Shiver", + "Shock", + "Shop", + "Shrug", + "Sigh", + "Sign", + "Signal", + "Sin", + "Sip", + "Ski", + "Skip", + "Slap", + "Slip", + "Slow", + "Smash", + "Smell", + "Smile", + "Smoke", + "Snatch", + "Sneeze", + "Sniff", + "Snore", + "Snow", + "Soak", + "Soothe", + "Sound", + "Spare", + "Spark", + "Sparkle", + "Spell", + "Spill", + "Spoil", + "Spot", + "Spray", + "Sprout", + "Squash", + "Squeak", + "Squeal", + "Squeeze", + "Stain", + "Stamp", + "Stare", + "Start", + "Stay", + "Steer", + "Step", + "Stir", + "Stitch", + "Stop", + "Store", + "Strap", + "Strengthen", + "Stretch", + "Strip", + "Stroke", + "Stuff", + "Subtract", + "Succeed", + "Suck", + "Suffer", + "Suggest", + "Suit", + "Supply", + "Support", + "Suppose", + "Surprise", + "Surround", + "Suspect", + "Suspend", + "Switch", + "Talk", + "Tame", + "Tap", + "Taste", + "Tease", + "Telephone", + "Tempt", + "Terrify", + "Test", + "Thank", + "Thaw", + "Tick", + "Tickle", + "Tie", + "Time", + "Tip", + "Tire", + "Touch", + "Tour", + "Tow", + "Trace", + "Trade", + "Train", + "Transport", + "Trap", + "Travel", + "Treat", + "Tremble", + "Trick", + "Trip", + "Trot", + "Trouble", + "Trust", + "Try", + "Tug", + "Tumble", + "Turn", + "Twist", + "Type", + "Undress", + "Unfasten", + "Unite", + "Unlock", + "Unpack", + "Untidy", + "Use", + "Vanish", + "Visit", + "Wail", + "Wait", + "Walk", + "Wander", + "Want", + "Warm", + "Warn", + "Wash", + "Waste", + "Watch", + "Water", + "Wave", + "Weigh", + "Welcome", + "Whine", + "Whip", + "Whirl", + "Whisper", + "Whistle", + "Wink", + "Wipe", + "Wish", + "Wobble", + "Wonder", + "Work", + "Worry", + "Wrap", + "Wreck", + "Wrestle", + "Wriggle", + "X-Ray", + "Yawn", + "Yell", + "Zip", + "Zoom" + }; + + public static string[] Animals => new[] + { + "Aardvark", + "Aardwolf", + "Abalone", + "Abyssiniancat", + "Abyssiniangroundhornbill", + "Acaciarat", + "Achillestang", + "Acornbarnacle", + "Acornweevil", + "Acornwoodpecker", + "Acouchi", + "Adamsstaghornedbeetle", + "Addax", + "Adder", + "Adeliepenguin", + "Admiralbutterfly", + "Adouri", + "Aegeancat", + "Affenpinscher", + "Afghanhound", + "Africanaugurbuzzard", + "Africanbushviper", + "Africancivet", + "Africanclawedfrog", + "Africanelephant", + "Africanfisheagle", + "Africangoldencat", + "Africangroundhornbill", + "Africanharrierhawk", + "Africanhornbill", + "Africanjacana", + "Africanmolesnake", + "Africanparadiseflycatcher", + "Africanpiedkingfisher", + "Africanporcupine", + "Africanrockpython", + "Africanwildcat", + "Africanwilddog", + "Agama", + "Agouti", + "Aidi", + "Airedale", + "Airedaleterrier", + "Akitainu", + "Alabamamapturtle", + "Alaskajingle", + "Alaskanhusky", + "Alaskankleekai", + "Alaskanmalamute", + "Albacoretuna", + "Albatross", + "Albertosaurus", + "Albino", + "Aldabratortoise", + "Allensbigearedbat", + "Alleycat", + "Alligator", + "Alligatorgar", + "Alligatorsnappingturtle", + "Allosaurus", + "Alpaca", + "Alpinegoat", + "Alpineroadguidetigerbeetle", + "Altiplanochinchillamouse", + "Amazondolphin", + "Amazonparrot", + "Amazontreeboa", + "Amberpenshell", + "Ambushbug", + "Americanalligator", + "Americanavocet", + "Americanbadger", + "Americanbittern", + "Americanblackvulture", + "Americanbobtail", + "Americanbulldog", + "Americancicada", + "Americancrayfish", + "Americancreamdraft", + "Americancrocodile", + "Americancrow", + "Americancurl", + "Americangoldfinch", + "Americanindianhorse", + "Americankestrel", + "Americanlobster", + "Americanmarten", + "Americanpainthorse", + "Americanquarterhorse", + "Americanratsnake", + "Americanredsquirrel", + "Americanriverotter", + "Americanrobin", + "Americansaddlebred", + "Americanshorthair", + "Americantoad", + "Americanwarmblood", + "Americanwigeon", + "Americanwirehair", + "Amethystgemclam", + "Amethystinepython", + "Amethystsunbird", + "Ammonite", + "Amoeba", + "Amphibian", + "Amphiuma", + "Amurminnow", + "Amurratsnake", + "Amurstarfish", + "Anaconda", + "Anchovy", + "Andalusianhorse", + "Andeancat", + "Andeancockoftherock", + "Andeancondor", + "Anemone", + "Anemonecrab", + "Anemoneshrimp", + "Angelfish", + "Angelwingmussel", + "Anglerfish", + "Angora", + "Angwantibo", + "Anhinga", + "Ankole", + "Ankolewatusi", + "Annashummingbird", + "Annelid", + "Annelida", + "Anole", + "Anophelesmosquito", + "Ant", + "Antarcticfurseal", + "Antarcticgiantpetrel", + "Antbear", + "Anteater", + "Antelope", + "Antelopegroundsquirrel", + "Antipodesgreenparakeet", + "Antlion", + "Anura", + "Aoudad", + "Apatosaur", + "Ape", + "Aphid", + "Apisdorsatalaboriosa", + "Aplomadofalcon", + "Appaloosa", + "Aquaticleech", + "Arabianhorse", + "Arabianoryx", + "Arabianwildcat", + "Aracari", + "Arachnid", + "Arawana", + "Archaeocete", + "Archaeopteryx", + "Archerfish", + "Arcticduck", + "Arcticfox", + "Arctichare", + "Arcticseal", + "Arcticwolf", + "Argali", + "Argentinehornedfrog", + "Argentineruddyduck", + "Argusfish", + "Arieltoucan", + "Arizonaalligatorlizard", + "Arkshell", + "Armadillo", + "Armedcrab", + "Armednylonshrimp", + "Armyant", + "Armyworm", + "Arrowana", + "Arrowcrab", + "Arrowworm", + "Arthropods", + "Aruanas", + "Asianconstablebutterfly", + "Asiandamselfly", + "Asianelephant", + "Asianlion", + "Asianpiedstarling", + "Asianporcupine", + "Asiansmallclawedotter", + "Asiantrumpetfish", + "Asianwaterbuffalo", + "Asiaticgreaterfreshwaterclam", + "Asiaticlesserfreshwaterclam", + "Asiaticmouflon", + "Asiaticwildass", + "Asp", + "Ass", + "Assassinbug", + "Astarte", + "Astrangiacoral", + "Atlanticblackgoby", + "Atlanticbluetang", + "Atlanticridleyturtle", + "Atlanticsharpnosepuffer", + "Atlanticspadefish", + "Atlasmoth", + "Attwatersprairiechicken", + "Auk", + "Auklet", + "Aurochs", + "Australiancattledog", + "Australiancurlew", + "Australianfreshwatercrocodile", + "Australianfurseal", + "Australiankelpie", + "Australiankestrel", + "Australianshelduck", + "Australiansilkyterrier", + "Austrianpinscher", + "Avians", + "Avocet", + "Axisdeer", + "Axolotl", + "Ayeaye", + "Aztecant", + "Azurevase", + "Azurevasesponge", + "Azurewingedmagpie", + "Babirusa", + "Baboon", + "Backswimmer", + "Bactrian", + "Badger", + "Bagworm", + "Baiji", + "Baldeagle", + "Baleenwhale", + "Balloonfish", + "Ballpython", + "Bandicoot", + "Bangeltiger", + "Bantamrooster", + "Banteng", + "Barasinga", + "Barasingha", + "Barb", + "Barbet", + "Barebirdbat", + "Barnacle", + "Barnowl", + "Barnswallow", + "Barracuda", + "Basenji", + "Basil", + "Basilisk", + "Bass", + "Bassethound", + "Bat", + "Bats", + "Beagle", + "Bear", + "Beardedcollie", + "Beardeddragon", + "Beauceron", + "Beaver", + "Bedbug", + "Bedlingtonterrier", + "Bee", + "Beetle", + "Bellfrog", + "Bellsnake", + "Belugawhale", + "Bengaltiger", + "Bergerpicard", + "Bernesemountaindog", + "Betafish", + "Bettong", + "Bichonfrise", + "Bighorn", + "Bighornedsheep", + "Bighornsheep", + "Bigmouthbass", + "Bilby", + "Billygoat", + "Binturong", + "Bird", + "Birdofparadise", + "Bison", + "Bittern", + "Blackandtancoonhound", + "Blackbear", + "Blackbird", + "Blackbuck", + "Blackcrappie", + "Blackfish", + "Blackfly", + "Blackfootedferret", + "Blacklab", + "Blacklemur", + "Blackmamba", + "Blacknorwegianelkhound", + "Blackpanther", + "Blackrhino", + "Blackrussianterrier", + "Blackwidowspider", + "Blesbok", + "Blobfish", + "Blowfish", + "Blueandgoldmackaw", + "Bluebird", + "Bluebottle", + "Bluebottlejellyfish", + "Bluebreastedkookaburra", + "Bluefintuna", + "Bluefish", + "Bluegill", + "Bluejay", + "Bluemorphobutterfly", + "Blueshark", + "Bluet", + "Bluetickcoonhound", + "Bluetonguelizard", + "Bluewhale", + "Boa", + "Boaconstrictor", + "Boar", + "Bobcat", + "Bobolink", + "Bobwhite", + "Boilweevil", + "Bongo", + "Bonobo", + "Booby", + "Bordercollie", + "Borderterrier", + "Borer", + "Borzoi", + "Boto", + "Boubou", + "Boutu", + "Bovine", + "Brahmanbull", + "Brahmancow", + "Brant", + "Bream", + "Brocketdeer", + "Bronco", + "Brontosaurus", + "Brownbear", + "Brownbutterfly", + "Bubblefish", + "Buck", + "Buckeyebutterfly", + "Budgie", + "Bufeo", + "Buffalo", + "Bufflehead", + "Bug", + "Bull", + "Bullfrog", + "Bullmastiff", + "Bumblebee", + "Bunny", + "Bunting", + "Burro", + "Bushbaby", + "Bushsqueaker", + "Bustard", + "Butterfly", + "Buzzard", + "Caecilian", + "Caiman", + "Caimanlizard", + "Calf", + "Camel", + "Canadagoose", + "Canary", + "Canine", + "Canvasback", + "Capeghostfrog", + "Capybara", + "Caracal", + "Cardinal", + "Caribou", + "Carp", + "Carpenterant", + "Cassowary", + "Cat", + "Catbird", + "Caterpillar", + "Catfish", + "Cats", + "Cattle", + "Caudata", + "Cavy", + "Centipede", + "Cero", + "Chafer", + "Chameleon", + "Chamois", + "Chanticleer", + "Cheetah", + "Chevrotain", + "Chick", + "Chickadee", + "Chicken", + "Chihuahua", + "Chimneyswift", + "Chimpanzee", + "Chinchilla", + "Chinesecrocodilelizard", + "Chipmunk", + "Chital", + "Chrysalis", + "Chrysomelid", + "Chuckwalla", + "Chupacabra", + "Cicada", + "Cirriped", + "Civet", + "Clam", + "Cleanerwrasse", + "Clingfish", + "Clownanemonefish", + "Clumber", + "Coati", + "Cob", + "Cobra", + "Cock", + "Cockatiel", + "Cockatoo", + "Cockerspaniel", + "Cockroach", + "Cod", + "Coelacanth", + "Collardlizard", + "Collie", + "Colt", + "Comet", + "Commabutterfly", + "Commongonolek", + "Conch", + "Condor", + "Coney", + "Conure", + "Cony", + "Coot", + "Cooter", + "Copepod", + "Copperbutterfly", + "Copperhead", + "Coqui", + "Coral", + "Cormorant", + "Cornsnake", + "Corydorascatfish", + "Cottonmouth", + "Cottontail", + "Cougar", + "Cow", + "Cowbird", + "Cowrie", + "Coyote", + "Coypu", + "Crab", + "Crane", + "Cranefly", + "Crayfish", + "Creature", + "Cricket", + "Crocodile", + "Crocodileskink", + "Crossbill", + "Crow", + "Crownofthornsstarfish", + "Crustacean", + "Cub", + "Cuckoo", + "Cur", + "Curassow", + "Curlew", + "Cuscus", + "Cusimanse", + "Cuttlefish", + "Cutworm", + "Cygnet", + "Dachshund", + "Daddylonglegs", + "Dairycow", + "Dalmatian", + "Damselfly", + "Danishswedishfarmdog", + "Darklingbeetle", + "Dartfrog", + "Darwinsfox", + "Dassie", + "Dassierat", + "Davidstiger", + "Deer", + "Deermouse", + "Degu", + "Degus", + "Deinonychus", + "Desertpupfish", + "Devilfish", + "Deviltasmanian", + "Diamondbackrattlesnake", + "Dikdik", + "Dikkops", + "Dingo", + "Dinosaur", + "Diplodocus", + "Dipper", + "Discus", + "Dobermanpinscher", + "Doctorfish", + "Dodo", + "Dodobird", + "Doe", + "Dog", + "Dogfish", + "Dogwoodclubgall", + "Dogwoodtwigborer", + "Dolphin", + "Donkey", + "Dorado", + "Dore", + "Dorking", + "Dormouse", + "Dotterel", + "Douglasfirbarkbeetle", + "Dove", + "Dowitcher", + "Drafthorse", + "Dragon", + "Dragonfly", + "Drake", + "Drever", + "Dromaeosaur", + "Dromedary", + "Drongo", + "Duck", + "Duckbillcat", + "Duckbillplatypus", + "Duckling", + "Dugong", + "Duiker", + "Dungbeetle", + "Dungenesscrab", + "Dunlin", + "Dunnart", + "Dutchshepherddog", + "Dutchsmoushond", + "Dwarfmongoose", + "Dwarfrabbit", + "Eagle", + "Earthworm", + "Earwig", + "Easternglasslizard", + "Easternnewt", + "Easteuropeanshepherd", + "Eastrussiancoursinghounds", + "Eastsiberianlaika", + "Echidna", + "Eel", + "Eelelephant", + "Eeve", + "Eft", + "Egg", + "Egret", + "Eider", + "Eidolonhelvum", + "Ekaltadeta", + "Eland", + "Electriceel", + "Elephant", + "Elephantbeetle", + "Elephantseal", + "Elk", + "Elkhound", + "Elver", + "Emeraldtreeskink", + "Emperorpenguin", + "Emperorshrimp", + "Emu", + "Englishpointer", + "Englishsetter", + "Equestrian", + "Equine", + "Erin", + "Ermine", + "Erne", + "Eskimodog", + "Esok", + "Estuarinecrocodile", + "Ethiopianwolf", + "Europeanfiresalamander", + "Europeanpolecat", + "Ewe", + "Eyas", + "Eyelashpitviper", + "Eyra", + "Fairybluebird", + "Fairyfly", + "Falcon", + "Fallowdeer", + "Fantail", + "Fanworms", + "Fattaileddunnart", + "Fawn", + "Feline", + "Fennecfox", + "Ferret", + "Fiddlercrab", + "Fieldmouse", + "Fieldspaniel", + "Finch", + "Finnishspitz", + "Finwhale", + "Fireant", + "Firebelliedtoad", + "Firecrest", + "Firefly", + "Fish", + "Fishingcat", + "Flamingo", + "Flatcoatretriever", + "Flatfish", + "Flea", + "Flee", + "Flicker", + "Flickertailsquirrel", + "Flies", + "Flounder", + "Fluke", + "Fly", + "Flycatcher", + "Flyingfish", + "Flyingfox", + "Flyinglemur", + "Flyingsquirrel", + "Foal", + "Fossa", + "Fowl", + "Fox", + "Foxhound", + "Foxterrier", + "Frenchbulldog", + "Freshwatereel", + "Frigatebird", + "Frilledlizard", + "Frillneckedlizard", + "Fritillarybutterfly", + "Frog", + "Frogmouth", + "Fruitbat", + "Fruitfly", + "Fugu", + "Fulmar", + "Funnelweaverspider", + "Furseal", + "Gadwall", + "Galago", + "Galah", + "Galapagosalbatross", + "Galapagosdove", + "Galapagoshawk", + "Galapagosmockingbird", + "Galapagospenguin", + "Galapagossealion", + "Galapagostortoise", + "Gallinule", + "Gallowaycow", + "Gander", + "Gangesdolphin", + "Gannet", + "Gar", + "Gardensnake", + "Garpike", + "Gartersnake", + "Gaur", + "Gavial", + "Gazelle", + "Gecko", + "Geese", + "Gelada", + "Gelding", + "Gemsbok", + "Gemsbuck", + "Genet", + "Gentoopenguin", + "Gerbil", + "Gerenuk", + "Germanpinscher", + "Germanshepherd", + "Germanshorthairedpointer", + "Germanspaniel", + "Germanspitz", + "Germanwirehairedpointer", + "Gharial", + "Ghostshrimp", + "Giantschnauzer", + "Gibbon", + "Gilamonster", + "Giraffe", + "Glassfrog", + "Globefish", + "Glowworm", + "Gnat", + "Gnatcatcher", + "Gnu", + "Goa", + "Goat", + "Godwit", + "Goitered", + "Goldeneye", + "Goldenmantledgroundsquirrel", + "Goldenretriever", + "Goldfinch", + "Goldfish", + "Gonolek", + "Goose", + "Goosefish", + "Gopher", + "Goral", + "Gordonsetter", + "Gorilla", + "Goshawk", + "Gosling", + "Gossamerwingedbutterfly", + "Gourami", + "Grackle", + "Grasshopper", + "Grassspider", + "Grayfox", + "Grayling", + "Grayreefshark", + "Graysquirrel", + "Graywolf", + "Greatargus", + "Greatdane", + "Greathornedowl", + "Greatwhiteshark", + "Grebe", + "Greendarnerdragonfly", + "Greyhounddog", + "Grison", + "Grizzlybear", + "Grosbeak", + "Groundbeetle", + "Groundhog", + "Grouper", + "Grouse", + "Grub", + "Grunion", + "Guanaco", + "Guernseycow", + "Guillemot", + "Guineafowl", + "Guineapig", + "Gull", + "Guppy", + "Gypsymoth", + "Gyrfalcon", + "Hackee", + "Haddock", + "Hadrosaurus", + "Hagfish", + "Hairstreak", + "Hairstreakbutterfly", + "Hake", + "Halcyon", + "Halibut", + "Halicore", + "Hamadryad", + "Hamadryas", + "Hammerheadbird", + "Hammerheadshark", + "Hammerkop", + "Hamster", + "Hanumanmonkey", + "Hapuka", + "Hapuku", + "Harborporpoise", + "Harborseal", + "Hare", + "Harlequinbug", + "Harpseal", + "Harpyeagle", + "Harrier", + "Harrierhawk", + "Hart", + "Hartebeest", + "Harvestmen", + "Harvestmouse", + "Hatchetfish", + "Hawaiianmonkseal", + "Hawk", + "Hectorsdolphin", + "Hedgehog", + "Heifer", + "Hellbender", + "Hen", + "Herald", + "Herculesbeetle", + "Hermitcrab", + "Heron", + "Herring", + "Heterodontosaurus", + "Hind", + "Hippopotamus", + "Hoatzin", + "Hochstettersfrog", + "Hog", + "Hogget", + "Hoiho", + "Hoki", + "Homalocephale", + "Honeybadger", + "Honeybee", + "Honeycreeper", + "Honeyeater", + "Hookersealion", + "Hoopoe", + "Hornbill", + "Hornedtoad", + "Hornedviper", + "Hornet", + "Hornshark", + "Horse", + "Horsechestnutleafminer", + "Horsefly", + "Horsemouse", + "Horseshoebat", + "Horseshoecrab", + "Hound", + "Housefly", + "Hoverfly", + "Howlermonkey", + "Huemul", + "Huia", + "Human", + "Hummingbird", + "Humpbackwhale", + "Husky", + "Hydatidtapeworm", + "Hydra", + "Hyena", + "Hylaeosaurus", + "Hypacrosaurus", + "Hypsilophodon", + "Hyracotherium", + "Hyrax", + "Iaerismetalmark", + "Ibadanmalimbe", + "Iberianbarbel", + "Iberianchiffchaff", + "Iberianemeraldlizard", + "Iberianlynx", + "Iberianmidwifetoad", + "Iberianmole", + "Iberiannase", + "Ibex", + "Ibis", + "Ibisbill", + "Ibizanhound", + "Iceblueredtopzebra", + "Icefish", + "Icelandgull", + "Icelandichorse", + "Icelandicsheepdog", + "Ichidna", + "Ichneumonfly", + "Ichthyosaurs", + "Ichthyostega", + "Icterinewarbler", + "Iggypops", + "Iguana", + "Iguanodon", + "Illadopsis", + "Ilsamochadegu", + "Imago", + "Impala", + "Imperatorangel", + "Imperialeagle", + "Incatern", + "Inchworm", + "Indianabat", + "Indiancow", + "Indianelephant", + "Indianglassfish", + "Indianhare", + "Indianjackal", + "Indianpalmsquirrel", + "Indianpangolin", + "Indianrhinoceros", + "Indianringneckparakeet", + "Indianrockpython", + "Indianskimmer", + "Indianspinyloach", + "Indigobunting", + "Indigowingedparrot", + "Indochinahogdeer", + "Indochinesetiger", + "Indri", + "Indusriverdolphin", + "Inexpectatumpleco", + "Inganue", + "Insect", + "Intermediateegret", + "Invisiblerail", + "Iraniangroundjay", + "Iridescentshark", + "Iriomotecat", + "Irishdraughthorse", + "Irishredandwhitesetter", + "Irishsetter", + "Irishterrier", + "Irishwaterspaniel", + "Irishwolfhound", + "Irrawaddydolphin", + "Irukandjijellyfish", + "Isabellineshrike", + "Isabellinewheatear", + "Islandcanary", + "Islandwhistler", + "Isopod", + "Italianbrownbear", + "Italiangreyhound", + "Ivorybackedwoodswallow", + "Ivorybilledwoodpecker", + "Ivorygull", + "Izuthrush", + "Jabiru", + "Jackal", + "Jackrabbit", + "Jaeger", + "Jaguar", + "Jaguarundi", + "Janenschia", + "Japanesebeetle", + "Javalina", + "Jay", + "Jellyfish", + "Jenny", + "Jerboa", + "Joey", + "Johndory", + "Juliabutterfly", + "Jumpingbean", + "Junco", + "Junebug", + "Kagu", + "Kakapo", + "Kakarikis", + "Kangaroo", + "Karakul", + "Katydid", + "Kawala", + "Kentrosaurus", + "Kestrel", + "Kid", + "Killdeer", + "Killerwhale", + "Killifish", + "Kingbird", + "Kingfisher", + "Kinglet", + "Kingsnake", + "Kinkajou", + "Kiskadee", + "Kissingbug", + "Kite", + "Kitfox", + "Kitten", + "Kittiwake", + "Kitty", + "Kiwi", + "Koala", + "Koalabear", + "Kob", + "Kodiakbear", + "Koi", + "Komododragon", + "Koodoo", + "Kookaburra", + "Kouprey", + "Krill", + "Kronosaurus", + "Kudu", + "Kusimanse", + "Labradorretriever", + "Lacewing", + "Ladybird", + "Ladybug", + "Lamb", + "Lamprey", + "Langur", + "Lark", + "Larva", + "Laughingthrush", + "Lcont", + "Leafbird", + "Leafcutterant", + "Leafhopper", + "Leafwing", + "Leech", + "Lemming", + "Lemur", + "Leonberger", + "Leopard", + "Leopardseal", + "Leveret", + "Lhasaapso", + "Lice", + "Liger", + "Lightningbug", + "Limpet", + "Limpkin", + "Ling", + "Lion", + "Lionfish", + "Littlenightmonkeys", + "Lizard", + "Llama", + "Lobo", + "Lobster", + "Locust", + "Loggerheadturtle", + "Longhorn", + "Longhornbeetle", + "Longspur", + "Loon", + "Lorikeet", + "Loris", + "Louse", + "Lovebird", + "Lowchen", + "Lunamoth", + "Lungfish", + "Lynx", + "Macaque", + "Macaw", + "Macropod", + "Madagascarhissingroach", + "Maggot", + "Magpie", + "Maiasaura", + "Majungatholus", + "Malamute", + "Mallard", + "Maltesedog", + "Mamba", + "Mamenchisaurus", + "Mammal", + "Mammoth", + "Manatee", + "Mandrill", + "Mangabey", + "Manta", + "Mantaray", + "Mantid", + "Mantis", + "Mantisray", + "Manxcat", + "Mara", + "Marabou", + "Marbledmurrelet", + "Mare", + "Marlin", + "Marmoset", + "Marmot", + "Marten", + "Martin", + "Massasauga", + "Massospondylus", + "Mastiff", + "Mastodon", + "Mayfly", + "Meadowhawk", + "Meadowlark", + "Mealworm", + "Meerkat", + "Megalosaurus", + "Megalotomusquinquespinosus", + "Megaraptor", + "Merganser", + "Merlin", + "Metalmarkbutterfly", + "Metamorphosis", + "Mice", + "Microvenator", + "Midge", + "Milksnake", + "Milkweedbug", + "Millipede", + "Minibeast", + "Mink", + "Minnow", + "Mite", + "Moa", + "Mockingbird", + "Mole", + "Mollies", + "Mollusk", + "Molly", + "Monarch", + "Mongoose", + "Mongrel", + "Monkey", + "Monkfish", + "Monoclonius", + "Montanoceratops", + "Moorhen", + "Moose", + "Moray", + "Morayeel", + "Morpho", + "Mosasaur", + "Mosquito", + "Moth", + "Motmot", + "Mouflon", + "Mountaincat", + "Mountainlion", + "Mouse", + "Mouse/Mice", + "Mousebird", + "Mudpuppy", + "Mule", + "Mullet", + "Muntjac", + "Murrelet", + "Muskox", + "Muskrat", + "Mussaurus", + "Mussel", + "Mustang", + "Mutt", + "Myna", + "Mynah", + "Myotis", + "Nabarlek", + "Nag", + "Naga", + "Nagapies", + "Nakedmolerat", + "Nandine", + "Nandoo", + "Nandu", + "Narwhal", + "Narwhale", + "Natterjacktoad", + "Nauplius", + "Nautilus", + "Needlefish", + "Needletail", + "Nematode", + "Nene", + "Neonblueguppy", + "Neonbluehermitcrab", + "Neondwarfgourami", + "Neonrainbowfish", + "Neonredguppy", + "Neontetra", + "Nerka", + "Nettlefish", + "Newfoundlanddog", + "Newt", + "Newtnutria", + "Nightcrawler", + "Nighthawk", + "Nightheron", + "Nightingale", + "Nightjar", + "Nijssenissdwarfchihlid", + "Nilgai", + "Ninebandedarmadillo", + "Noctilio", + "Noctule", + "Noddy", + "Noolbenger", + "Northerncardinals", + "Northernelephantseal", + "Northernflyingsquirrel", + "Northernfurseal", + "Northernhairynosedwombat", + "Northernpike", + "Northernseahorse", + "Northernspottedowl", + "Norwaylobster", + "Norwayrat", + "Nubiangoat", + "Nudibranch", + "Numbat", + "Nurseshark", + "Nutcracker", + "Nuthatch", + "Nutria", + "Nyala", + "Nymph", + "Ocelot", + "Octopus", + "Okapi", + "Olingo", + "Olm", + "Opossum", + "Orangutan", + "Orca", + "Oregonsilverspotbutterfly", + "Oriole", + "Oropendola", + "Oropendula", + "Oryx", + "Osprey", + "Ostracod", + "Ostrich", + "Otter", + "Ovenbird", + "Owl", + "Owlbutterfly", + "Ox", + "Oxen", + "Oxpecker", + "Oyster", + "Ozarkbigearedbat", + "Paca", + "Pachyderm", + "Pacificparrotlet", + "Paddlefish", + "Paintedladybutterfly", + "Panda", + "Pangolin", + "Panther", + "Paperwasp", + "Papillon", + "Parakeet", + "Parrot", + "Partridge", + "Peacock", + "Peafowl", + "Peccary", + "Pekingese", + "Pelican", + "Pelicinuspetrel", + "Penguin", + "Perch", + "Peregrinefalcon", + "Pewee", + "Phalarope", + "Pharaohhound", + "Pheasant", + "Phoebe", + "Phoenix", + "Pig", + "Pigeon", + "Piglet", + "Pika", + "Pike", + "Pikeperch", + "Pilchard", + "Pinemarten", + "Pinkriverdolphin", + "Pinniped", + "Pintail", + "Pipistrelle", + "Pipit", + "Piranha", + "Pitbull", + "Pittabird", + "Plainsqueaker", + "Plankton", + "Planthopper", + "Platypus", + "Plover", + "Polarbear", + "Polecat", + "Polliwog", + "Polyp", + "Polyturator", + "Pomeranian", + "Pondskater", + "Pony", + "Pooch", + "Poodle", + "Porcupine", + "Porpoise", + "Portuguesemanofwar", + "Possum", + "Prairiedog", + "Prawn", + "Prayingmantid", + "Prayingmantis", + "Primate", + "Pronghorn", + "Pseudodynerusquadrisectus", + "Ptarmigan", + "Pterodactyls", + "Pterosaurs", + "Puffer", + "Pufferfish", + "Puffin", + "Pug", + "Pullet", + "Puma", + "Pupa", + "Pupfish", + "Puppy", + "Purplemarten", + "Pussycat", + "Pygmy", + "Python", + "Quadrisectus", + "Quagga", + "Quahog", + "Quail", + "Queenalexandrasbirdwing", + "Queenalexandrasbirdwingbutterfly", + "Queenant", + "Queenbee", + "Queenconch", + "Queenslandgrouper", + "Queenslandheeler", + "Queensnake", + "Quelea", + "Quetzal", + "Quetzalcoatlus", + "Quillback", + "Quinquespinosus", + "Quokka", + "Quoll", + "Rabbit", + "Rabidsquirrel", + "Raccoon", + "Racer", + "Racerunner", + "Ragfish", + "Rail", + "Rainbowfish", + "Rainbowlorikeet", + "Rainbowtrout", + "Ram", + "Raptors", + "Rasbora", + "Rat", + "Ratfish", + "Rattail", + "Rattlesnake", + "Raven", + "Ray", + "Redhead", + "Redheadedwoodpecker", + "Redpoll", + "Redstart", + "Redtailedhawk", + "Reindeer", + "Reptile", + "Reynard", + "Rhea", + "Rhesusmonkey", + "Rhino", + "Rhinoceros", + "Rhinocerosbeetle", + "Rhodesianridgeback", + "Ringtailedlemur", + "Ringworm", + "Riograndeescuerzo", + "Roach", + "Roadrunner", + "Roan", + "Robberfly", + "Robin", + "Rockrat", + "Rodent", + "Roebuck", + "Roller", + "Rook", + "Rooster", + "Rottweiler", + "Sable", + "Sableantelope", + "Sablefish", + "Saiga", + "Sakimonkey", + "Salamander", + "Salmon", + "Saltwatercrocodile", + "Sambar", + "Samoyeddog", + "Sandbarshark", + "Sanddollar", + "Sanderling", + "Sandpiper", + "Sapsucker", + "Sardine", + "Sawfish", + "Scallop", + "Scarab", + "Scarletibis", + "Scaup", + "Schapendoes", + "Schipperke", + "Schnauzer", + "Scorpion", + "Scoter", + "Screamer", + "Seabird", + "Seagull", + "Seahog", + "Seahorse", + "Seal", + "Sealion", + "Seamonkey", + "Seaslug", + "Seaurchin", + "Senegalpython", + "Seriema", + "Serpent", + "Serval", + "Shark", + "Shearwater", + "Sheep", + "Sheldrake", + "Shelduck", + "Shibainu", + "Shihtzu", + "Shorebird", + "Shoveler", + "Shrew", + "Shrike", + "Shrimp", + "Siamang", + "Siamesecat", + "Siberiantiger", + "Sidewinder", + "Sifaka", + "Silkworm", + "Silverfish", + "Silverfox", + "Silversidefish", + "Siskin", + "Skimmer", + "Skink", + "Skipper", + "Skua", + "Skunk", + "Skylark", + "Sloth", + "Slothbear", + "Slug", + "Smelts", + "Smew", + "Snail", + "Snake", + "Snipe", + "Snoutbutterfly", + "Snowdog", + "Snowgeese", + "Snowleopard", + "Snowmonkey", + "Snowyowl", + "Sockeyesalmon", + "Solenodon", + "Solitaire", + "Songbird", + "Sora", + "Southernhairnosedwombat", + "Sow", + "Spadefoot", + "Sparrow", + "Sphinx", + "Spider", + "Spidermonkey", + "Spiketail", + "Spittlebug", + "Sponge", + "Spoonbill", + "Spotteddolphin", + "Spreadwing", + "Springbok", + "Springpeeper", + "Springtail", + "Squab", + "Squamata", + "Squeaker", + "Squid", + "Squirrel", + "Stag", + "Stagbeetle", + "Stallion", + "Starfish", + "Starling", + "Steed", + "Steer", + "Stegosaurus", + "Stickinsect", + "Stickleback", + "Stilt", + "Stingray", + "Stinkbug", + "Stinkpot", + "Stoat", + "Stonefly", + "Stork", + "Stud", + "Sturgeon", + "Sugarglider", + "Sulphurbutterfly", + "Sunbear", + "Sunbittern", + "Sunfish", + "Swallow", + "Swallowtail", + "Swallowtailbutterfly", + "Swan", + "Swellfish", + "Swift", + "Swordfish", + "Tadpole", + "Tahr", + "Takin", + "Tamarin", + "Tanager", + "Tapaculo", + "Tapeworm", + "Tapir", + "Tarantula", + "Tarpan", + "Tarsier", + "Taruca", + "Tasmaniandevil", + "Tasmaniantiger", + "Tattler", + "Tayra", + "Teal", + "Tegus", + "Teledu", + "Tench", + "Tenrec", + "Termite", + "Tern", + "Terrapin", + "Terrier", + "Thoroughbred", + "Thrasher", + "Thrip", + "Thrush", + "Thunderbird", + "Thylacine", + "Tick", + "Tiger", + "Tigerbeetle", + "Tigermoth", + "Tigershark", + "Tilefish", + "Tinamou", + "Titi", + "Titmouse", + "Toad", + "Toadfish", + "Tomtit", + "Topi", + "Tortoise", + "Toucan", + "Towhee", + "Tragopan", + "Treecreeper", + "Trex", + "Triceratops", + "Trogon", + "Trout", + "Trumpeterbird", + "Trumpeterswan", + "Tsetsefly", + "Tuatara", + "Tuna", + "Turaco", + "Turkey", + "Turnstone", + "Turtle", + "Turtledove", + "Uakari", + "Ugandakob", + "Uintagroundsquirrel", + "Ulyssesbutterfly", + "Umbrellabird", + "Umbrette", + "Unau", + "Ungulate", + "Unicorn", + "Upupa", + "Urchin", + "Urial", + "Uromastyxmaliensis", + "Uromastyxspinipes", + "Urson", + "Urubu", + "Urus", + "Urutu", + "Urva", + "Utahprairiedog", + "Vampirebat", + "Vaquita", + "Veery", + "Velociraptor", + "Velvetcrab", + "Velvetworm", + "Venomoussnake", + "Verdin", + "Vervet", + "Viceroybutterfly", + "Vicuna", + "Viper", + "Viperfish", + "Vipersquid", + "Vireo", + "Virginiaopossum", + "Vixen", + "Vole", + "Volvox", + "Vulpesvelox", + "Vulpesvulpes", + "Vulture", + "Walkingstick", + "Wallaby", + "Wallaroo", + "Walleye", + "Walrus", + "Warbler", + "Warthog", + "Wasp", + "Waterboatman", + "Waterbuck", + "Waterbuffalo", + "Waterbug", + "Waterdogs", + "Waterdragons", + "Watermoccasin", + "Waterstrider", + "Waterthrush", + "Wattlebird", + "Watussi", + "Waxwing", + "Weasel", + "Weaverbird", + "Weevil", + "Westafricanantelope", + "Whale", + "Whapuku", + "Whelp", + "Whimbrel", + "Whippet", + "Whippoorwill", + "Whitebeakeddolphin", + "Whiteeye", + "Whitepelican", + "Whiterhino", + "Whitetaileddeer", + "Whitetippedreefshark", + "Whooper", + "Whoopingcrane", + "Widgeon", + "Widowspider", + "Wildcat", + "Wildebeast", + "Wildebeest", + "Willet", + "Wireworm", + "Wisent", + "Wobbegongshark", + "Wolf", + "Wolfspider", + "Wolverine", + "Wombat", + "Woodborer", + "Woodchuck", + "Woodcock", + "Woodnymphbutterfly", + "Woodpecker", + "Woodstorks", + "Woollybearcaterpillar", + "Worm", + "Wrasse", + "Wreckfish", + "Wren", + "Wrenchbird", + "Wryneck", + "Wuerhosaurus", + "Wyvern", + "Xanclomys", + "Xanthareel", + "Xantus", + "Xantusmurrelet", + "Xeme", + "Xenarthra", + "Xenoposeidon", + "Xenops", + "Xenopterygii", + "Xenopus", + "Xenotarsosaurus", + "Xenurine", + "Xenurusunicinctus", + "Xerus", + "Xiaosaurus", + "Xinjiangovenator", + "Xiphias", + "Xiphiasgladius", + "Xiphosuran", + "Xoloitzcuintli", + "Xoni", + "Xrayfish", + "Xraytetra", + "Xuanhanosaurus", + "Xuanhuaceratops", + "Xuanhuasaurus", + "Yaffle", + "Yak", + "Yapok", + "Yardant", + "Yearling", + "Yellowbelliedmarmot", + "Yellowbellylizard", + "Yellowhammer", + "Yellowjacket", + "Yellowlegs", + "Yellowthroat", + "Yellowwhitebutterfly", + "Yeti", + "Ynambu", + "Yorkshireterrier", + "Yosemitetoad", + "Yucker", + "Zander", + "Zanzibardaygecko", + "Zebra", + "Zebradove", + "Zebrafinch", + "Zebrafish", + "Zebralongwingbutterfly", + "Zebraswallowtailbutterfly", + "Zebratailedlizard", + "Zebu", + "Zenaida", + "Zeren", + "Zethusspinipes", + "Zethuswasp", + "Zigzagsalamander", + "Zonetailedpigeon", + "Zooplankton", + "Zopilote", + "Zorilla" + }; + + public static bool WordIsInWordList(string word, WordType wordType) + { + switch (wordType) + { + case WordType.Adjective: + return Adjectives.Contains(word, StringComparer.OrdinalIgnoreCase); + case WordType.Verb: + return Verbs.Contains(word, StringComparer.OrdinalIgnoreCase); + case WordType.Animal: + return Animals.Contains(word, StringComparer.OrdinalIgnoreCase); + } + + return false; + } + + } +} \ No newline at end of file diff --git a/HumanReadableId.UnitTests/HumanReadableId.UnitTests.csproj b/HumanReadableId.UnitTests/HumanReadableId.UnitTests.csproj new file mode 100644 index 0000000..ed03e1b --- /dev/null +++ b/HumanReadableId.UnitTests/HumanReadableId.UnitTests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + diff --git a/HumanReadableId.UnitTests/HumanReadableIdTests.cs b/HumanReadableId.UnitTests/HumanReadableIdTests.cs new file mode 100644 index 0000000..85c2832 --- /dev/null +++ b/HumanReadableId.UnitTests/HumanReadableIdTests.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace HumanReadableId.UnitTests +{ + public class HumanReadableIdTests + { + [Test] + public void ShouldGenerateAnId() + { + var id = HumanReadableId.Generate(); + Assert.IsNotEmpty(id); + } + + [Test] + public void ShouldHaveWordTypeArraysForAdjectivesVerbsAndAnimals() + { + Assert.IsTrue(Words.Adjectives.Length > 0); + Assert.IsTrue(Words.Verbs.Length > 0); + Assert.IsTrue(Words.Animals.Length > 0); + Console.WriteLine($"Adjectives: {Words.Adjectives.Length} Verbs: {Words.Verbs.Length} Animals: {Words.Animals.Length}"); + } + + [Test] + public void ShouldGenerateAnIdWithExpectedWordCountByDefault() + { + var id = HumanReadableId.Generate(); + var words = id.Split('-'); + Assert.AreEqual(words.Length, HumanReadableId.DefaultPattern.Length); + } + + [Test] + public void ShouldGenerateAnIdInTheDefaultFormatByDefault() + { + var id = HumanReadableId.Generate(); + var words = id.Split('-'); + + for (var i = 0; i < HumanReadableId.DefaultPattern.Length; i++) + { + Assert.IsTrue(Words.WordIsInWordList(words[i], HumanReadableId.DefaultPattern[i])); + } + } + + [Test] + [TestCase(new[] { WordType.Adjective, WordType.Adjective, WordType.Adjective, WordType.Animal })] + [TestCase(new[] { WordType.Animal, WordType.Verb, WordType.Adjective })] + public void ShouldGenerateAnIdWithCustomFormat(WordType[] pattern) + { + var id = HumanReadableId.Generate(pattern); + var words = id.Split('-'); + + for (var i = 0; i < pattern.Length; i++) + { + Assert.IsTrue(Words.WordIsInWordList(words[i], pattern[i])); + } + } + + [Test] + public void ShouldRespectLowerCasePassphraseConfig() + { + var config = new Config { LowerCasePassphrase = true }; + var id = HumanReadableId.Generate(config); + + // Split the ID by the separator to get the individual words + var words = id.Split(config.SeparationChar); + + // Check that each word is in lowercase + foreach (var word in words) + { + Assert.IsTrue(word.All(char.IsLower), $"Word '{word}' is not in lowercase"); + } + } + + [Test] + public void ShouldRespectSeparationCharConfig() + { + var config = new Config { SeparationChar = "|" }; + var id = HumanReadableId.Generate(config, WordType.Adjective, WordType.Animal); + Assert.IsTrue(id.Contains("|")); + var words = id.Split('|'); + + Assert.AreEqual(words.Length, 2); // Adjective and Animal + Assert.IsTrue(Words.WordIsInWordList(words[0], WordType.Adjective)); + Assert.IsTrue(Words.WordIsInWordList(words[1], WordType.Animal)); + } + + [Test] + public void ShouldHandleEmptyPattern() + { + var id = HumanReadableId.Generate(new WordType[] { }); + var words = id.Split('-'); + Assert.AreEqual(words.Length, HumanReadableId.DefaultPattern.Length); + } + + [Test] + public void ShouldGenerateIdWithLargePattern() + { + var largePattern = Enumerable.Repeat(WordType.Adjective, 100).ToArray(); + var id = HumanReadableId.Generate(largePattern); + var words = id.Split('-'); + Assert.AreEqual(words.Length, largePattern.Length); + } + + [Test] + public void ShouldHandleNullPattern() + { + var id = HumanReadableId.Generate(null, null); + var words = id.Split('-'); + Assert.AreEqual(words.Length, HumanReadableId.DefaultPattern.Length); + } + + [Test] + [TestCase(1000000)] + public void ShouldGenerateUniqueIds(int numIdsToGenerate) + { + static string GenerateIdAndCheckForDupes(ICollection hashSet) + { + var id = HumanReadableId.Generate(); + if (hashSet.Contains(id)) + { + id = GenerateIdAndCheckForDupes(hashSet); + } + + return id; + } + + var ids = new HashSet(); + for (var i = 0; i < numIdsToGenerate; i++) + { + ids.Add(GenerateIdAndCheckForDupes(ids)); + } + + Assert.AreEqual(ids.Count, numIdsToGenerate); + } + } +} diff --git a/HumanReadableId.sln b/HumanReadableId.sln new file mode 100644 index 0000000..d8ddcbe --- /dev/null +++ b/HumanReadableId.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HumanReadableId.ConsoleApp", "HumanReadableId.ConsoleApp\HumanReadableId.ConsoleApp.csproj", "{BD20D877-2D57-4BE9-981C-C507705568B2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HumanReadableId", "HumanReadableId.Core\HumanReadableId.csproj", "{681B4C32-FAE2-491E-B54C-2E370582892D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HumanReadableId.UnitTests", "HumanReadableId.UnitTests\HumanReadableId.UnitTests.csproj", "{975886A1-E641-47BA-A918-C0217DDA40A3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BD20D877-2D57-4BE9-981C-C507705568B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD20D877-2D57-4BE9-981C-C507705568B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD20D877-2D57-4BE9-981C-C507705568B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD20D877-2D57-4BE9-981C-C507705568B2}.Release|Any CPU.Build.0 = Release|Any CPU + {681B4C32-FAE2-491E-B54C-2E370582892D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {681B4C32-FAE2-491E-B54C-2E370582892D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {681B4C32-FAE2-491E-B54C-2E370582892D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {681B4C32-FAE2-491E-B54C-2E370582892D}.Release|Any CPU.Build.0 = Release|Any CPU + {975886A1-E641-47BA-A918-C0217DDA40A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {975886A1-E641-47BA-A918-C0217DDA40A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {975886A1-E641-47BA-A918-C0217DDA40A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {975886A1-E641-47BA-A918-C0217DDA40A3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C64E43A0-797C-4564-989C-81DED729861E} + EndGlobalSection +EndGlobal diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..5d39847 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Gavin Foley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..deda2d5 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# HumanReadableId + +![.NET Core](https://github.com/GFoley83/HumanReadableId/workflows/.NET%20Core/badge.svg?branch=master) + +Create human-readable Ids, just like Gfycat. Use the default format of _VerbAdjectiveAnimal_ or a custom format of your choosing. + +## Example Usage + +[https://dotnetfiddle.net/4KGjWQ](https://dotnetfiddle.net/4KGjWQ) + +```csharp +// Create Id in the default form VerbAdjectiveAnimal +var id = GfycatesceIds.Generate(); // id == "ExaltedDifficultAntelope" + +// Create classic Gfycat Id in the form AdjectiveAdjectiveAnimal +var id = GfycatesceIds.Generate(GfycatesceIds.GfycatPattern); // id == "CalmFriendlyLion" + +// Create Id in a custom form and length +var id = GfycatesceIds.Generate(new[] + { + WordType.Verb, WordType.Adjective, WordType.Verb, WordType.Verb, WordType.Animal + }); // id == "WalkHorribleConfessQuestionZebra" +``` \ No newline at end of file