There are hashes that will hash into any number of "buckets". Since you do not care about security or "accuracy", what I have done in the past is just to use the first or last characters of the MD5 hash. It has always been random enough for me. There is a danger of collision, but that is true of a smaller hash function, too.
It looks as though you need about 32 bits of hash (5 or 6 bits/char depending on char set and 5 or 6 chars). How about Digest::Adler32 or CRC32?
--traveler | [reply] |
If you are not worried about security or collision frequency, you could use a mod:
my $short = $digest % ($largest_int_wanted + 1);
Alternately, you could use the 5-6 least significant characters of the digest.
| [reply] [d/l] |
Taking the modulus doesn't prevent people from guessing the next and/or previous key, as it will likely still be n+1 or n-1, if the modulus is large enough. But based on the modulus idea, one could use the linear method used by random number generators - take a large prime number, multiply the record number by it, and then take the modulus - this should give a fairly good distribution, but I'd still look at what Knuth (or some other book) says about the algorithm. I think it's called Linear Random Number Generator, but it might be called something else.
| [reply] |
Use bitreverse (see Bit::Vector, Reverse() for example), or another similar bitswapping mechanism, that way you can map any integer to another integer, in a unique way, reversible way. Most users won't have a clue to what's happening.
Another idea is to just pick a random number, check it for uniqueness, and store it in a database table for reverse lookup.
| [reply] |
perl -e 'for (1..10) {srand($_); print int rand (100000), $/}'
# output
51385
2770
54159
5545
56930
8319
59704
11090
62475
13864
Cheers, R. | [reply] [d/l] |
Use MD5 and take the last x number of characters rather than the whole thing.
EDIT: As BrowserUk pointed out in a PM to me, this was already said in the first post to the thread. My bad. | [reply] |