PHP实现生成唯一编号(36进制的不重复编号) |
本文标签:PHP,生成唯一编号,36进制 当我们要将一个庞大的数据进行编号时,而编号有位数限制,比如5位的车牌号、10位的某证件号码、订单流水号、短网址等等,我们可以使用36进制计算出符合位数的不重复的编号 。 我们将0-Z(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)分别代表数值0-35,如字母Z代表35 。这样的话我要得到一个5位的编号,最大信息量就是36的5次方了,36^5 = 60466176,即最大的5位编号相当于10进制的数字:60466176 。 PHP实现 我们使用PHP进行进制转换,10进制转36进制 。 复制代码 代码如下: class Code { //密码字典 private $dic = array( 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>A, 11=>B, 12=>C, 13=>D, 14=>E, 15=>F, 16=>G, 17=>H, 18=>I,19=>J, 20=>K, 21=>L, 22=>M, 23=>N, 24=>O, 25=>P, 26=>Q, 27=>R,28=>S, 29=>T, 30=>U, 31=>V, 32=>W, 33=>X, 34=>Y, 35=>Z ); public function encodeID($int, $format=8) { $dics = $this->dic; $dnum = 36; //进制数 $arr = array (); $loop = true; while ($loop) { $arr[] = $dics[bcmod($int, $dnum)]; $int = bcdiv($int, $dnum, 0); if ($int == 0) { $loop = false; } } if (count($arr) < $format) $arr = array_pad($arr, $format, $dics[0]); return implode(, array_reverse($arr)); } public function decodeID($ids) { $dics = $this->dic; $dnum = 36; //进制数 //键值交换 $dedic = array_flip($dics); //去零 $id = ltrim($ids, $dics[0]); //反转 $id = strrev($id); $v = 0; for ($i = 0, $j = strlen($id); $i < $j; $i++) { $v = bcadd(bcmul($dedic[$id { $i } ], bcpow($dnum, $i, 0), 0), $v, 0); } return $v; } } 我们定义Code类,先定义密码字典,即0-Z分别对应的数值,方法encodeID($int, $format)中参数$int表示数字,$format表示位数长度,比方encodeID(123456789,5)表示将数字123456789转换成5位的36进制编号,而方法decodeID($ids)用于将36进制的编号转换成10进制的编号 。 复制代码 代码如下: $code = new Code(); $card_no = $code->encodeID(888888,5); 如上,我们就可以得到一个5位的卡编号,它实际代表着卡号是888888(6个8)的会员编号,而实际进行转换后是5位编号:0J1VC 。 复制代码 代码如下: $card_pre = 755; $card_vc = substr(md5($card_pre.$card_no),0,2); $card_vc = strtoupper($card_vc); echo $card_pre.$card_no.$card_vc; 实际应用中,可以通过数据库得到10进制的编号,保证编号唯一,再将上述代码组合,最终生成一个10位的不重复的会员卡号 。 |