#!/usr/bin/perl -I/usr/lib/perl5/site_perl/5.8.3/

use strict;

use Getopt::Std;
use Crypt::RandPasswd;

my %opt;
getopts('nc:',\%opt);

my $is_with_num = $opt{n};
my $length = $opt{c};
die "password length should be specified" unless $length > 0;

my $pswd = '';
my $is_num_added = 0;

## compose string from number of syllables
## insert numbers between syllables if needed (randomized)

## we will exit earlier than counter reach length
for(my $i=0; $i < $length; $i++) {

	## get syllable
	## Crypt::RandPasswd::get_syllable hangs sometime
	## my ($syllable, @symb) = Crypt::RandPasswd::get_syllable(4);
	my $syllable;
	$SIG{ALRM} = sub { die "timeout"; };
	eval { alarm(1); $syllable = Crypt::RandPasswd->word(2,4); };
	alarm(0);
	if ($@) { sleep(1); next; }

	## add syllable
	$pswd .= $syllable;
	last if length($pswd) >= $length;

	## add number?
	if($is_with_num && (length($length)/length($pswd)) > rand(1)) {
		$pswd .= int(rand(10));
		$is_num_added = 1;
	}
}

## cut string if needed
$pswd = substr($pswd,0,$length) if length($pswd) > $length;

## force number if not added yet
if($is_with_num && !$is_num_added) {
	substr($pswd,int(rand(length($pswd))),1,int(rand(10)));
}

## output password
print $pswd;

exit;

