Unique, unpredictable, 12-digit integer identifier

How will I generate this ... I want to keep my primary key consistent and have a 12-digit unique output generated for each new object added to the database.

The reason this could just be auto-increment, I don't want consecutive numbers to be easily guessed.

It must be an integer, because I will have confirmation codes, which must be typed on the telephone keypad.

+4
php mysql random
source share
7 answers

Use the concatenation of a unique extension and a randomly generated number.

A unique incremented number ensures that the result is unique, and a randomly generated number makes it hardly possible.

It is simple and guaranteed without collisions (1). The result is incremental , partially random and unpredictable (provided that part of the random number is generated with good PRNG).

(1): You need to either put id and random zeros, or separate them from some non-digital character.

With MySQL db, this means:

 CREATE TABLE foo ( id int not null auto_increment, random int not null, ... primary key (id) ); 
+6
source share

Perhaps you can use UUID_SHORT() . No more than 12 digits, but can still be a viable option:

 mysql> select uuid_short(); +-------------------+ | uuid_short() | +-------------------+ | 22048742962102272 | +-------------------+ 

So:

 INSERT INTO `table` (`id`, `text`) VALUES (UUID_SHORT(), 'hello world!'); 

Note. If you really want to have exactly 12 digits, then do not even try to fine-tune the result if you did not guarantee the uniqueness of the identifier and could cause conflicts.

+2
source share
 <?php $allowed_characters = array(1,2,3,4,5,6,7,8,9,0); for($i = 1;$i <= 12; $i++){ $pass .= $allowed_characters[rand(0, count($allowed_characters) - 1)]; } echo $pass; ?> 

demo: http://sandbox.phpcode.eu/g/c0190/4

+1
source share

One method is to take your primary key value, salt it with several other random data bits (username, current time, process ID, fixed line, etc.) and hash it with md5 or sha1, then you take a hash string and convert it to numbers through basic string operations. This will give you a relatively unique digital code.

Of course, with only 12 digits, you are much more likely to encounter a collision than using the raw hash string, but since you require this to be typed on the keyboard, this is an acceptable compromise.

If contacts are canceled / deleted after use, the likelihood of a collision will be significantly reduced.

0
source share

You want two things

  • Uniqueness
  • Incremental

If you need both things from the same sequence, you will not succeed (literally). Uniqueness is guaranteed by the presence of a large sampling space + random + verification-unique. This means that the actual number can be anywhere between the sample.

But if you want the unique + incremental property, you divide the sample space by 2. In 64 attempts, you would reduce the space with the sample in 64 bits to 1 bit of space space.

Good luck

0
source share

In general, I would rather do something a little lower tech. I hide the values โ€‹โ€‹in PHP and leave them as auto-increment in JS.

 $seeds = array( /*series 100 of very large >= 10-digit numbers*/ ); $seedID = rand( count( $seeds ) ); // randomly choose one of those. // a string combination which represents the ID + some hash. $id = bcadd( $seeds[ $seedID ], /* id retrieved from database */ ); // make sure we've not accidentally passed the 10^12 point $id = bcmod( $id, 1000000000000 ); // make sure to pad $id = str_pad('' . $id, 3, "0", STR_PAD_LEFT); $outID = substr( $id, 0, 5 ) . $seedID . substr( $id, 6 ); 

Then when you get the id from the user:

 $seedID = substr( $outID, 6, 2 ); $tmpID = substr( $outID, 0, 5 ) . substr( $outID, 8 ); $id = bcsub( $tmpID, $seeds[ $seedID ] ); // we passed the modulus se we need to add this back in. if( $id < 0 ) $id = bcmod( bcadd( $id, 1000000000000 ), 1000000000000 ); 

This will mean that you simply gloss over any amount you want - you can use auto_increment with impunity!

0
source share

All solutions still have nothing to do with your application: Security !

You said that you will use these numbers as a product confirmation code (so you really want it to be unpredictable, otherwise it will be exploited.

None of the MySQL RANDOM built-in functions, nor any of the random functions that PHP provides today, are safe random functions. They behave pseudo-randomly, well, but they are all predictable!

You only have a chance to hack something of your own using /dev/urandom on a * nix machine or using the Crypto API on Windows. OpenSSL provides safe random numbers based on these mechanisms - you can reuse this either in the C extension for PHP, or by reading the output from the command line script called from PHP. See also this answer .

About your requirement for numbers to be consistent - is it really that important? This complicates the situation. Otherwise, it would be nice to go with a simple safe 6-byte random number encoded in a string using hexadecimal encoding (with a 12-character string). Although I would recommend doing it 10 bytes and 20 characters in order to be more secure.

But if you want to be consistent, which I interpret as monotonically increasing (since a simple +1 would be trivially predictable), this makes things a lot more complicated. And you donโ€™t get anything from this complexity, the only thing that can happen is that you violate security by inventing an obscure scheme that is easy to use.

My suggestion: add another column that acts as a plain old automatically incrementing identifier and will add the code as a random number, constructed as a separate column as above. As far as I see, there is no need to require that the product activation code be an identifier at the same time.

0
source share

All Articles