How to generate unqiue code or serial numbers?

Hi,

I am working on a members database and I need to generate unique serial / code for each member.
The unique code must be in format of XXXX-XXXX-XXXX-XXXX-XXXX or something similar.

I can generate the code by one way or another usin chr() etc. but how do i make sure that its unique ?

Thanks.

The easiest way would be by using md5() or [URL=“http://www.php.net/sha1”]sha1() for generating hash of some dynamically generate strings. For checking the uniqueness you have to store them in a database table and each time you generate new id you check if it already exists or not.

Hi,

Umm i was trying something like this:

<?php
$uni_id = rand(10,99);

$first = $uni_id;
$chars_to_do = 5 - strlen($uni_id);
for ($i = 1; $i <= $chars_to_do; $i++) { $first .= chr(rand(48,57)); }

echo $first;

$chars_to_do = 5 - strlen($uni_id);
for ($i = 1; $i <= $chars_to_do; $i++) 
{
	if ($i == "2") { $second[] = $uni_id; }
	$second[] = chr(rand(48,57));
}

echo "-" . implode("", $second);

$chars_to_do = 5 - strlen($uni_id);
for ($i = 1; $i <= $chars_to_do; $i++) 
{
	if ($i == "3") { $third[] = $uni_id; }
	$third[] = chr(rand(48,57));
}

echo "-" . implode("", $third);

$chars_to_do = 5 - strlen($uni_id);
for ($i = 1; $i <= $chars_to_do; $i++) 
{
	$fourth[] = chr(rand(48,57));
}
$fourth[] = $uni_id;

echo "-" . implode("", $fourth);
?>

Generation is not an issue, how to make sure of uniqueness ? Even if i check against a database still there is a chance of duplicate record getting generated, or ain’t ?

But i think if i use my code then there will be no chance…

Thanks.

Hi,

Now i did this, it generates unique alpha-numeric code:

	$md5 = strtoupper(md5($memb_id . $memb_name . $memb_email . $memb_mobile));
	
	$code[] = substr ($md5, 0, 5);
	$code[] = substr ($md5, 5, 5);
	$code[] = substr ($md5, 10, 5);
	$code[] = substr ($md5, 15, 5);
	
	$membcode = implode ("-", $code);
	if (strlen($membcode) == "23") { return ($membcode); } else { return (false); }

Its unique enough for me. Hope it helps! :slight_smile:

Thanks.

How about this then?


$collection = array();
for($i = 1; $i < 10; $i++){
	$ukey = strtoupper(substr(sha1(microtime() . $i), rand(0, 5), 25));
	if(!in_array($ukey, $collection)){ // you can check this in database as well.
		$collection[] = implode("-", str_split($ukey, 5));
	}
}
echo "<pre>";
print_r($collection);

Nice :slight_smile: I can use that too :slight_smile:

When storing in the db give the column a UNIQUE index, that way instead of checking to see if the hash exists as you insert the hash you check for error number 1062 (duplicate found) - then possibly go back and add a digit/char to the values and try again 'till it succeeds.

Would that work?

Hi,

I think the code Raju gave will always generate unique codes as he’s using microtime and $i which is going to be unique everytime a hash is being generated, hence there is no need for checking the hash in db at all.

Thanks.

Any processing that uses a hash will need to check for uniqueness since there are an infinite number of possible values that map to any one hash and no matter what method you use for generating the values to be hashed there is always a possibility of finding a second value that maps to the same hash you already generated.

Hashes are guaranteed to NOT be unique once you generate enough of them. It is unlikely though that you will generate the same hash twice until you have generated a lot of them particularly if the original values only vary by a small amount each time - since the purpose of a hash is that a minor change to the original will produce an entirely different hash - you would still need to test if it has already been used but simply restarting the process if inserting the hash into the database fails wouldd be the simplest way of handling it (assuming that you use the value as the primary key - which is appropriate as it is supposed to be unique).

I need a code that can generate serial number for loyalty program

Why not use uniqid(“”, true) and get a 23 character unique code? Just add “-XXX” to the end of your current format and you’ve covered all the characters. Personally, I’d save the value as-is, masking it with dashes only for user display and input.

http://us3.php.net/manual/en/function.uniqid.php

“Gets a prefixed unique identifier based on the current time in microseconds.”

But in any case you have to check in database. As felgall said, it’s possible to get the same record several times. For example if you will use md5, it’s limited by 32 characters, so there is possibility to get the same record several times.
Using microseconds will not solve the problem of being unique.

The thing is, it’s based on time since epoch. No sequence should ever be repeated. Theoretically. But then again, the problem crops up in .NET with GUID collisions occasionally. There’s also the issue of a user figuring out your schema, and exploiting it. In such a case, the $prefix parameter to uniqid would help minimize that. In any case, it’s another viable option to consider.

The problem is that you create a hash out of the sequence, and you can have several strings which generate the same hash, especially the weaker the hashing method is; like md5.

This means if you generate enough records, you are almost bound to get a collision happening.

You cant compare it to GUID, since there is more variable in play here. Though as you mentioned it is possible to get collisions here as well (note depends on what GUID version your database engine is using).