private static void CombinationCount(ReadablePassphraseGenerator generator) { Console.WriteLine(); Console.WriteLine("Combination count:"); foreach (var strength in RandomStrengths) { var combinations = generator.CalculateCombinations(strength); Console.WriteLine(" {0}: {1:E3} ({2:N2} bits)", strength, combinations.ToString(), combinations.EntropyBitsToString()); } Console.WriteLine(); var predefined = new PhraseStrength[] { PhraseStrength.Normal, PhraseStrength.NormalAnd, PhraseStrength.NormalSpeech, PhraseStrength.NormalEqual, PhraseStrength.NormalEqualAnd, PhraseStrength.NormalEqualSpeech, PhraseStrength.NormalRequired, PhraseStrength.NormalRequiredAnd, PhraseStrength.NormalRequiredSpeech, PhraseStrength.Strong, PhraseStrength.StrongAnd, PhraseStrength.StrongSpeech, PhraseStrength.StrongEqual, PhraseStrength.StrongEqualAnd, PhraseStrength.StrongEqualSpeech, PhraseStrength.StrongRequired, PhraseStrength.StrongRequiredAnd, PhraseStrength.StrongRequiredSpeech, PhraseStrength.Insane, PhraseStrength.InsaneAnd, PhraseStrength.InsaneSpeech, PhraseStrength.InsaneEqual, PhraseStrength.InsaneEqualAnd, PhraseStrength.InsaneEqualSpeech, PhraseStrength.InsaneRequired, PhraseStrength.InsaneRequiredAnd, PhraseStrength.InsaneRequiredSpeech, }; for (int i = 0; i < predefined.Length; i++) { var strength = predefined[i]; var combinations = generator.CalculateCombinations(strength); Console.WriteLine(" {0}: {1:E3} ({2:N2} bits)", strength, combinations.ToString(), combinations.EntropyBitsToString()); if ((i + 1) % 9 == 0) { Console.WriteLine(); } } }
private static void TinkerWithCustomClause(ReadablePassphraseGenerator generator) { GenerateCustomSamples(new Clause[] { new NounClause() { CommonNounFactor = 1, ProperNounFactor = 0, NounFromAdjectiveFactor = 0, SingularityFactor = 1, PluralityFactor = 1, NoArticleFactor = 1, DefiniteArticleFactor = 1, IndefiniteArticleFactor = 1, DemonstractiveFactor = 1, PersonalPronounFactor = 1, NoNumberFactor = 1, NumberFactor = 1, NoAdjectiveFactor = 1, AdjectiveFactor = 0, NoPrepositionFactor = 1, PrepositionFactor = 0 }, new VerbClause() { PresentFactor = 1, PastFactor = 1, FutureFactor = 1, ContinuousFactor = 1, ContinuousPastFactor = 1, PerfectFactor = 1, SubjunctiveFactor = 1, NoAdverbFactor = 1, AdverbFactor = 0, NoInterrogativeFactor = 1, InterrogativeFactor = 0, IntransitiveByNoNounClauseFactor = 1, IntransitiveByPrepositionFactor = 1 }, new NounClause() { CommonNounFactor = 1, ProperNounFactor = 0, NounFromAdjectiveFactor = 0, SingularityFactor = 1, PluralityFactor = 1, NoArticleFactor = 1, DefiniteArticleFactor = 1, IndefiniteArticleFactor = 1, DemonstractiveFactor = 1, PersonalPronounFactor = 1, NoNumberFactor = 1, NumberFactor = 0, NoAdjectiveFactor = 1, AdjectiveFactor = 0, NoPrepositionFactor = 1, PrepositionFactor = 0 }, } , generator, 100); }
private static void DictionaryCheck(ReadablePassphraseGenerator generator) { Console.WriteLine(); Console.WriteLine("Name: {0}", generator.Dictionary.Name); Console.WriteLine("Langauge: {0}", generator.Dictionary.LanguageCode); Console.WriteLine("TOTAL: {0:N0}", generator.Dictionary.Count); Console.WriteLine("TOTAL forms: {0:N0}", generator.Dictionary.CountOfAllDistinctForms()); Console.WriteLine("Nouns: {0:N0}", generator.Dictionary.OfType <Noun>().Count()); Console.WriteLine("Proper Nouns: {0:N0}", generator.Dictionary.OfType <ProperNoun>().Count()); Console.WriteLine("Verbs (all): {0:N0}", generator.Dictionary.OfType <Verb>().Count()); Console.WriteLine("Verbs (trans): {0:N0}", generator.Dictionary.OfType <Verb>().Count(w => w.IsTransitive)); Console.WriteLine("Verbs (intrans): {0:N0}", generator.Dictionary.OfType <Verb>().Count(w => !w.IsTransitive)); Console.WriteLine("Prepositions: {0:N0}", generator.Dictionary.OfType <Preposition>().Count()); Console.WriteLine("Adverbs: {0:N0}", generator.Dictionary.OfType <Adverb>().Count()); Console.WriteLine("Adjectives: {0:N0}", generator.Dictionary.OfType <Adjective>().Count()); // Check for duplicates. foreach (var t in typeof(Word).Assembly.GetTypes().Where(t => typeof(Word).IsAssignableFrom(t) && t != typeof(Word))) { var duplicates = generator.Dictionary .Where(w => t.IsAssignableFrom(w.GetType())) .GroupBy(w => w.DictionaryEntry, StringComparer.OrdinalIgnoreCase) .Where(g => g.Count() > 1); if (duplicates.Any()) { Console.WriteLine("DUPLICATES for {0}:", t.Name); foreach (var g in duplicates) { Console.WriteLine(" - " + g.Key); } } } }
private static void TestGenerationAsSecure(ReadablePassphraseGenerator generator, IEnumerable <PhraseStrength> strengths, int iterations) { Console.Write("Testing {0:N0} secure phrases of strength {1}...", iterations, String.Join(",", strengths.Select(x => x.ToString()))); for (int i = 0; i < iterations; i++) { generator.GenerateAsSecure(strengths); } Console.WriteLine(" OK."); }
private static void GenerateSamples(PhraseStrength strength, ReadablePassphraseGenerator generator, int count) { Console.WriteLine(); Console.WriteLine("Samples:"); for (int i = 0; i < count; i++) { Console.WriteLine(generator.Generate(strength)); } }
private static void GenerateDelimiterSamples(PhraseStrength strength, ReadablePassphraseGenerator generator, int count, string delimiter) { Console.WriteLine(); Console.WriteLine("Delimited Samples ('{0}'):", delimiter); for (int i = 0; i < count; i++) { Console.WriteLine(generator.Generate(strength, wordDelimiter: delimiter)); } }
private static void TestGenerationAsSecure(ReadablePassphraseGenerator generator, PhraseStrength strength, int iterations) { Console.Write("Testing {0:N0} secure phrases of strength {1}...", iterations, strength); for (int i = 0; i < iterations; i++) { generator.GenerateAsSecure(strength); } Console.WriteLine(" OK."); }
private static void GenerateMutatedSamples(PhraseStrength strength, ReadablePassphraseGenerator generator, int count, IEnumerable <IMutator> mutators) { Console.WriteLine(); Console.WriteLine("Mutated Samples:"); for (int i = 0; i < count; i++) { var passphrase = generator.Generate(strength, mutators: mutators); Console.WriteLine(passphrase); } }
private static void BenchmarkUtf8Generation(ReadablePassphraseGenerator generator, PhraseStrength strength, int iterations) { Console.WriteLine(); Console.WriteLine("Benchmark of {0:N0} UTF8 phrases of strength {1}...", iterations, strength); var sw = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { generator.GenerateAsUtf8Bytes(strength); } sw.Stop(); Console.WriteLine(" in {0:N3}ms", sw.Elapsed.TotalMilliseconds); }
private static void WriteAllStatistics(ReadablePassphraseGenerator generator) { System.IO.File.Delete(AllStatsCharFilename); var specialStrengths = RandomStrengths.Concat(new[] { PhraseStrength.Custom }); var allToTest = Enum.GetValues(typeof(PhraseStrength)).Cast <PhraseStrength>() .Where(x => !specialStrengths.Contains(x)); foreach (var strength in allToTest) { WriteStatisticsFor(generator, strength, 1000000, strength.ToString() + ".csv"); } foreach (var strength in RandomStrengths) { WriteStatisticsFor(generator, strength, 10000000, strength.ToString() + ".csv"); } }
private static void TestConfigForm(ReadablePassphraseGenerator generator) { String config; using (var frm = new KeePassReadablePassphrase.ConfigRoot("", GetRandomness())) { frm.ShowDialog(); Console.WriteLine(); Console.WriteLine("Serialised Config from Form:"); Console.WriteLine(frm.ConfigForKeePass); config = frm.ConfigForKeePass; } using (var frm = new KeePassReadablePassphrase.ConfigRoot(config, GetRandomness())) { frm.ShowDialog(); } }
private static void TestTextualParsing(ReadablePassphraseGenerator generator, PhraseStrength strength) { Console.WriteLine("Testing parsing of textual phrase strength {0}...", strength); var description = Clause.CreatePhraseDescription(strength, generator.Randomness); var sb = new StringBuilder(); foreach (var c in description) { c.ToStringBuilder(sb); } var textualDescription = sb.ToString(); Console.Write(" Generation OK."); var customStrength = Clause.CreateCollectionFromTextString(textualDescription); Console.Write(" Parsing OK."); generator.Generate(customStrength); Console.WriteLine(" Passphrase OK."); }
private static void TestAllStrengthsAndOutputs(ReadablePassphraseGenerator generator) { var specialStrengths = RandomStrengths.Concat(new[] { PhraseStrength.Custom }); var allToTest = Enum.GetValues(typeof(PhraseStrength)).Cast <PhraseStrength>() .Where(x => !specialStrengths.Contains(x)); foreach (var strength in allToTest) { TestTextualParsing(generator, strength); TestGeneration(generator, strength, 50); TestGenerationAsUtf8(generator, strength, 20); TestGenerationAsSecure(generator, strength, 20); } foreach (var strength in RandomStrengths) { TestGeneration(generator, Clause.RandomMappings[strength], 10); TestGenerationAsUtf8(generator, Clause.RandomMappings[strength], 10); TestGenerationAsSecure(generator, Clause.RandomMappings[strength], 10); } }
private static void TestGithubIssue3(ReadablePassphraseGenerator generator) { // No trailing whitespace causes ArgumentOutOfRangeException in ConstantMutator // Caused with combination of numeric mutator at end of phrase, then constant mutator at end of phrase // https://github.com/ligos/readablepassphrasegenerator/issues/3 var numericMutator = new NumericMutator() { When = NumericStyles.EndOfPhrase }; var constantMutator = new ConstantMutator() { When = ConstantStyles.EndOfPhrase }; var mutatorArray = new IMutator[] { numericMutator, constantMutator }; var phrase = generator.Generate(wordDelimiter: "__", mutators: mutatorArray); Console.WriteLine(phrase); if (!phrase.EndsWith(constantMutator.ValueToAdd)) { throw new Exception("Should not be any trailing whitespace; final character should be the '.' from ConstantMutator"); } phrase = generator.Generate(wordDelimiter: "", mutators: mutatorArray); Console.WriteLine(phrase); if (!phrase.EndsWith(constantMutator.ValueToAdd)) { throw new Exception("Should not be any trailing whitespace; final character should be the '.' from ConstantMutator"); } var sb = new StringBuilder("some passphrase without trailing whitespace"); numericMutator.Mutate(sb, GetRandomness()); constantMutator.Mutate(sb, GetRandomness()); Console.WriteLine(sb.ToString()); sb = new StringBuilder("some passphrase with extra trailing whitespace "); numericMutator.Mutate(sb, GetRandomness()); constantMutator.Mutate(sb, GetRandomness()); Console.WriteLine(sb.ToString()); }
private static void TestBitbucketIssue16(ReadablePassphraseGenerator generator) { // Testing Bitbucket Issue #16 - always generating the definite article. GenerateCustomSamples(new Clause[] { //Noun = { // Adjective->0, NoAdjective->1, // NoArticle->100, DefiniteArticle->1, IndefiniteArticle->0, Demonstrative->0, PersonalPronoun->0, // ProperNoun->0, CommonNoun->12, AdjectiveNoun->2, // Number->0, NoNumber->1, // Plural->0, Single->1, // Preposition->0, NoPreposition->1, // } new NounClause() { CommonNounFactor = 12, ProperNounFactor = 0, NounFromAdjectiveFactor = 2, SingularityFactor = 1, PluralityFactor = 0, NoArticleFactor = 100, DefiniteArticleFactor = 1, IndefiniteArticleFactor = 0, DemonstractiveFactor = 0, PersonalPronounFactor = 0, NoNumberFactor = 1, NumberFactor = 0, NoAdjectiveFactor = 1, AdjectiveFactor = 0, NoPrepositionFactor = 0, PrepositionFactor = 1 }, } , generator, 10); // Try with no definite article - much better! // Singular requires an noun prelude, so it ignores the NoArticleFactor. GenerateCustomSamples(new Clause[] { new NounClause() { CommonNounFactor = 12, ProperNounFactor = 0, NounFromAdjectiveFactor = 2, SingularityFactor = 1, PluralityFactor = 0, NoArticleFactor = 1, DefiniteArticleFactor = 0, IndefiniteArticleFactor = 0, DemonstractiveFactor = 0, PersonalPronounFactor = 0, NoNumberFactor = 1, NumberFactor = 0, NoAdjectiveFactor = 1, AdjectiveFactor = 0, NoPrepositionFactor = 0, PrepositionFactor = 1 }, } , generator, 10); }
private static void TestBitbucketIssue15(ReadablePassphraseGenerator generator) { // Testing Bitbucket Issue #15 - causes crash. GenerateCustomSamples(new Clause[] { // Adjective->1, NoAdjective->1, // NoArticle->50, DefiniteArticle->25, IndefiniteArticle->0, Demonstrative->1, PersonalPronoun->0, // ProperNoun->1, CommonNoun->5, AdjectiveNoun->0, // Number->0, NoNumber->1, // Plural->1, Single->1, // Preposition->1, NoPreposition->1 new NounClause() { CommonNounFactor = 5, ProperNounFactor = 1, NounFromAdjectiveFactor = 0, SingularityFactor = 1, PluralityFactor = 1, NoArticleFactor = 50, DefiniteArticleFactor = 25, IndefiniteArticleFactor = 0, DemonstractiveFactor = 1, PersonalPronounFactor = 0, NoNumberFactor = 1, NumberFactor = 0, NoAdjectiveFactor = 1, AdjectiveFactor = 1, NoPrepositionFactor = 1, PrepositionFactor = 1 }, } , generator, 10); }
static void RunMain() { // Generate and print phrases. if (!quiet) { var ver = GetProgramVersion(); var idx = ver.IndexOf('.', ver.IndexOf('.', ver.IndexOf('.') + 1) + 1); Console.WriteLine("Readable Passphrase Generator {0}", ver.Substring(0, idx)); } if (!quiet && anyLength > 0) { Console.WriteLine("Generating {0:N0} non-grammatic phrase(s) of length '{1}'...", count, anyLength); } else if (!quiet && String.IsNullOrEmpty(customPhrasePath)) { Console.WriteLine("Generating {0:N0} phrase(s) of strength '{1}'...", count, strength); } else if (!quiet && !String.IsNullOrEmpty(customPhrasePath)) { Console.WriteLine("Generating {0:N0} phrase(s) based on phrase description in '{1}'...", count, System.IO.Path.GetFileName(customPhrasePath)); } if (!quiet && (maxLength < Int32.MaxValue || minLength > 1)) { Console.WriteLine("Must be between {0:N0} and {1} characters.", minLength, maxLength == Int32.MaxValue ? "∞" : maxLength.ToString("N0")); } var generator = new ReadablePassphraseGenerator(); // Must load dictionary before trying to generate. var dictSw = System.Diagnostics.Stopwatch.StartNew(); var loaderT = GetDictionaryLoaderType(); // If the internal dictionary loader is being used and no other arguments are specified, tell it to use the default dictionary. if (loaderT == typeof(ExplicitXmlDictionaryLoader) && String.IsNullOrEmpty(loaderArguments.Trim())) { loaderArguments = "useDefaultDictionary=true"; } // And load our dictionary! using (var loader = Activator.CreateInstance(loaderT) as IDictionaryLoader) { if (loader == null) { throw new Exception($"Unable to create instance of dictionary loader {loaderT.FullName}"); } generator.LoadDictionary(loader, loaderArguments); } dictSw.Stop(); // Summarise actions and combinations / entropy. if (!quiet) { Console.WriteLine("Dictionary contains {0:N0} words (loaded in {1:N2}ms)", generator.Dictionary.Count, dictSw.Elapsed.TotalMilliseconds); PhraseCombinations combinations; if (anyLength > 0) { combinations = generator.CalculateCombinations(NonGrammaticalClause(anyLength)); } else if (strength != PhraseStrength.Custom) { combinations = generator.CalculateCombinations(strength); } else { combinations = generator.CalculateCombinations(phraseDescription); } Console.WriteLine("Average combinations ~{0:E3} (~{1:N2} bits)", combinations.OptionalAverage, combinations.OptionalAverageAsEntropyBits); Console.WriteLine("Total combinations {0:E3} - {1:E3} ({2:N2} - {3:N2} bits)", combinations.Shortest, combinations.Longest, combinations.ShortestAsEntropyBits, combinations.LongestAsEntropyBits); var upperTypeText = upperStyle == AllUppercaseStyles.RunOfLetters ? " run" : upperStyle == AllUppercaseStyles.WholeWord ? " word" : ""; var upperTypeText2 = upperStyle == AllUppercaseStyles.RunOfLetters ? "run" : upperStyle == AllUppercaseStyles.WholeWord ? "word" : "capital"; if (applyStandardMutators) { Console.WriteLine("Using standard mutators (2 numbers, 2 capitals, period at end)"); } else if (applyAlternativeMutators) { Console.WriteLine("Using alternate mutators (2 numbers, 1 whole capital word, period at end)"); } else if (numericStyle != 0 && upperStyle != 0 && constantStyle != 0) { Console.WriteLine($"Using upper case{upperTypeText}, numeric and constant mutators ({upperCount:N0} {upperTypeText2}(s), {numericCount:N0} number(s))"); } else if (numericStyle != 0 && upperStyle != 0 && constantStyle == 0) { Console.WriteLine($"Using upper case{upperTypeText} and numeric mutators ({upperCount:N0} {upperTypeText2}(s), {numericCount:N0} number(s))"); } else if (numericStyle == 0 && upperStyle != 0 && constantStyle != 0) { Console.WriteLine($"Using upper case{upperTypeText} and constant mutators ({upperCount:N0} {upperTypeText2}(s))"); } else if (numericStyle == 0 && upperStyle != 0 && constantStyle == 0) { Console.WriteLine($"Using upper case{upperTypeText} mutator only ({upperCount:N0} {upperTypeText2}(s))"); } else if (numericStyle != 0 && upperStyle == 0 && constantStyle != 0) { Console.WriteLine($"Using numeric and constant mutators ({numericCount:N0} number(s))"); } else if (numericStyle != 0 && upperStyle == 0 && constantStyle == 0) { Console.WriteLine($"Using numeric mutator only ({numericCount:N0} number(s))"); } else if (numericStyle == 0 && upperStyle == 0 && constantStyle != 0) { Console.WriteLine($"Using constant mutator only"); } else { Console.WriteLine("Using no mutators"); } Console.WriteLine(); } // Generate! var genSw = System.Diagnostics.Stopwatch.StartNew(); int generated = 0; int attempts = 0; int maxAttempts = count * MaxAttemptsPerCount; var mutators = applyStandardMutators ? new IMutator[] { UppercaseMutator.Basic, NumericMutator.Basic, ConstantMutator.Basic } : applyAlternativeMutators ? new IMutator[] { UppercaseWordMutator.Basic, NumericMutator.Basic, ConstantMutator.Basic } : Enumerable.Empty <IMutator>(); if (upperStyle > 0 && upperStyle <= AllUppercaseStyles.Anywhere) { mutators = mutators.Concat(new IMutator[] { new UppercaseMutator() { When = (UppercaseStyles)upperStyle, NumberOfCharactersToCapitalise = upperCount } }); } if (upperStyle == AllUppercaseStyles.RunOfLetters) { mutators = mutators.Concat(new IMutator[] { new UppercaseRunMutator() { NumberOfRuns = upperCount } }); } if (upperStyle == AllUppercaseStyles.WholeWord) { mutators = mutators.Concat(new IMutator[] { new UppercaseWordMutator() { NumberOfWordsToCapitalise = upperCount } }); } if (numericStyle != 0) { mutators = mutators.Concat(new IMutator[] { new NumericMutator() { When = numericStyle, NumberOfNumbersToAdd = numericCount } }); } if (constantStyle != 0) { mutators = mutators.Concat(new IMutator[] { new ConstantMutator() { When = constantStyle, ValueToAdd = constantValue } }); } while (generated < count) { // Generate phrase. // We always include spaces in the phrase because the mutators rely on whitespace. string phrase; attempts++; if (anyLength > 0) { phrase = generator.Generate(NonGrammaticalClause(anyLength), " ", mutators); } else if (strength == PhraseStrength.Custom) { phrase = generator.Generate(phraseDescription, " ", mutators); } else { phrase = generator.Generate(strength, " ", mutators); } // After mutators are applied, it's safe to remove white space. if (wordSeparator != " ") { phrase = phrase.Replace(" ", wordSeparator); } // Clamp the length. if (phrase.Length >= minLength && phrase.Length <= maxLength) { Console.WriteLine(phrase); generated++; } if (attempts >= maxAttempts) { break; } } genSw.Stop(); // Summarise result. if (!quiet) { Console.WriteLine(); Console.WriteLine("Generated {0:N0} phrase(s) in {1:N2}ms.", generated, genSw.Elapsed.TotalMilliseconds); if (attempts >= maxAttempts) { Console.WriteLine("But unable to generate requested {0:N0} phrase(s) after {1:N0} attempts." + Environment.NewLine + "Perhaps try changing the minimum or maximum phrase length.", count, attempts); } } }
private static void WriteStatisticsFor(ReadablePassphraseGenerator generator, PhraseStrength strength, int count, string filename) { Console.Write("Writing statistics to '{0}'...", filename); var wordHistogram = new Dictionary <int, int>(); var charHistogram = new Dictionary <int, int>(); var keepassQualityHistogram = new Dictionary <uint, int>(); var combinations = generator.CalculateCombinations(strength); for (int i = 0; i < count; i++) { var phrase = generator.Generate(strength); if (!charHistogram.ContainsKey(phrase.Length)) { charHistogram.Add(phrase.Length, 0); } charHistogram[phrase.Length] = charHistogram[phrase.Length] + 1; var wordCount = phrase.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Length; if (!wordHistogram.ContainsKey(wordCount)) { wordHistogram.Add(wordCount, 0); } wordHistogram[wordCount] = wordHistogram[wordCount] + 1; var keePassQualityEst = KeePassLib.Cryptography.QualityEstimation.EstimatePasswordBits(phrase.ToCharArray()); if (!keepassQualityHistogram.ContainsKey(keePassQualityEst)) { keepassQualityHistogram.Add(keePassQualityEst, 0); } keepassQualityHistogram[keePassQualityEst] = keepassQualityHistogram[keePassQualityEst] + 1; } using (var writer = new System.IO.StreamWriter(filename, false, Encoding.UTF8)) { writer.WriteLine("Word histogram"); for (int i = wordHistogram.Keys.Min(); i < wordHistogram.Keys.Max() + 1; i++) { writer.WriteLine("{0},{1}", i, wordHistogram.ContainsKey(i) ? wordHistogram[i] : 0); } writer.WriteLine(); writer.WriteLine("Character histogram"); for (int i = charHistogram.Keys.Min(); i < charHistogram.Keys.Max() + 1; i++) { writer.WriteLine("{0},{1}", i, charHistogram.ContainsKey(i) ? charHistogram[i] : 0); } writer.WriteLine(); writer.WriteLine("KeePass Quality Estimate"); for (uint i = keepassQualityHistogram.Keys.Min(); i < keepassQualityHistogram.Keys.Max() + 1; i++) { writer.WriteLine("{0},{1}", i, keepassQualityHistogram.ContainsKey(i) ? keepassQualityHistogram[i] : 0); } writer.WriteLine(); writer.WriteLine("Combination counts"); writer.WriteLine("Min:,{0:E3},{1:N2}", combinations.Shortest, combinations.ShortestAsEntropyBits); writer.WriteLine("Max:,{0:E3},{1:N2}", combinations.Longest, combinations.LongestAsEntropyBits); writer.WriteLine("Avg:,{0:E3},{1:N2}", combinations.OptionalAverage, combinations.OptionalAverageAsEntropyBits); writer.WriteLine(); writer.WriteLine("Samples:"); for (int i = 0; i < 20; i++) { writer.WriteLine(generator.Generate(strength)); } } Console.WriteLine(" Done."); bool isFirst = !System.IO.File.Exists(AllStatsCharFilename); using (var writer = new System.IO.StreamWriter(AllStatsCharFilename, true, Encoding.UTF8)) { if (isFirst) { writer.WriteLine("Strength,Min,Max,Avg,Median,Samples"); } writer.WriteLine("{0},{1},{2},{3},{4},{5}", strength.ToString(), charHistogram.Keys.Min(), charHistogram.Keys.Max(), GetAvg(charHistogram), GetMedian(charHistogram), count); } }
private static void GenerateSamples(PhraseStrength strength, ReadablePassphraseGenerator generator) { GenerateSamples(strength, generator, 20); }
private static void GenerateCustomSamples(IEnumerable <MurrayGrant.ReadablePassphrase.PhraseDescription.Clause> clause, ReadablePassphraseGenerator generator, int count) { Console.WriteLine(); Console.WriteLine("Custom samples:"); var combinations = generator.CalculateCombinations(clause); Console.WriteLine("Combinations: {0:E3} ({1:N2} bits)", combinations.ToString(), combinations.EntropyBitsToString()); for (int i = 0; i < count; i++) { Console.WriteLine(generator.Generate(clause)); } }
static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; var sw = System.Diagnostics.Stopwatch.StartNew(); var generator = new ReadablePassphraseGenerator(GetRandomness()); var loader = new ExplicitXmlDictionaryLoader(); var dict = loader.LoadFrom(new DirectoryInfo(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location))); generator.SetDictionary(dict); sw.Stop(); Console.WriteLine("Loaded dictionary of type '{0}' with {1:N0} words in {2:N2}ms ({3:N3} words / sec)", loader.GetType().Name, generator.Dictionary.Count, sw.Elapsed.TotalMilliseconds, generator.Dictionary.Count / sw.Elapsed.TotalSeconds); // Basic statistics / samples. //GenerateSamples(PhraseStrength.Random, generator); //DictionaryCheck(generator); //CombinationCount(generator); // Short benchmarks. //BenchmarkGeneration(generator, PhraseStrength.Normal, 1000); //BenchmarkSecureGeneration(generator, PhraseStrength.Normal, 1000); //BenchmarkUtf8Generation(generator, PhraseStrength.Normal, 1000); //BenchmarkGeneration(generator, PhraseStrength.Strong, 1000); //BenchmarkGeneration(generator, PhraseStrength.Insane, 1000); //BenchmarkGeneration(generator, PhraseStrength.Random, 1000); // Test all combinations of phrase combinations / textual parsing. //TestAllStrengthsAndOutputs(generator); // Test spaces, no spaces and custom delimiter. //GenerateDelimiterSamples(PhraseStrength.Random, generator, 5, " "); //GenerateDelimiterSamples(PhraseStrength.Random, generator, 5, ""); //GenerateDelimiterSamples(PhraseStrength.Random, generator, 5, "."); //GenerateDelimiterSamples(PhraseStrength.Random, generator, 5, "✶"); // Generate statistics. //WriteAllStatistics(generator); // This is used to tinker with custom clauses, probabilities, grammar, etc. //TinkerWithCustomClause(generator); // Other test cases. //TestBitbucketIssue15(generator); //TestBitbucketIssue16(generator); // Longer benchmarks. //BenchmarkGeneration(generator, PhraseStrength.Normal, 10000); //BenchmarkGeneration(generator, PhraseStrength.Strong, 10000); //BenchmarkGeneration(generator, PhraseStrength.Insane, 10000); // Random function distribution tests. //TestCoinFlip(SeededRandom()); //TestWeightedCoinFlip(SeededRandom(), 1, 1); //TestNextInt32(SeededRandom(), 4); //TestNextInt32(SeededRandom(), 15); //TestNextInt32(SeededRandom(), 50); //TestNextInt32(SeededRandom(), 64); //TestNextInt32(SeededRandom(), 256); //TestNextInt32(SeededRandom(), 1296); // TODO: Test load an alternate dictionary loader. // Test the config form. #if NETFRAMEWORK // No WinForms in NetCore //TestConfigForm(generator); #endif // Test mutators. //GenerateMutatedSamples(PhraseStrength.Random, generator, 10, new IMutator[] { new UppercaseRunMutator() }); //GenerateMutatedSamples(PhraseStrength.Random, generator, 10, new IMutator[] { new NumericMutator() }); //GenerateMutatedSamples(PhraseStrength.Random, generator, 10, new IMutator[] { new ConstantMutator() }); // Test loading the default dictionary. //var defaultDictSw = System.Diagnostics.Stopwatch.StartNew(); //var defaultDict = MurrayGrant.ReadablePassphrase.Dictionaries.Default.Load(); //defaultDictSw.Stop(); //Console.WriteLine("Loaded default dictionary from assembly resource with {0:N0} words in {1:N2}ms ({2:N3} words / sec)", defaultDict.Count, defaultDictSw.Elapsed.TotalMilliseconds, defaultDict.Count / defaultDictSw.Elapsed.TotalSeconds); //var easyCreatedGenerator = MurrayGrant.ReadablePassphrase.Generator.Create(); //Console.WriteLine("Loaded generator from Generator.Create() with default dictionary of {0:N0} words.", easyCreatedGenerator.Dictionary.Count); }