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

Re: Generate a session ID

by BrowserUk (Patriarch)
on Dec 03, 2005 at 14:55 UTC ( [id://513809]=note: print w/replies, xml ) Need Help??


in reply to Generate a session ID

Check the rand function used by your version of Perl. Specifically, check for the number of randbits it is configured for:

P:\test>Perl -v This is perl, v5.8.7 built for MSWin32-x86-multi-thread (with 7 registered patches, see perl -V for more detail) ... P:\test>Perl -V:randbits randbits='15';

Which means that with AS perl, this snippet will only ever produce 32768 unique ids:

#! perl -slw use strict; my %cache; $cache{ sprintf("%0.8x",rand()*0xffffffff) } = undef for 1 .. 1_000_00 +0; printf "1 million attempts produced %d keys\n", scalar keys %cache; printf "between %s and %s\n", (sort keys %cache)[ 0, -1 ]; __END__ P:\test>junk 1 million attempts produced 32768 keys between 00000000 and fffdffff

I'm not sure what the mathematical probability is for picking duplicates from a pool 2^15 values, but in practice, it produces very, very few unique values before it repeats itself:

#! perl -slw use strict; my %cache; my $u = sprintf("%0.8x",rand()*0xffffffff); until( exists $cache{ $u } ) { $cache{ $u } = undef; $u = sprintf("%0.8x",rand()*0xffffffff); } printf "Produced %d unique keys before duplicating\n", scalar keys %ca +che; printf "between %s and %s\n", (sort keys %cache)[ 0, -1 ]; __END__ P:\test>junk Produced 454 unique keys before duplicating between 00bdffff and ff89ffff P:\test>junk Produced 273 unique keys before duplicating between 013dffff and feb5ffff P:\test>junk Produced 84 unique keys before duplicating between 0183ffff and fe5bffff P:\test>junk Produced 94 unique keys before duplicating between 001bffff and fbc1ffff

You can extend the range almost linearly by multiplying two calls to rand:

#! perl -slw use strict; my %cache; $cache{ sprintf( "%0.8x", rand() * rand() * 0xffffffff ) } = undef for + 1 .. 1_000_000; printf "1 million attempts produced %d keys\n", scalar keys %cache; printf "between %s and %s\n", (sort keys %cache)[ 0, -1 ]; __END__ P:\test>junk 1 million attempts produced 994758 keys between 00000000 and ffae0137

but even then, the number of uniques you will get before repeats is dismally low:

Produced 17891 unique keys before duplicating between 00000000 and fba0116f P:\test>junk Produced 1957 unique keys before duplicating between 0008e633 and fb575407 P:\test>junk Produced 30229 unique keys before duplicating between 00000000 and fdeaed07 P:\test>junk Produced 10830 unique keys before duplicating between 0000eedf and ff441eff P:\test>junk Produced 15537 unique keys before duplicating between 00000000 and fe068a77

All in all, a better session id generator than this would be strongly advisable.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Generate a session ID
by thor (Priest) on Dec 03, 2005 at 17:21 UTC
    I'm not sure what the mathematical probability is for picking duplicates from a pool 2^15 values, but in practice, it produces very, very few unique values before it repeats itself:
    This is an application of the Birthday Paradox, which isn't really a paradox, just counter-intuitive. Here's a little code that shows how many you have to pick before your chances are greater than 50% of getting a dupe. The number is quite a bit lower than you would think.
    my $prod = 1; foreach my $num (1..2**15) { printf("%5d => %0.6f\n", $num, $prod); die "Threshold reached\n"if $prod <= 0.5; $prod *= (2**15 - $num)/2**15; }
    Update: In looking back, it may be a little unclear what the program above produces. It prints a list of pairs in the form of "x => y". 'x' is the number of IDs that you've generated, 'y' is the probability that you've chosen a unique one. I also had a typo (one too many '}'s) and a slight logic error (the third line used to be the first).

    thor

    The only easy day was yesterday

Re^2: Generate a session ID
by Spidy (Chaplain) on Dec 04, 2005 at 19:28 UTC
    I checked it out on the system I was running it on...I have 48 randbits, and it produces 99,000 keys in 1 million attempts.

    That being said, does anyone know of a good way to generate something like a session ID that's unique? I can't install modules.

      I can't install modules.

      Do what you can to change that parameter.

      It will help you more than a little right now, and we just can't estimate how much it will help in the future.

      Cheers, Sören

      This won't be speedy but you could use fewer rands by adapting your original approach.

      print new_session_id(), $/; sub new_session_id { my $id = ''; for ( 1 .. 32 ) { $id .= sprintf "%x", rand(16); } return $id; }

      You should also see if you've got Digest/Digest::MD5 available on your system. You can do something like:

      use Digest::MD5 "md5_hex"; my @user_info = map { $ENV{$_} } grep { /USER|REMOTE/ } keys %ENV; print md5_hex( rand() . join('', @user_info) );

      Don't forget to do a search for unique ID too, there are many points of departure: Google on the pen for "unique id." Also, try vanilla "unique."

        Well, I'm using this method, right now:

        • When user A signs up, a new row is added to the MySQL table with their info.
        • They have a unique ID number assigned to them(3,4,etc) that auto-increments.
        • I then encrypt their ID number, using a cryptsalt of x. This becomes their unique session ID.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://513809]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-26 07:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found