Thursday, April 3, 2008

A Random Password Generator

A good password should be as random as possible, not just pseudo-random. Hence password generator programs shouldn't depend on the library functions like rand() because they generate reproducible "random" numbers whose "randomness" depends solely on the seed.

Here is a simple password generator in Perl which uses random bits from /dev/random to generate as good a password as can be made on a Unix machine. The password length can be specified as an optional argument. By default, it generates a password of length 10.


#!/usr/bin/perl -w

# (C) Minus i 2008
# Permission is granted to copy, modify and/or redistribute this under the
# terms of GNU General Public Licence version 3, or later.

use bignum;   # for arithmetic that may transgress
              # from the integer field

use Config;   # to know the integer sizes in the system

$len=$ARGV[0]>0?int $ARGV[0]:10; # by default, generate a password of length 10

open R, "/dev/random", or die "couldn't open: $!";

# password contains characters from this array
@CHR=('a'..'z','A'..'Z',0..9,' ',
qw(~ ! @ $ % ^ & * - _ = + \ | ; : < > . / ? ));


$intsize=$Config{ivsize};
$maxint=(1<<8*$intsize)-1;># The idea is simple. To generate a character, we read $intsize bytes
# from the random file and use it to get a random number in the range of
# 0 and $#CHR. With this, we just index the array.

read R, $buf,$intsize*$len;


$pw="";

# The Unpack function is used to get $len integers of $intsize bytes each
# from the string $buf
map {$pw.=$CHR[int (@CHR * ($_/(1+$maxint)))]} unpack("I$intsize"x$len,$buf);

# Work over, print the password
print"$pw\n";




Caution: Since the program uses /dev/random, in GNU/Linux systems it may block until the system has gathered enough entropy. You can use /dev/urandom to generate less random passwords faster, but I would advise against it. While you are at it, generate highly secure passwords.

No comments: