How to create random, but unique IDs? |
[eluser]Steven Ross[/eluser]
Not specifically related to Code Igniter... I'd like to generate a 7 or 8 digit unique ID. But I'd like to avoid just simply counting up sequentially, and instead use random numbers from the pool of not-yet-taken IDs. What's the most efficient way to do that?
[eluser]Unknown[/eluser]
http://php.net/manual/en/function.uniqid.php, but, you should validate yout IDs to prevent concurrency problems.
[eluser]Steven Ross[/eluser]
Thanks, but those IDs are 13 characters long and in hex, i.e. the contain letters a-f. I'd prefer a purely numeric ID of no more than 8 digits. Also, from the comments on the manual page: "this function simply returns the UNIX timestamp with added microsecond counter as a hex number; it's more or less just microtime(), in hexit form" So, IDs will still be in order small -> large, not random. You can address that with the "added entropy" parameter, but that makes numbers 23 characters - definitely too long for me.
[eluser]huzzel[/eluser]
a purely numeric ID with no more than 8 digits couldnt be a uniqe id. i prefere something like this $id = sha1(uniqid(rand(), TRUE));
[eluser]Steven Ross[/eluser]
[quote author="huzzel" date="1273709694"]a purely numeric ID with no more than 8 digits couldnt be a uniqe id.[/quote]Why not? Unique within our system. We have a few thousand items for these IDs, the number grows over time, but will likely never exceed 100,000. Eight digits gives me 100 million IDs to choose from randomly. More than enough, isn't it? And those IDs get exposed to users, so I'd like to avoid huge clunky hex numbers like what sha1 produces.
[eluser]huzzel[/eluser]
[quote author="Steven Ross" date="1273710864"][quote author="huzzel" date="1273709694"]a purely numeric ID with no more than 8 digits couldnt be a uniqe id.[/quote]Why not? Unique within our system. We have a few thousand items for these IDs, the number grows over time, but will likely never exceed 100,000. Eight digits gives me 100 million IDs to choose from randomly. More than enough, isn't it? And those IDs get exposed to users, so I'd like to avoid huge clunky hex numbers like what sha1 produces.[/quote] thats why i put this userids into cookie/session :-)
[eluser]n0xie[/eluser]
[quote author="Steven Ross" date="1273710864"] And those IDs get exposed to users, so I'd like to avoid huge clunky hex numbers like what sha1 produces.[/quote] If the id's are going to be exposed to users, why not just count up? What's the advantage of having random id's?
[eluser]Steven Ross[/eluser]
I don't want people to be able to guess valid ID ranges and build scrapers too easily and most of all, I don't want them to be able to draw conclusions about the age of an item in our system and the total item count.
[eluser]n0xie[/eluser]
There isn't really much you can do about scrapers, no matter how you build your URL. As for the age of the items, I guess you have a point. I just think you're making it way more complicated than need be. You could probably throw a rand function together that 'randomly' picks a number between 1 and 10.000.000, then match it against the db to see if it already exists. The maximum int size on a 32bit system is 2.147.483.647 which should be big enough for what you need: Code: function get_random_id()
[eluser]Steven Ross[/eluser]
Thanks, we're doing something like this currently. And since we only have a few thousand items and draw IDs out of a pool of a few million, we usually get a valid ID on the first attempt. I'm just concerned that, as the database fills up more, you'll get to a point where it may loop for a long time before it finds an available ID. I was thinking to compile a shuffled list of 7-digit numbers. Then, to avoid creating a DB table with 10m records, load chunks of, say, 100k into a DB and then just go down that list, assign the next number as ID for new items and check it off as "used". When each 100k block is used up (if ever), switch in the next block. I just thought that's a bit awkward, so I was hoping there's a simpler way. Looks like maybe there isn't... |
Welcome Guest, Not a member yet? Register Sign In |