How can i generate a unique combinations of maximum 6 characters in php using (0 - 9), (a - z) and (A - Z)? How many possible combination those will be? (for example AAaa will be different than Aaaa)?
-
2uniqid() http://nz.php.net/manual/en/function.uniqid.php – Feb 12 '11 at 09:38
-
2The problem is not so much generating them but making sure they stay unique. How do you intend to store them? – Gordon Feb 12 '11 at 09:42
-
1if you generate an id you still need to check it every time to make sure it has not been generated before, if you use uniquid(), you don't have to check every time. – Feb 12 '11 at 09:50
-
Thanks. @Gordon, yes that my next concern, how to store the words such as **AA** and **aa** in database and how to keep them separate. If you have any suggestion, please let me know. – adam Feb 12 '11 at 09:56
-
@Dagon OP is looking for a 6 chars string while `uniqid` will generate a 13 character string. If you truncate that anywhere, you will have to check for uniqueness as well. – Gordon Feb 12 '11 at 10:06
-
@adam can you provide more information about your scenario. What are the IDs used for? Can you use stored procedures in the database? Can IDs be "freed", e.g. when they are deleted in the db should they be reassigned or are they used up forever? Do they have to be a-Z0-9 or would an ongoing number work as well? – Gordon Feb 12 '11 at 10:09
-
sometimes, a simple search can solve your problem faster than waiting for answers: http://stackoverflow.com/search?q=php+unique+id – Zathrus Writer Feb 12 '11 at 10:21
-
@Gordon, I want to use the id's to shorten the url, similar way like bit.ly does, they have ids like "dVcXMi". I just want to create random id's similar way. – adam Feb 12 '11 at 11:05
-
possible duplicate of [How to code a URL shortener?](http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener) and more php specific [http://stackoverflow.com/search?q=php+url+shortener](http://stackoverflow.com/search?q=php+url+shortener) – Gordon Feb 12 '11 at 11:19
2 Answers
Using base_convert($number, 10, 36)
will not treat a-z
differently from A-Z
as is specified in the question. Custom functions are required.
Use an int column in your DB as the primary key that auto-increments on insert, then convert this ID from decimal to base-62 in your logic for the permalink (62 allows use of 0-9, a-z and A-Z).
When creating a new permalink:
<?php
/**
* Convert decimal int to a base-62 string
*
* @param int $dec
* @returns string
*/
function toBase62 ($dec) {
// 0 is always 0
if ($dec == 0)
return "0";
// this array maps decimal keys to our base-62 radix digits
$values = array(
"0", "1", "2", "3", "4",
"5", "6", "7", "8", "9",
"A", "B", "C", "D", "E",
"F", "G", "H", "I", "J",
"K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y",
"Z", "a", "b", "c", "d",
"e", "f", "g", "h", "i",
"j", "k", "l", "m", "n",
"o", "p", "q", "r", "s",
"t", "u", "v", "w", "x",
"y", "z"
);
// convert negative numbers to positive.
$neg = $dec < 0;
if ($neg)
$dec = 0 - $dec;
// do the conversion:
$chars = array(); // this will store our base-62 chars
while ($dec > 0) {
$val = $dec % 62;
$chars[] = $values[$val];
$dec -= $val;
$dec /= 62;
}
// add zero-padding:
while (count($chars) < 6)
$chars[] = '0';
// convert to string
$rv = implode( '' , array_reverse($chars) );
// if input was negative:
return $neg ? "-$rv" : $rv;
}
// Usage example:
// ... do mysql insert here and retrieve new insert_id into var $id ...
$permalink = toBase62($id);
?>
When decoding a requested permalink:
<?php
/**
* Convert base-62 string to a decimal int
*
* @param string $str
* @returns int on success, FALSE on failure
*/
function base62ToInt ($str) {
// validate str:
if ( ! preg_match('/^\-?[0-9A-Za-z]+$/', $str) )
return FALSE; // not a valid string
// 0 is always 0
if ($str == "0" )
return 0;
// this array maps decimal keys to our base-62 radix digits
$values = array(
"0", "1", "2", "3", "4",
"5", "6", "7", "8", "9",
"A", "B", "C", "D", "E",
"F", "G", "H", "I", "J",
"K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y",
"Z", "a", "b", "c", "d",
"e", "f", "g", "h", "i",
"j", "k", "l", "m", "n",
"o", "p", "q", "r", "s",
"t", "u", "v", "w", "x",
"y", "z"
);
// flip $values so it maps base-62 digits to decimal values:
$values = array_flip($values);
// get chars from $str:
$chars = str_split($str);
// convert negative numbers to positive.
$neg = $chars[0] == '-';
if ($neg)
array_shift($chars);
// do the conversion:
$val = 0;
$i = 0;
while ( count($chars) > 0 ) {
$char = array_pop($chars);
$val += ($values[$char] * pow(62, $i) );
++$i;
}
return $neg ? 0 - $val : $val;
}
// Usage example:
// ... assuming permalink has been put in a var called $permalink
$id = base62ToInt($permalink);
// ... now look up $id in DB
?>

- 11,441
- 6
- 50
- 62
-
This algorithm is good but the result url will be not pretty . For row 3 result 000003 which does not seems to be shorten url. What do you think – Rajib Jun 12 '22 at 02:41
My suggestion (particuarily if you are using a database to store them anyway) would be to let the database generate a unique row id using an autoincrement number in the database and then convert that number to your code, which is guaranteed to be unique since it was generated by the database.
In terms of generating the code from the number, my suggestion would be a simple substitution, so create a string with all your possible characters and convert your number to base 62 (count of all the characters) substituting a letter or number for each .
AaBbCcDd...0123456789
(on an aside, I would suggest removing lIioO01 as they all look very similar)
As suggested by Dan Grossman in the comment below, the following code will give you a very good approximation of what you want.
$code = base_convert($number, 10, 36);
This will give you a number based on the numbers and letters 0-9 and a-z.

- 10,997
- 11
- 73
- 124
-
1`$code = base_convert($number, 10, 36);` will use 0-9 and a-z. That should be short enough for him that you don't really need to hand code a higher base. – Dan Grossman Feb 12 '11 at 11:25