Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Re: Need a wait to generate a 4 digit "PIN" number

by polettix (Vicar)
on Dec 16, 2007 at 03:45 UTC ( [id://657249]=note: print w/replies, xml ) Need Help??

in reply to Need a wait to generate a 4 digit "PIN" number

This kinda smells of homework and you didn't show your efforts so far... so no code examples for now :)

Concatenate the three "bits of data" in some way (e.g. join), calculate some hash function over it (e.g. MD5 using Digest::MD5) and extract an integer from this hash (e.g. unpack). Calculate the rest modulo 10000 (perlop, look for %) and use sprintf to get a 4-digits zero-padded representation -- you're done.

Note that this does not guarantee that the combinations from 0000 to 9999 are covered fairly. Well, I actually don't know... I'm just not able/willing to demonstrate it.

perl -ple'$_=reverse' <<<ti.xittelop@oivalf

Io ho capito... ma tu che hai detto?

Replies are listed 'Best First'.
Re^2: Need a wait to generate a 4 digit "PIN" number
by jaiello (Novice) on Dec 16, 2007 at 04:23 UTC

    This is not homework and I didn't have a code sample as I was trying to find a way to do this. I have the bits already concatenated. I have a hex MD5hash of the concatenated string.

    You gave me the thought to use a Solaris like SUM of the string. So I did this:

    $pinc=join("$data1","$data2","$data3"); $digest2 = md5_hex($pinc); $pin=unpack("%32C*",$digest2) % 65535; print "[$pinc],[$digest2],[$pin]";

    and I get:

    [ilikeyoumy@email.comilikepie] [be256d5090d0875e7812428991d70026] [1961]

    This seems to work.

    Do you have an opinion on this?


      That could result in something larger than 9999 (up to 65535) and it could result in 1, 2, 3 digit pins (you'll never get 0123, but you will get 123).

      What's with quotes around variable names?
      Why start with the hex form?
      Why calculate a hash *and* a checksum?

      Using a MD5 hash will produce a good distribution of PINs.
      Solution using MD5 hash:

      my $pinc = join('', $data1, $data2, $data3); my $pin = sprintf('%04d', unpack('N', md5($pinc)) % 10000);

      Using CRC32 will *probably* produce a good distribution of PINs, but I don't personally know that.
      Using CRC32 will probably be faster than MD5, but it probably won't be noticeable unless you do millions of these in a row.
      Solution using CRC32:

      my $pinc = join('', $data1, $data2, $data3); my $pin = sprintf('%04d', unpack('%32C*', $pinc) % 10000);
        I quote the variables as they may contain *@%, etc. I figured it was safer. I started with hex as when I used a straight md5 hash, I did not get 4 digit numbers all the time. I don't entirely understand the code I used, but it worked, so I used it. So, that u=included a hash and a checksum. Why do you use '' as a separator in the join when it works without one? Thanks for the code snippets. I researched the modulus some but did not understand it very well, so I opted for a checksum. I'll probably use one in my application. I am sure you would cringe at the rest of my code. For example, I needed to strip both - and \r\n from a string but never managed to do it in one search/replace. So I had to do in on two lines: $data=~ s/\n\r//g; $data=~ s/-//g; Thanks!

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-06-22 02:25 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.