Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Golfing password creation

by kyle (Abbot)
on Jul 29, 2009 at 02:49 UTC ( #784102=perlmeditation: print w/replies, xml ) Need Help??

When I need to set an initial password for someone at the office, I turn to this simple program:

use strict; use warnings; my @alphabet = ( '0' .. '9', 'a' .. 'z', 'A' .. 'Z' ); my $length = shift @ARGV || 8; my $out = ''; while ( length $out < $length ) { $out .= $alphabet[ rand @alphabet ]; } print "$out\n";

A coworker remarked recently, "you're really not trying to make this easy, are you." Well, no.

This evening I thought about golfing this down to a one liner to make it easier to paste into a chat, and this is what I came up with:

perl -E '@a=("0".."9","A".."Z","a".."z");$o.=$a[rand@a]while 8>length$ +o;say$o'

I don't doubt that this could be improved greatly. Any monk who wants to play along should try to generate passwords of 8–15 characters from an alphabet that includes letters and non-letters (/\w/ and /\W/). The more secure the results, the better.

I'd consider a side discussion of manual password selection methods also to be on topic. My personal favorite is to take the initials of some phrase that I can recall reliably, usually a quote from a movie or a song lyric ("happy birthday to you" would be "hb2U"). At a company I used to work for, we'd set root on all the machines using different parts of a single song. If I was caught without my password list, I could go through the song phrase by phrase and find the password to whatever I was trying to access. That didn't happen much since I had the most commonly used ones memorized in a day or two.

Replies are listed 'Best First'.
Re: Golfing password creation
by moritz (Cardinal) on Jul 29, 2009 at 06:36 UTC
    Without changing your algorithm in any way, you can gain a few characters by removing unnecessary quotes, and substituting $o with $_. Since say and length both default to $_ the change of the variable removes four extra characters.
    perl -E '@a=(0..9,A..Z,a..z);$_.=$a[rand@a]while 8>length;say'

    And here's a completely non-golfed Perl 6 version that's even shorter:

    perl6 -e 'say (0..9, "A".."Z", "a".."z").pick(8, :repl)' JIEFoUyiq

    On my Linux box this is even shorter:

    $ pwgen -s 8 1 mUM6fAiz

    But I guess not using Perl in a golfing challenge is cheating ;-)

Re: Golfing password creation
by sundialsvc4 (Abbot) on Jul 29, 2009 at 03:10 UTC

    The bottom-line, in this particular case, is quite simple:   (no offense, but...) “do not listen too-much to the idle comments of your co-workers!”   :-D

    When you are generating an initial-password, just about anything you can dream up will do just-as-well as anything else you could have dreamed up.   Therefore, just take whatever's easiest, and call it a day. Your original algorithm is just as suitable as anything else could possibly have been. Beyond that point, “you're thinking too much.”

    FISI = “(!!) It.. Ship It!”

Re: Golfing password creation
by jdporter (Canon) on Jul 29, 2009 at 18:07 UTC

    Text::Password::Pronounceable is one of several modules in this space.

    perl -MText::Password::Pronounceable -e "print Text::Password::Pronoun +ceable->generate(6, 10);"
    Between the mind which plans and the hands which build, there must be a mediator... and this mediator must be the heart.
Re: Golfing password creation
by GrandFather (Sage) on Jul 29, 2009 at 03:13 UTC

    Slightly less efficient and includes _ as a valid character, but shorter:

    ($a.=chr rand 128)=~s/[^\w\d]//while length$a<8;say$a

    or without the _:

    ($a.=chr rand 128)=~s/[^0-9a-zA-Z]//while length$a<8;say$a

    True laziness is hard work
Re: Golfing password creation
by shmem (Canon) on Jul 29, 2009 at 11:06 UTC
    perl -le 'print map+(0..9,a..z,A..Z)[rand 62],1..(pop||8)'
Re: Golfing password creation
by Porculus (Hermit) on Jul 29, 2009 at 21:10 UTC

    Shortest I can come up with that doesn't produce any very obvious patterns is

    perl -E 'say crypt$$,rand$$'

    Which matches JavaFan's best all-digits solution for stroke count, but improves on it by using the full alphanumeric character set (plus . and /).

Re: Golfing password creation
by fullermd (Priest) on Jul 30, 2009 at 08:25 UTC
    $o.=$a[rand@a]while 8>length$o

    You can shave a few chars off using for and a range. I think it's more readable too (is that a positive or negative in golf? :)

    $o.=$a[rand@a]for 1..8
Re: Golfing password creation
by JavaFan (Canon) on Jul 29, 2009 at 12:00 UTC
    Picks from a subset (well, just numbers...) of \w, but does wonders for your golf score:
    perl -wE 'say substr rand,2,8' perl -wE 'say int rand 10**8' # Won't show leading 0's.