My today's goal was to create a function, which would evaluate the entropy of a given string password. It's mostly about how random the password is.
This little code is based on the C# code from Jeff Atwood answer post on Calculating entropy of a string
Based on the wikipedia article I checked this as ok, still I am unsure if the logarithms are ok, or not, but it seems to work.
Let me know, please, if you see any problem with this:
function TPassword.GetEntropy: Extended;
type
TDictionary = specialize TFPGMap<Char, Integer>;
var
Dictionary: TDictionary;
I: Integer;
Chr: Char;
PasswordLength: Integer;
Frequency: Extended;
begin
// dictionary initialization
Dictionary := TDictionary.Create;
try
// in this cycle we add distinct keys into mapped dictionary with value 1
// if the key (char) is already there, we increase the value
for I := 1 to Length(FPassword) do begin
Chr := FPassword[I];
if Dictionary.IndexOf(Chr) = -1
then Dictionary.Add(Chr, 1)
else Dictionary[Chr] := Dictionary[Chr] + 1;
end;
// now that we went through the string and mapped its content,
// we have for password 'abbbgg' map like a=>1, b=>3, g=>2
PasswordLength := Length(FPassword);
Result := 0;
Frequency := 0;
// - in this cycle we go through each dictionary item
// - first we take the number of its occurrences in the string
// and divide it with password length, let's call it frequency
// - then there is the main part where we multiply the frequency
// with natural logarithm of frequency divided by natural logarithm of 2
// and we are adding it to the result until we went through all keys
for I := 0 to Dictionary.Count - 1 do begin
Frequency := Dictionary.Data[I] / PasswordLength;
Result := Result - (Frequency * (Ln(Frequency) / Ln(2)));
end;
finally
// dictionary freeing
Dictionary.Free;
end;
end;