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

by polettix (Vicar)
 on Dec 16, 2007 at 03:45 UTC Need Help??

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.

Flavio
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?

Thanks!

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 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!

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://657249]
help
Chatterbox?
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
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?
 • 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.