#!/usr/bin/perl # -*- mode: cperl; coding: utf-8; -*- use strict; use warnings; use utf8; use lib "/h/hamren/src/post/lib", "."; my $rval = do "common.pm" || die "$0: common.pm failed ($!) [$@]"; #--- Single-line common initializer #--- End of header my $text = em("text"); my $s2 = "  "; my $s3 = "   "; my $s4 = "    "; post( header(), p("A good password should be randomly generated, have a certain level of randomness, and not be too difficult to type.", " The generator below takes as argument a pattern, like '«000»' for three decimal digits,", " '«lll0»' for three letters followed by a decimal digit, or '«Cwc0»' for an uppercase consonant, a lowercase wowel, a lowercase consonant and a decimal digit.", " A second argument is a repeat count, four by default."), p(" To generate passwords of 16 decimal digits in four groups, say:"), css("table.narrow td { min-width: 1pt }"), table({class => "tight10 narrow", style=>"white-space: pre"}, trow(td('«$ password-generator.pl 0000 4»')), trow(td("«« $s3 8058460983365774 $s3 8058 4609 8336 5774»»")), trow(td("««$s3 4609833657742695 $s3 4609 8336 5774 2695»»")), trow(td("««$s3 8336577426958145 $s3 8336 5774 2695 8145»»")), trow(td("««$s3 5774269581454664 $s3 5774 2695 8145 4664»»")), trow(td("««$s3 2695814546642111 $s3 2695 8145 4664 2111»»")), trow(td("««$s3 8145466421116990 $s3 8145 4664 2111 6990»»")), trow(td("««$s3 4664211169900297 $s3 4664 2111 6990 0297»»")), trow(td("««$s3 2111699002979514 $s3 2111 6990 0297 9514»»")), trow(td("««$s3 6990029795149225 $s3 6990 0297 9514 9225»»")), trow(td("««$s3 0297951492251091 $s3 0297 9514 9225 1091»»")), trow(td("««$s3 9514922510914616 $s3 9514 9225 1091 4616»»")), trow(td("««$s3 9225109146163033 $s3 9225 1091 4616 3033»»")), trow(td('«About 53.2 bits of randomness (16.0 decimal digits, 8.1 ASCII-94 characters)»')) ), p("The 0000 indicates four digits, and 4 is the number of repetitions.", " The left half is the \"raw\" password, the right half is the same password, with spaces printed between the groups.", " It should come as no suprise that the program reports 16 decimal digits of randomness.", " ASCII-94 refers to all the printable ASCII character, character codes 33 to 126. "), p("Only pick one password from the list, since nearby passwords are related.", " For each new password, the leftmost group is dropped and replaced by a new group to the right.", " Look at the '«5774»' at the far right of the first password, and see how it moves to the left for each new password.", " After making an appearance at the far left, it is dropped.", "" ), p("To generate passwords of 12 characters in three groups, where each group is three letters and a digit, say:"), table({class => "tight10"}, trow(td('«$ password-generator.pl aaa0 4»')), trow(td("««$s3 fhj3sfl0djt2 $s3 fhj3 sfl0 djt2»»")), trow(td("««$s3 sfl0djt2vqh6 $s3 sfl0 djt2 vqh6»»")), trow(td("««$s3 djt2vqh6iec4 $s3 djt2 vqh6 iec4»»")), trow(td("««$s3 vqh6iec4wyu1 $s3 vqh6 iec4 wyu1»»")), trow(td("««$s3 iec4wyu1pqa3 $s3 iec4 wyu1 pqa3»»")), trow(td("««$s3 wyu1pqa3kyl3 $s3 wyu1 pqa3 kyl3»»")), trow(td("««$s3 pqa3kyl3jdq7 $s3 pqa3 kyl3 jdq7»»")), trow(td("««$s3 kyl3jdq7nmx7 $s3 kyl3 jdq7 nmx7»»")), trow(td("««$s3 jdq7nmx7evh8 $s3 jdq7 nmx7 evh8»»")), trow(td("««$s3 nmx7evh8wzu7 $s3 nmx7 evh8 wzu7»»")), trow(td("««$s3 evh8wzu7zee6 $s3 evh8 wzu7 zee6»»")), trow(td('«About 52.3 bits of randomness (15.7 decimal digits, 8.0 ASCII-94 characters)»')), ), p("While these passwords are shorter, they have about the same randomness as the previous 16-digit passwords.", " This is because there are more letters than digits, creating about the same number of different passwords."), p("And you can have an equally strong, but even shorter, password by using the full ASCII-94 character set:"), table({class => "tight10"}, trow(td('«password-generator.pl @@@@ 2»')), trow(td("««$s3 ,]D1Ko+~ $s3 ,]D1 Ko+~»»")), trow(td("««$s3 Ko+~j8He $s3 Ko+~ j8He»»")), trow(td("««$s3 j8Hee4&h $s3 j8He e4&h»»")), trow(td("««$s3 e4&hdl\"3 $s3 e4&h dl\"3»»")), trow(td("««$s3 dl\"3ZD[[ $s3 dl\"3 ZD[[»»")), trow(td("««$s3 ZD[[ws#G $s3 ZD[[ ws#G»»")), trow(td("««$s3 ws#GhWQn $s3 ws#G hWQn»»")), trow(td("««$s3 hWQneks= $s3 hWQn eks=»»")), trow(td("««$s3 eks=T,#O $s3 eks= T,#O»»")), trow(td("««$s3 T,#OK\@=9 $s3 T,#O K\@=9»»")), trow(td("««$s3 K\@=9If.r $s3 K\@=9 If.r»»")), trow(td('«About 52.4 bits of randomness (15.8 decimal digits, 8.0 ASCII-94 characters)»')) ), p("Passwords such as these may become more readable using the '«-w»' (wide) option:"), table({class => "tight10"}, trow(td('«password-generator.pl -w @@@@ 2»')), trow(td("««$s3 /|h>R5zt $s3 /|h> R5zt $s4 / | h > $s2 R 5 z t»»")), trow(td("««$s3 R5ztM6m\$ $s3 R5zt M6m\$ $s4 R 5 z t $s2 M 6 m \$»»")), trow(td("««$s3 M6m\$J-KN $s3 M6m\$ J-KN $s4 M 6 m \$ $s2 J - K N»»")), trow(td("««$s3 J-KN'!%E $s3 J-KN '!%E $s4 J - K N $s2 ' ! % E»»")), trow(td("««$s3 '!%E=4=n $s3 '!%E =4=n $s4 ' ! % E $s2 = 4 = n»»")), trow(td("««$s3 =4=nGw7s $s3 =4=n Gw7s $s4 = 4 = n $s2 G w 7 s»»")), trow(td("««$s3 Gw7sF:(W $s3 Gw7s F:(W $s4 G w 7 s $s2 F : ( W»»")), trow(td("««$s3 F:(WBi~F $s3 F:(W Bi~F $s4 F : ( W $s2 B i ~ F»»")), trow(td("««$s3 Bi~Fw'WO $s3 Bi~F w'WO $s4 B i ~ F $s2 w ' W O»»")), trow(td("««$s3 w'WOL?|5 $s3 w'WO L?|5 $s4 w ' W O $s2 L ? | 5»»")), trow(td("««$s3 L?|5%LCJ $s3 L?|5 %LCJ $s4 L ? | 5 $s2 % L C J»»")), trow(td("««$s3 %LCJliR` $s3 %LCJ liR` $s4 % L C J $s2 l i R `»»")), trow(td("««$s3 liR`nFuW $s3 liR` nFuW $s4 l i R ` $s2 n F u W»»")), trow(td("««$s3 nFuWW/,# $s3 nFuW W/,# $s4 n F u W $s2 W / , #»»")), trow(td("««$s3 W/,#X>0a $s3 W/,# X>0a $s4 W / , # $s2 X > 0 a»»")), trow(td('«About 52.4 bits of randomness (15.8 decimal digits, 8.0 ASCII-94 characters)»')) ), p("To generate passwords of 16 characters in four groups, where each group is consonant + wovel + consonant + digit, say:"), table({class => "tight10"}, trow(td('«$ password-generator.pl cwc0 4»')), trow(td("««$s3 zyr0zih6qat0kus2 $s3 zyr0 zih6 qat0 kus2»»")), trow(td("««$s3 zih6qat0kus2xyr0 $s3 zih6 qat0 kus2 xyr0»»")), trow(td("««$s3 qat0kus2xyr0saj4 $s3 qat0 kus2 xyr0 saj4»»")), trow(td("««$s3 kus2xyr0saj4gan9 $s3 kus2 xyr0 saj4 gan9»»")), trow(td("««$s3 xyr0saj4gan9tif6 $s3 xyr0 saj4 gan9 tif6»»")), trow(td("««$s3 saj4gan9tif6hyq1 $s3 saj4 gan9 tif6 hyq1»»")), trow(td("««$s3 gan9tif6hyq1naq2 $s3 gan9 tif6 hyq1 naq2»»")), trow(td("««$s3 tif6hyq1naq2fav6 $s3 tif6 hyq1 naq2 fav6»»")), trow(td("««$s3 hyq1naq2fav6xoc8 $s3 hyq1 naq2 fav6 xoc8»»")), trow(td("««$s3 naq2fav6xoc8bod8 $s3 naq2 fav6 xoc8 bod8»»")), trow(td("««$s3 fav6xoc8bod8fus4 $s3 fav6 xoc8 bod8 fus4»»")), trow(td('«About 58.2 bits of randomness (17.5 decimal digits, 8.9 ASCII-94 characters)»')) ), p("Here are all the characters that can go into a pattern:"), table({class => "tight10 narrow"}, trow(td('«+»'), td("$s3 Punctuation and special characters")), trow(td('«0»'), td("$s3 Digits" )), trow(td('«H»'), td("$s3 Hexadecimal digits, uppercase" )), trow(td('«h»'), td("$s3 Hexadecimal digits, lowercase" )), trow(td('«@»'), td("$s3 All printable ASCII characters" )), trow(td('«A»'), td("$s3 Digits and uppercase letters (alphanumeric)" )), trow(td('«L»'), td("$s3 Uppercase letters (alphabetic)" )), trow(td('«C»'), td("$s3 Uppercase consonants" )), trow(td('«W»'), td("$s3 Uppercase wowels" )), trow(td('«a»'), td("$s3 Digits and lowercase letters (alphanumeric)" )), trow(td('«l»'), td("$s3 Lowercase letters" )), trow(td('«c»'), td("$s3 Lowercase consonants" )), trow(td('«w»'), td("$s3 Lowercase wowels" )), trow(td('«z»'), td("$s3 Upper- and lower-case letters" )) ), p("Using patterns decreases the randomness, but that can be countered by using longer passwords."), p("For most uses, such as logging in to a web site, the password need not be very long.", " There is an interval of several seconds between attempts, and the number of attemps is often limited to just a few.", " With four digits and three attempts, an attacker has a 3 in 10,000 chance.", " This is what most banks and credit card companies deem safe, although they are probably under pressure from customers, who do not want six or eight digit PIN codes."), p("Using '«cwc0»' generates passwords that are almost pronouncable.", " With a repeat count of just two, there are almost 631 miljon passwords, giving the attacker a 1 in 210 miljon chance."), h2("Download"), p("There is no download; just copy and paste the source."), h2("The source code"), source_file("./lh-password-generator.pl.source"), footer() ); __END__