PHP create short ID created with php-like Youtube or tinyurl
?
?
More are less-the ' math '
The alphabet has characters. That's a lot more than ten digits. If We also distinguish Upper-and lowercase, and add digits to the bunch or the heck of it, we already has (x 2 + 10)? We can use the options? per position? in the ID.
Now of course we can also add additional funny characters to ' the bunch ' like-/* & # But those may cause problems I n URLs and that's our target audience for now.
OK so because there is roughly? 6x More characters? We'll use per position, IDs would get much? shorter. We can just fit a lot? More data on each position.
This is the basically what URL shortening services does like tinyurl, is.gd, or bit.ly. But similar IDs can also is found at youtube:?http://www.youtube.com/watch?v=Yznjibedyww
Convert your IDs
Now unlike Database Servers:webservers is easy-to-scale so can-let-them do a bit of converting-ease the life of Y Our users, while keeping your database fast with numbers (MySQL really likes them plain numbers;).
To does the conversion I ' ve written a PHP function that can translate big numbers to short strings and vice versa. I call It:alphaid.
The resulting string is isn't hard-to-decipher, but it can be a very nice feature to make URLs or directorie structures more Compact and significant.
So basically:
- When someone requests RLHWFKD
- Alphaid () converts it to 999999999999
- You lookup the record for ID 999999999999 in your database
?
?
Source
PPQXN7COF * * Specifiying The second argument true, it'll * translate back e.g.: * PPQXN7COF-9007199254740989 * * This function was based on Any2dec && dec2any by * Fragmer[at]mail[dot]ru * see:http://nl3.php.net/manual/en/fun ction.base-convert.php#52450 * * If you want the alphaid to being at least 3 letter long, use the * $pad _up = 3 Argument * * In the most cases the better than totally random ID generators * Because this can easily avoid duplicate ID ' s. * For example if your correlate the Alpha ID to a auto incrementing ID * in your database, your ' re done. * * The reverse is do because it makes it slightly more cryptic, * but it also makes it easier to spread lots of IDs in Different * directories on your filesystem. Example: * $part 1 = substr ($alpha _id,0,1); * $part 2 = substr ($alpha _id,1,1); * $part 3 = substr ($alpha _id,2,strlen ($alpha _id)); * $destindir = "/". $part 1. " /". $part 2." /". $part 3; *//By reversing, directories is more evenly spread out. The *//First 26Directories already occupy to main levels * * More info on limitation: *-HTTP://BLADE.NAGAOKAUT.AC.JP/CGI-BIN/SCAT.RB/RU by/ruby-talk/165372 * * If you really need this for bigger numbers you probably has to look * at things like:http://thes erverpages.com/php/manual/en/ref.bc.php * or:http://theserverpages.com/php/manual/en/ref.gmp.php * but I haven ' t Really dugg into this. If you had more info on those * matters feel free to leave a comment. * * The following code block can be utilized by PEAR ' s testing_doctest * * // Input // * $number_in = 2188847690240; * $alpha_in = "SpQXn7Cb"; * * // Execute // * $alpha_out = alphaID($number_in, false, 8); * $number_out = alphaID($alpha_in, true, 8); * * if ($number_in != $number_out) { * echo "Conversion failure, ".$alpha_in." returns ".$number_out." instead of the "; * echo "desired: ".$number_in."\n"; * } * if ($alpha_in != $alpha_out) { * echo "Conversion failure, ".$number_in." returns ".$alpha_out." instead of the "; * echo "desired: ".$alpha_in."\n"; * } * * // Show // * echo $number_out." => ".$alpha_out."\n"; * echo $alpha_in." => ".$number_out."\n"; * echo alphaID(238328, false)." => ".alphaID(alphaID(238328, false), true)."\n"; * * // expects: * // 2188847690240 => SpQXn7Cb * // SpQXn7Cb => 2188847690240 * // aaab => 238328 * *
* * @authorKevin van Zonneveld
* @authorSimon Franz * @authorDeadfish * @copyright Kevin van Zonneveld (http://kevin.vanzonneveld.net) * @license http://www.opensource.org/licenses/bsd-license.php New BSD Licence * @version svn:release: $Id: alphaID.inc.php 344 2 009-06-10 17:43:59z Kevin $ * @link http://kevin.vanzonneveld.net/* * @param mixed $in String or long input to transl Ate * @param boolean $to _num reverses translation when True * @param mixed $pad _up number or Boolean padds the result Up to a specified length * @param string $passKey supplying a password makes it harder to calculate the original ID * * @ Return mixed string or long */function alphaid ($in, $to _num = False, $pad _up = false, $passKey = null) {$index = "Abcdefghi JKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ "; if ($passKey!== null) {//Although this function ' s purpose are to Just make the//ID short-and do much secure,//with this patch by Simon Franz (http://blog.snaky.org/)//You can opt Ionally Supply a password To make it harder//to calculate the corresponding numeric idfor ($n = 0; $n
0) $out-= POW ($base, $pad _up);} $out = sprintf ('%F ', $out); $out = substr ($out, 0, Strpos ($out, '. '));} else {//Digital number-->> alphabet Letter Codeif (is_numeric ($pad _up)) {$pad _up--;if ($pad _up > 0) $in + = PO W ($base, $pad _up);} $out = ""; for ($t = Floor (log ($in, $base)); $t >= 0; $t-) {$bcp = Bcpow ($base, $t), $a = floor ($in/$bcp)% $base; $out = $out. substr ($index, $a, 1); $in = $in-($a * $BC p);} $out = Strrev ($out); Reverse}return $out;}
?
Example
Running:
Alphaid(9007199254740989);
Would return 'ppqxn7cof' and:
Alphaid(' ppqxn7cof 'true);
Would return '9007199254740989'
Easy right?
More Features
- There also is an optional third argument:?
$pad_up
. This enables do the resulting alphaid at least? X? characters long.
- Can support even more characters (making the resulting alphaid even smaller) by adding characters to the?
$index
? var at the top of the function body.
?
?
?
JavaScript implementation
Thanks to even Simon, there's a JavaScript implementation. You'll also find PHP version there, that's implements the Encode & decode functions as separate methods in a class.
?
?
Python implementation
Thanks To?wessite, there's a Python implementation.
?
ALPHABET = "bcdfghjklmnpqrstvwxyz0123456789bcdfghjklmnpqrstvwxyz" BASE = Len (ALPHABET) MaxLen = 6 def encode_id (self, N): pad = self. MAXLEN-1 n = Int (n + pow (self). BASE, pad)) s = [] t = Int (Math.log (n, self). BASE) while True: bcp = int (the POW (self). BASE, T)) a = Int (n/bcp)% self. BASE s.append (self. ALPHABET[A:A+1]) n = n-(A * bcp) T-= 1 if T < 0:break return "". Join (Reversed (s)) def decode_id (s Elf, N): n = "". Join (Reversed (n)) s = 0 l = Len (n)-1 t = 0 while True: bcpow = Int (POW (sel F.base, l-t)) s = s + self. Alphabet.index (n[t:t+1]) * Bcpow T + = 1 if T > l:break pad = self. MAXLEN-1 s = Int (S-pow (self). BASE, pad)) return int (s)
?
Python implementation
Thanks to? Andy Li, there ' s a HaXe implementation.
?
/** * HaXe version of Alphabeticid * Author:andy Li * ported from ... * Javascript alphabeticid class * Author:ev En Simon
* Which is based in a script by Kevin van Zonneveld
) * * Description:translates A numeric identifier into a short string and backwords. * http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/**/class Alphaid {static public var index:string = ' abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz '; static public function encode (_number:int): String {var strbuf = new Stringbuf (); var i = 0; var end = Math.floor (Math.log (_number)/math.log (index.length)); while (I <= end) {Strbuf.add (Index.charat (Math.floor (_number/bcpow (index.length))% i++)); } return strbuf.tostring (); } static Public Function decode (_string:string): Int {var str = reversestring (_string); var ret = 0; var i = 0; var end = Str.length-1; while (I <= end) {ret + = Std.int (Index.indexof (Str.charat (i)) * (Bcpow (index.length, end-i))); ++i; } RETurn ret; } inline static Private function Bcpow (_a:float, _b:float): Float {return Math.floor (Math.pow (_a, _b)); } inline static Private function reversestring (instr:string): String {var ary = Instr.split (""); Ary.reverse (); Return Ary.join (""); }}
?
? Source: http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/
?
?