/// <summary> /// Given the path of a file containing a count, followed by a space, followed by a password, /// this method reads in the distribution and creates a password selector that can provide /// passwords sampled from that distribution. /// </summary> /// <param name="pathToWeightedFrequencyFile"></param> private void LoadPasswordSelector(string pathToWeightedFrequencyFile) { _passwordSelector = new WeightedSelector <string>(); // Created a weighted-random selector for paasswords based on the RockYou database. using (System.IO.StreamReader file = new System.IO.StreamReader(new FileStream(pathToWeightedFrequencyFile, FileMode.Open, FileAccess.Read))) { string lineWithCountFollowedBySpaceFollowedByPassword; while ((lineWithCountFollowedBySpaceFollowedByPassword = file.ReadLine()) != null) { lineWithCountFollowedBySpaceFollowedByPassword = lineWithCountFollowedBySpaceFollowedByPassword.Trim(); int indexOfFirstSpace = lineWithCountFollowedBySpaceFollowedByPassword.IndexOf(' '); if (indexOfFirstSpace < 0 || indexOfFirstSpace + 1 >= lineWithCountFollowedBySpaceFollowedByPassword.Length) { continue; // The line is invalid as it doesn't have a space with a password after it } string countAsString = lineWithCountFollowedBySpaceFollowedByPassword.Substring(0, indexOfFirstSpace); ulong count; if (!ulong.TryParse(countAsString, out count)) { continue; // The count field is invalid as it doesn't parse to an unsigned number } string password = lineWithCountFollowedBySpaceFollowedByPassword.Substring(indexOfFirstSpace + 1); _passwordSelector.AddItem(password, count); } } }
/// <summary> /// Create a new selector that only contains the first <paramref name="count"/> items of this selector. /// </summary> /// <param name="count">The number of values to keep</param> /// <returns>The new selector that has only the first <paramref name="count"/> items.</returns> public WeightedSelector <T> TrimToInitialItems(int count) { WeightedSelector <T> trimmed = new WeightedSelector <T>(); count = Math.Min(count, _items.Count); trimmed._items.AddRange(_items.Take(count)); trimmed._cumulativeWeight.AddRange(_cumulativeWeight.Take(count)); return(trimmed); }
public WeightedSelector <T> TrimToRemoveInitialItems(int count) { WeightedSelector <T> trimmed = new WeightedSelector <T>(); count = Math.Min(count, _items.Count); double weightRemoved = _cumulativeWeight[count]; trimmed._items.AddRange(_items.Skip(count)); trimmed._cumulativeWeight.AddRange(_cumulativeWeight.Skip(count).Select(x => x - weightRemoved)); return(trimmed); }
public SimulatedPasswords(DebugLogger logger, ExperimentalConfiguration config) { _logger = logger; _logger.WriteStatus("Loading popular password file"); LoadPasswordSelector(config.PasswordFrequencyFile); if (config.PopularPasswordsToRemoveFromDistribution > 0) { _passwordSelector = _passwordSelector.TrimToRemoveInitialItems(config.PopularPasswordsToRemoveFromDistribution); } _logger.WriteStatus("Loading passwords known to be common by the algorithm before the attack"); LoadKnownPopularPasswords(config.PreviouslyKnownPopularPasswordFile); _logger.WriteStatus("Creating common password selector"); _commonPasswordSelector = _passwordSelector.TrimToInitialItems( (int)config.NumberOfPopularPasswordsForAttackerToExploit); _logger.WriteStatus("Finished creating common password selector"); _logger.WriteStatus("Creating list of most common passwords"); OrderedListOfMostCommonPasswords = _passwordSelector.GetItems(); _logger.WriteStatus("Finished creating list of most common passwords"); }