private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count) { length = Math.Min(length, MaxLength); count = Math.Min(count, MaxCount); if (count <= 0 || length <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < count; i++) { var bytes = random.GetRandomBytes(length); var result = String.Join("", bytes.Select(x => x.ToString("x2"))); yield return(result); } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("Hex", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count); }
/// <summary> /// Stops listening on the specified remote endpoints. /// </summary> /// <param name="remoteEps">The remote eps.</param> public void StopListeningOn(params IPEndPoint[] remoteEps) { // If nothing specified then just stop listening on all if (remoteEps == null || remoteEps.Length == 0) { this.StopListening(); return; } lock (this.Server) { if (!this.Server.IsListening) { return; } // Drop all the multicast groups specified foreach (IPEndPoint ep in remoteEps.Where(ep => IPAddressHelpers.IsMulticast(ep.Address))) { try { this.Server.DropMulticastGroup(ep.Address); } catch (SocketException) { // If we're not part of this group then it will throw an error so just ignore it } } } }
public void SearchAsync(params IPEndPoint[] destinations) { lock (this.SearchLock) { // If we're already searching then this is not allowed so throw an error if (this.IsSearching) { throw new InvalidOperationException("Search is already in progress."); } this.IsSearching = true; this.Server.SsdpMessageReceived += OnSsdpMessageReceived; // TODO: Come up with a good calculation for this // Just double our mx value for the timeout for now this.CreateSearchTimeout(TimeSpan.FromSeconds(this.Mx * 2)); } // If no destinations were specified then default to the IPv4 discovery if (destinations == null || destinations.Length == 0) { destinations = new[] { Protocol.DiscoveryEndpoints.IPv4 } } ; // Start the server and join our igmp groups this.Server.StartListening(); // Do we really need to join the multicast group to send out multicast messages? Seems that way... foreach (IPEndPoint dest in destinations.Where(ep => IPAddressHelpers.IsMulticast(ep.Address))) { this.Server.JoinMulticastGroupAllInterfaces(dest.Address); } // If we're sending out any searches to the broadcast address then be sure to enable broadcasts if (!this.Server.EnableBroadcast) { this.Server.EnableBroadcast = destinations.Any(ep => ep.Address.Equals(IPAddress.Broadcast)); } // Now send out our search data foreach (var dest in destinations) { // Make sure we respect our option as to whether we use the destination as the host value var host = (this.UseRemoteEndpointAsHost ? dest : this.HostEndpoint); var req = Protocol.CreateSearchRequest(host, this.SearchType, this.Mx); var bytes = Encoding.ASCII.GetBytes(req); var dest1 = dest; // TODO: Should we make this configurable? // NOTE: It's recommended to send two searches Trace.WriteLine(string.Format("Sending ssdp:discover [{0}, {1}] from {2} to {3}", this.SearchType, this.Mx, this.Server.LocalEndpoint, dest1), AppInfo.Application); this.Server.Send(bytes, bytes.Length, dest1); this.Server.Send(bytes, bytes.Length, dest1); } }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?l) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); // Return information about the number of combinations as a JSON object. var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength); var result = new JsonCombinationContainer(); result.combinations = Math.Pow(256, length); return(new JsonNetResult(result)); }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?sc) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); var syllableCount = Math.Min(sc.HasValue ? sc.Value : DefaultSyllableCount, MaxSyllableCount); // Return information about the number of combinations as a JSON object. var result = new JsonCombinationContainer(); result.combinations = Math.Pow(ConsonantSounds.Length * VowelSounds.Length * (ConsonantSounds.Length * ProbabilityOfTwoConsonantsInOneSyllable), syllableCount); return(new JsonNetResult(result)); }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?wc) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); // Return information about the number of combinations as a JSON object. var result = new JsonCombinationContainer(); var wordCount = Math.Min(wc.HasValue ? wc.Value : DefaultWords, MaxWords); var dict = Dictionary.Value; result.combinations = Math.Pow(dict.Count, wordCount); return(new JsonNetResult(result)); }
private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int syllableCount, int count, bool hyphansBetweenSyllables) { syllableCount = Math.Min(syllableCount, MaxSyllableCount); count = Math.Min(count, MaxCount); if (count <= 0 || syllableCount <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); var sb = new StringBuilder(); for (int c = 0; c < count; c++) { // Generate a password. for (int l = 0; l < syllableCount; l++) { sb.Append(ConsonantSounds[random.GetRandomInt32(ConsonantSounds.Length)]); sb.Append(VowelSounds[random.GetRandomInt32(VowelSounds.Length)]); if (sb[sb.Length - 2] != 'g' && sb[sb.Length - 1] != 'h' && random.GetRandomSingle() < ProbabilityOfTwoConsonantsInOneSyllable) { sb.Append(ConsonantSounds[random.GetRandomInt32(ConsonantSounds.Length)]); } if (hyphansBetweenSyllables) { sb.Append('-'); } } if (hyphansBetweenSyllables && sb[sb.Length - 1] == '-') { sb.Remove(sb.Length - 1, 1); } // Yield the phrase and reset state. var result = sb.ToString(); yield return(result); sb.Clear(); } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("Pronouncable", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count); }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?l) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); // Return information about the number of combinations as a JSON object. var result = new JsonCombinationContainer(); var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength); result.combinations = Math.Pow(Characters.Length, length); result.combinations -= (double)Blacklist.Value.Count(x => x.Length == l); // Remove blacklist entries. result.rating = PasswordRatingService.RatePin(result.combinations); return(new JsonNetResult(result)); }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?l, string sym) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); // Return information about the number of combinations as a JSON object. var result = new JsonCombinationContainer(); var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength); var symbols = sym.IsTruthy(DefaultSymbols); var charCount = symbols ? AllCharacters.Length : AlphanumericCharacters.Length; result.combinations = Math.Pow(charCount, length); return(new JsonNetResult(result)); }
public virtual void JoinMulticastGroupAllInterfaces(IPEndPoint remoteEp) { var localIps = IPAddressHelpers.GetUnicastAddresses(ip => ip.AddressFamily == remoteEp.AddressFamily); foreach (var addr in localIps) { try { this.JoinMulticastGroup(remoteEp.Address, addr); } catch (SocketException) { // If we're already joined to this group we'll throw an error so just ignore it } } }
public override void OnActionExecuting(ActionExecutingContext filterContext) { if (IpThrottlerService.HasExceededLimit(IPAddressHelpers.GetHostOrCacheIp(filterContext.HttpContext.Request), filterContext.HttpContext.GetApiKeyId())) { bool isAjaxRequest = false; if (isAjaxRequest) { // TODO: return a friendly message about IP limiting with appropriate HTTP status code. filterContext.Result = new HttpStatusCodeResult(429, "{ 'message':'You have exceeded IP based limits. These will be lifted automatically within 2 hours.'"); } else { // TODO: return plain text details about the error. filterContext.Result = new HttpStatusCodeResult(429, "You have exceeded IP based limits. These will be lifted automatically within 2 hours."); } } }
private IEnumerable <string> SelectPins(IRandomNumberGenerator random, int length, int count) { length = Math.Min(length, MaxLength); count = Math.Min(count, MaxCount); if (count <= 0 || length <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); var sb = new StringBuilder(); var blacklist = Blacklist.Value; for (int c = 0; c < count; c++) { for (int l = 0; l < length; l++) { sb.Append(Characters[random.GetRandomInt32(Characters.Length)]); } var candidate = sb.ToString(); if (!blacklist.Contains(candidate) // 4 digit PINs starting with '19' are more likely, so weight them lower. || (length == 4 && candidate.Substring(0, 2) == "19" && random.GetRandomInt32(0, 3) == 0)) { yield return(candidate); } sb.Clear(); } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("Pin", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count); }
/// <summary> /// Gets the locations to respond with. /// </summary> /// <param name="condition">Condition to use when determining locations.</param> /// <returns></returns> public virtual IEnumerable <string> GetLocations(Func <IPAddress, bool> condition) { Uri uri; if (!Uri.TryCreate(this.Location, UriKind.Absolute, out uri) || (uri.Host != "0.0.0.0" && uri.Host != "localhost")) { yield return(this.Location); } else { foreach (var addr in IPAddressHelpers.GetUnicastAddresses()) { // Don't include the loopback if (IPAddress.IsLoopback(addr)) { continue; } // Skip any addresses not matching our condition if (!condition(addr)) { continue; } var builder = new UriBuilder(uri); if (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { builder.Host = string.Format("[{0}]", addr); } else { builder.Host = addr.ToString(); } yield return(builder.ToString()); } } }
private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count, bool includeSymbols) { length = Math.Min(length, MaxLength); count = Math.Min(count, MaxCount); if (count <= 0 || length <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); var chars = includeSymbols ? AllCharacters : AlphanumericCharacters; var sb = new StringBuilder(); for (int c = 0; c < count; c++) { for (int l = 0; l < length; l++) { sb.Append(chars[random.GetRandomInt32(chars.Length)]); } var result = sb.ToString(); yield return(result); sb.Clear(); } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("AlphaNumeric", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count); }
[OutputCache(Duration = 60 * 60)] // Cache for one hour. #endif public ActionResult Combinations(int?l, string bmp, string asian) { IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1); var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength); var onlyFromBasicMultilingualPlane = bmp.IsTruthy(DefaultBmp); var includeEastAsianCharacters = asian.IsTruthy(DefaultAsian); var allowedCategories = includeEastAsianCharacters ? AsianCategories : DefaultCategories; var mask = onlyFromBasicMultilingualPlane ? 0x0000ffff : 0x001fffff; // This takes ~100ms to calculate on Murray's laptop, so we cache it. // Unless new unicode characters magicly appear, the result will always be the same for our 3 inputs. var cacheKey = (length | (onlyFromBasicMultilingualPlane ? 0x01000000 : 0) | (includeEastAsianCharacters ? 0x02000000 : 0)).ToString("x8"); int keyspace = 0; var maybeKeyspace = MemoryCache.Default[cacheKey]; if (maybeKeyspace == null) { maybeKeyspace = Enumerable.Range(0, 0x001fffff & mask) .Where(cp => !(this.InvalidSurrogateCodePoints(cp) || this.InvalidMaxCodePoints(cp))) .Select(cp => Char.ConvertFromUtf32(cp)) .Where(s => allowedCategories.Contains(Char.GetUnicodeCategory(s, 0))) .Count(); MemoryCache.Default.Add(cacheKey, maybeKeyspace, DateTimeOffset.Now.AddHours(8)); } keyspace = (int)maybeKeyspace; // Return information about the number of combinations as a JSON object. var result = new JsonCombinationContainer(); result.combinations = Math.Pow(keyspace, length); return(new JsonNetResult(result)); }
/// <summary> /// Starts listening on the specified remote endpoints. /// </summary> /// <param name="remoteEps">The remote eps.</param> public void StartListening(params IPEndPoint[] remoteEps) { if (remoteEps == null || remoteEps.Length == 0) { remoteEps = new IPEndPoint[] { Protocol.DiscoveryEndpoints.IPv4 } } ; lock (this.Server) { if (!this.Server.IsListening) { this.Server.StartListening(); } this.Server.EnableBroadcast = true; // Join all the multicast groups specified foreach (IPEndPoint ep in remoteEps.Where(ep => IPAddressHelpers.IsMulticast(ep.Address))) { this.Server.JoinMulticastGroupAllInterfaces(ep); } } }
private IEnumerable <string> SelectPhrases(IRandomNumberGenerator random, int wordCount, int phraseCount, bool spaces, int minChars, int maxChars, NumericStyles whenNumeric, int numbersToAdd, AllUppercaseStyles whenUpper, int uppersToAdd) { if (minChars > maxChars) { yield break; } phraseCount = Math.Min(phraseCount, MaxCount); wordCount = Math.Min(wordCount, MaxWords); if (phraseCount <= 0 || wordCount <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); var sb = new StringBuilder(); var dict = Dictionary.Value; int attempts = 0; ICollection <IMutator> mutators = null; if (whenNumeric != NumericStyles.Never || whenUpper != AllUppercaseStyles.Never) { mutators = new List <IMutator>(); } if (whenNumeric != NumericStyles.Never) { mutators.Add(new NumericMutator() { When = whenNumeric, NumberOfNumbersToAdd = numbersToAdd }); } if (whenUpper == AllUppercaseStyles.Anywhere) { mutators.Add(new UppercaseMutator() { When = UppercaseStyles.Anywhere, NumberOfCharactersToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.StartOfWord) { mutators.Add(new UppercaseMutator() { When = UppercaseStyles.StartOfWord, NumberOfCharactersToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.WholeWord) { mutators.Add(new UppercaseWordMutator() { NumberOfWordsToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.RunOfLetters) { mutators.Add(new UppercaseRunMutator() { NumberOfRuns = uppersToAdd }); } MurrayGrant.ReadablePassphrase.Random.RandomSourceBase randomWrapper = null; if (mutators != null) { randomWrapper = new MurrayGrant.ReadablePassphrase.Random.ExternalRandomSource(random.GetRandomBytes); } for (int c = 0; c < phraseCount; c++) { do { // Generate a phrase. for (int l = 0; l < wordCount; l++) { sb.Append(dict[random.GetRandomInt32(dict.Count)]); sb.Append(' '); } sb.Remove(sb.Length - 1, 1); // Apply mutators. if (mutators != null) { foreach (var m in mutators) { m.Mutate(sb, randomWrapper); } } // Finally, remove spaces if required (as the mutators depend on whitespace to do their work). if (!spaces) { for (int i = sb.Length - 1; i >= 0; i--) { if (sb[i] == ' ') { sb.Remove(i, 1); } } } attempts++; // Ensure the final phrase is within the min / max chars. } while (attempts < MaxAttemptsPerCount && (sb.Length < minChars || sb.Length > maxChars)); if (attempts >= MaxAttemptsPerCount) { sb.Clear(); sb.Append("A passphrase could not be found matching your minimum and maximum length requirements"); } // Yield the phrase and reset state. var result = sb.ToString(); yield return(result); sb.Clear(); attempts = 0; } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("Passphrase", phraseCount, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), phraseCount); }
/// <summary> /// Starts listening on the specified remote endpoints. /// </summary> /// <param name="groups">The remote eps.</param> public virtual void StartListening(params IPAddress[] groups) { if (groups == null || groups.Length == 0) { groups = new[] { Protocol.DiscoveryEndpoints.IPv4 } } ; ForEachSocket(socket => { if (!socket.IsListening) { socket.StartListening(); } /* TODO: might need to update this slightly. It was this way in SsdpSearch: * * if (!this.Server.EnableBroadcast) * this.Server.EnableBroadcast = destinations.Any(ep => ep.Address.Equals(IPAddress.Broadcast)); * */ socket.EnableBroadcast = true; Trace.WriteLine(string.Format("Listening on {0}", socket.LocalEndpoint), AppInfo.Application); // Join all the multicast groups specified foreach (var group in groups.Where(ep => ep.AddressFamily == socket.LocalEndpoint.AddressFamily && IPAddressHelpers.IsMulticast(ep))) { socket.JoinMulticastGroup(group); Trace.WriteLine(string.Format("Interface {0} joined igmp group {1}", socket.LocalEndpoint, group), AppInfo.Application); } }); }
private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count, bool onlyFromBasicMultilingualPlane, bool includeEastAsianCharacters) { length = Math.Min(length, MaxLength); count = Math.Min(count, MaxCount); if (count <= 0 || length <= 0) { yield break; } var allowedCategories = includeEastAsianCharacters ? AsianCategories : DefaultCategories; var sw = System.Diagnostics.Stopwatch.StartNew(); int numberOfCharacters = 0, attempts = 0; var mask = onlyFromBasicMultilingualPlane ? 0x0000ffff : 0x001fffff; var sb = new StringBuilder(); for (int i = 0; i < count; i++) { numberOfCharacters = 0; attempts = 0; sb.Clear(); while (numberOfCharacters < length) { // Get random int32 and create a code point from it. // PERF: can reduce number of bytes required here based on the mask. var codePoint = random.GetRandomInt32(); codePoint = codePoint & mask; // Mask off the top bits, which aren't used. attempts++; // Break if too many attempts. if (attempts > MaxAttemptsPerCodePoint) { continue; } // Surrogate code points are invalid. if (this.InvalidSurrogateCodePoints(codePoint)) { continue; } // Ensure the code point is not outside the maximum range. if (this.InvalidMaxCodePoints(codePoint)) { continue; } // the Int32 to up to 2 Char structs (in a string). var s = Char.ConvertFromUtf32(codePoint); var category = Char.GetUnicodeCategory(s, 0); if (!allowedCategories.Contains(category)) { // Not allowed category. continue; } sb.Append(s); numberOfCharacters++; } var result = sb.ToString(); yield return(result); attempts = 0; } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("Unicode", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count); }
private IEnumerable <string> SelectPhrases(IRandomNumberGenerator random, PhraseStrength strength, int phraseCount, bool includeSpaces, int minChars, int maxChars, NumericStyles whenNumeric, int numbersToAdd, AllUppercaseStyles whenUpper, int uppersToAdd) { if (minChars > maxChars) { yield break; } phraseCount = Math.Min(phraseCount, MaxCount); if (phraseCount <= 0) { yield break; } var sw = System.Diagnostics.Stopwatch.StartNew(); var generator = this.GetGenerator(random); int attempts = 0; ICollection <IMutator> mutators = null; if (whenNumeric != NumericStyles.Never || whenUpper != AllUppercaseStyles.Never) { mutators = new List <IMutator>(); } if (whenNumeric != NumericStyles.Never) { mutators.Add(new NumericMutator() { When = whenNumeric, NumberOfNumbersToAdd = numbersToAdd }); } if (whenUpper == AllUppercaseStyles.Anywhere) { mutators.Add(new UppercaseMutator() { When = UppercaseStyles.Anywhere, NumberOfCharactersToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.StartOfWord) { mutators.Add(new UppercaseMutator() { When = UppercaseStyles.StartOfWord, NumberOfCharactersToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.WholeWord) { mutators.Add(new UppercaseWordMutator() { NumberOfWordsToCapitalise = uppersToAdd }); } else if (whenUpper == AllUppercaseStyles.RunOfLetters) { mutators.Add(new UppercaseRunMutator() { NumberOfRuns = uppersToAdd }); } for (int c = 0; c < phraseCount; c++) { string candidate = ""; do { // Generate a phrase. candidate = generator.Generate(strength, " ", mutators); // Finally, remove spaces if required (as the mutators depend on whitespace to do their work). if (!includeSpaces) { candidate = new string(candidate.Where(ch => ch != ' ').ToArray()); } attempts++; // Ensure the final phrase is within the min / max chars. } while (attempts < MaxAttemptsPerCount && (candidate.Length < minChars || candidate.Length > maxChars)); if (attempts >= MaxAttemptsPerCount) { candidate = "A passphrase could not be found matching your minimum and maximum length requirements"; } // Yield the phrase and reset state. yield return(candidate); attempts = 0; } sw.Stop(); var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault(); RandomService.LogPasswordStat("ReadablePassphrase", phraseCount, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId()); if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request))) { RandomService.AddWebRequestEntropy(this.Request); } IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), phraseCount); }