I am trying to perform some analysis on a text file with approximately ten million lines containing passwords. I was doing this by reading each line of the file, creating a class with the value as a parameter, and then adding that class to a list. After line 4,000,000 I get an out of memory exception. Short of storing everything in a SQL database, is there anything else that could be done?
Edit: What I am trying to do is take the password, add it to a Credential object, and then add that to a list.
public class Credential
{
public string Password { get; set; }
public static readonly List<string> specialCharacters = new List<string> { "@", "!", "~", "*", "^", "&", "\\", "/", "#", "$", "%", "<", ">", ".", ",", "?", ")", "(", "'", "\"", "+", "=", "_", "-", ";", ":", "{", "}", "]", "[", };
public Credential(string password)
{
this.Password = password;
this.Mapping = new Dictionary<int, CredentialValueType>();
for (var i = 0; i < this.Length; i++)
{
this.Mapping.Add(i, new CredentialValueType(this.Password[i]));
}
}
public Dictionary<int, CredentialValueType> Mapping { get; private set; }
public int Length
{
get
{
return this.Password.Length;
}
}
public bool HasUppercase
{
get
{
return this.Password.Any(c => char.IsUpper(c));
}
}
public bool HasLowercase
{
get
{
return this.Password.Any(c => char.IsLower(c));
}
}
public bool HasNumber
{
get
{
return this.Password.Any(c => char.IsNumber(c));
}
}
public bool HasSpecialCharacter
{
get //Verify that this works right...
{
return this.Password.Where(a => specialCharacters.Contains(a.ToString())).Count() > 0;
}
}
}
public struct CredentialValueType
{
public char Value { get; set; }
public ValueType ValueType { get; set; }
public CredentialValueType(char val)
{
this = new CredentialValueType();
this.Value = val;
if (char.IsUpper(val)) this.ValueType = ValueType.UpperCase;
else if (char.IsLower(val)) this.ValueType = PasswordStats.ValueType.LowerCase;
else if (char.IsNumber(val)) this.ValueType = PasswordStats.ValueType.Number;
else this.ValueType = PasswordStats.ValueType.SpecialCharacter;
}
}
My function is as follows:
public class PasswordAnalyzer
{
public IList<Credential> Credentials { get; private set; }
public PasswordAnalyzer(string file, int passwordField = 0, Delimiter delim = Delimiter.Comma)
{
this.Credentials = new List<Credential>();
using (var fileReader = File.OpenText(file)) //Verify UTF-8
{
using (var csvReader = new CsvHelper.CsvReader(fileReader))
{
csvReader.Configuration.Delimiter = "\t";
while (csvReader.Read())
{
var record = csvReader.GetField<string>(passwordField);
this.Credentials.Add(new Credential(record));
System.Diagnostics.Debug.WriteLine(this.Credentials.Count);
}
}
}
}
}