Estoy generando contraseñas seleccionando palabras aleatorias de un diccionario y contando entropy=words_in_passphrase*log(dictionary_size)/log(2)
. Este algoritmo supone que las palabras se seleccionarán del diccionario con una distribución uniforme.
Creo que el principio de diseño es sólido, pero no estoy seguro de la implementación. Estoy leyendo de /dev/urandom
de bytes suficientes para expresar un índice en el diccionario @words
, y convertir esos bytes en un entero de manera algo incómoda.
El código parece para funcionar correctamente, pero ¿hay alguna advertencia a Perl o / dev / urandom que distorsione los resultados? Fuente completa.
my $entropy_per_word = log (@words) / log (2);
my $pw = "";
my $pw_entropy = 0;
# maybe /dev/random ?
open my $random_source, '<', "/dev/urandom" or die "Could not open /dev/urandom";
binmode $random_source or die $!;
my $random_buffer = "";
my $random_bytes = ceil ($entropy_per_word / 8);
die "Tried to read no random bytes." if ($random_bytes < 1);
while ($pw_entropy < $entropy)
{
die "Could not read random bytes"
if ($random_bytes !=
read ($random_source, $random_buffer, $random_bytes));
my @bytes = unpack 'C ' x $random_bytes, $random_buffer;
my $n = 0;
foreach (@bytes)
{
$n *= 256;
$n += $_ * 1;
}
next if ($n >= @words); # don't use %, it will bias the randomness
$pw .= ' ' if ("" ne $pw);
foreach (split //, $words[$n])
{
# sprinkle some capitalization for good measure
$_ = uc if (rand > 0.8);
$pw .= $_;
}
$pw_entropy += $entropy_per_word;
}