Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

If I try
perl -w print crypt( (time) x 2);
I get error Not enough arguments for crypt, it's because of prototypes right? I try workaround
perl -w print &crypt( (time) x 2);
but get Undefined subroutine &main::crypt. What do I do?

Replies are listed 'Best First'.
Re: crypt prototype and ( time ) x 2
by liz (Monsignor) on Oct 08, 2003 at 09:15 UTC
    To me this falls in the category:
    Q: Doctor, it hurts when I press here
    A: Then don't press there!
    

    How about crypt( time,time ), or probably better:

    my $time; crypt( $time = time,$time );

    Liz

    Update:
    Moved lexical outside of crypt(), as second $time would be undef because it would refer to a non-existing global $time (which shows nicely when using strict). Thanks to broquaint for pointing this out.

Re: crypt prototype and ( time ) x 2
by Abigail-II (Bishop) on Oct 08, 2003 at 09:49 UTC
    Either do what Liz said, or if you really don't want to create extra variables, do something like:
    $ perl -wle 'print sub {crypt $_ [0], $_ [0]} -> (time)'

    Having said that, one should realize that the output only changes every 100 seconds, as crypt only looks at the first 8 characters, and time returns nowadays a 10 digit number.

    Abigail

      If you wanted to get around the time only changing every 100 seconds problem use:
      $time = time() % 100000000; # time mod a number with 8 zeros
      That will give you a different time-seeded number every second, being the last 8 digits of the time returned by the time function.
      ----
      If I melt dry ice can I swim without getting wet?
Re: crypt prototype and ( time ) x 2
by broquaint (Abbot) on Oct 08, 2003 at 09:47 UTC
    but get Undefined subroutine &main::crypt
    This is because prepending subroutines with an ampersand forces a user defined function to be called. If you're really determined to override the default prototype, you could just subvert crypt with the subs module e.g
    use subs 'crypt'; sub crypt { CORE::crypt($_[0], $_[1]) } print crypt( (time) x 2 );
    For a good rant^Warticle on prototypes in perl see Tom Christiansen's FMTEYEWTK about Prototypes in Perl.
    HTH

    _________
    broquaint

Re: crypt prototype and ( time ) x 2
by MidLifeXis (Monsignor) on Oct 08, 2003 at 17:21 UTC

    This response does not answer the question directly, but asks the AM to evaluate what is trying to be accomplished.

    You will not get the randomness in your seed that you are expecting. Your seed will always be '10' (at least for the next ~ 34000000 seconds). Even if you use DentArthurDent's suggestion, you are still only using 100 out of 64*64 possible salts, because you are ignoring 54 (I think) other valid characters which can randomize the salt.

    To randomize the salt a little more, you may want to use some form of pack to convert time() into a base64 string, and use that as your salt.

    Update: Fixed DentArthurDent's name. Sorry :)

    Update-2: Fixed Speelink mesteaks.

Re: crypt prototype and ( time ) x 2
by ambrus (Abbot) on Oct 10, 2003 at 11:11 UTC
    The problem is, that crypt has a prototype ($$). I've met this problem with select: I tried to write select +(undef)x3, 0.4; but that won't work for exactly the same reason. As a solution, you can write a wrapper function: sub cryp{crypt$_[0],$_[1]};cryp +(time)x2;