PHP实现生成唯一编号(36进制的不重复编号)


Posted in PHP onJuly 01, 2014

当我们要将一个庞大的数据进行编号时,而编号有位数限制,比如5位的车牌号、10位的某证件号码、订单流水号、短网址等等,我们可以使用36进制计算出符合位数的不重复的编号。

我们将0-Z(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)分别代表数值0-35,如字母Z代表35。这样的话我要得到一个5位的编号,最大信息量就是36的5次方了,36^5 = 60466176,即最大的5位编号相当于10进制的数字:60466176。
本文中为了做演示,我们假定某俱乐部发放一批10位的会员卡号,会员卡号由3位城市编号+5位卡号编码+2位校验码组成。城市编号用区号表示,如755代表深圳,5位卡编号则由36进制的卡编号组成,后面两位校验码则是通过一定的算法生成的,校验码的用处是可以验证卡号的合法性。这样的话,我们生成的10位卡号相当于最大能满足6000多万会员卡号,并且是不重复唯一的卡号。

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。
接着,我们将城市编号和校验码加上,城市编号是已经定义好的,校验码则通过一定的算法取得,本例中,我们使用简单的算法:将前三位城市编号和五位卡编号进行md5加密,然后取md5值的前2位作为校验码,这样就得到了编号后面的两位校验码。

$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位的不重复的会员卡号。

PHP 相关文章推荐
PHP array_push 数组函数
Dec 26 PHP
php 数组使用详解 推荐
Jun 02 PHP
PHP提示Warning:phpinfo() has been disabled函数禁用的解决方法
Dec 17 PHP
PDO防注入原理分析以及注意事项
Feb 25 PHP
Laravel 5框架学习之向视图传送数据
Apr 08 PHP
php打造智能化的柱状图程序,用于报表等
Jun 19 PHP
如何实现php图片等比例缩放
Jul 28 PHP
PHP 极验验证码实例讲解
Sep 29 PHP
thinkPHP中验证码的简单实现方法
Dec 05 PHP
PHP无限极分类函数的实现方法详解
Apr 15 PHP
PHP实现打包zip并下载功能
Jun 12 PHP
PHP生成短网址的思路以及实现方法的详解
Mar 25 PHP
ThinkPHP使用smarty模板引擎的方法
Jul 01 #PHP
PHP使用GIFEncoder类处理gif图片实例
Jul 01 #PHP
ThinkPHP模板IF标签用法详解
Jul 01 #PHP
PHP使用GIFEncoder类生成gif动态滚动字幕
Jul 01 #PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
Jul 01 #PHP
ThinkPHP模板范围判断输出In标签与Range标签用法详解
Jun 30 #PHP
ThinkPHP模板判断输出Empty标签用法详解
Jun 30 #PHP
You might like
用PHP发电子邮件
2006/10/09 PHP
PHP字符串长度计算 - strlen()函数使用介绍
2013/10/15 PHP
PHP 9 大缓存技术总结
2015/09/17 PHP
php提交表单时保留多个空格及换行的文本样式的方法
2017/06/20 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
javascript 极速 隐藏/显示万行表格列只需 60毫秒
2009/03/28 Javascript
javascript学习笔记(十八) 获得页面中的元素代码
2012/06/20 Javascript
javascript break指定标签打破多层循环示例
2014/01/20 Javascript
nodejs调用cmd命令实现复制目录
2015/05/04 NodeJs
莱鸟介绍javascript onclick事件
2016/01/06 Javascript
js确认框confirm()用法实例详解
2016/01/07 Javascript
JavaScript提高性能知识点汇总
2016/01/15 Javascript
Ubuntu系统下Angularjs开发环境安装
2016/09/01 Javascript
jquery日历插件e-calendar升级版
2016/11/10 Javascript
JS中去掉array中重复元素的方法
2017/05/26 Javascript
nodejs中sleep功能实现暂停几秒的方法
2017/07/12 NodeJs
老生常谈js数据类型
2017/08/03 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
javascript代码优化的8点总结
2018/01/29 Javascript
小程序实现短信登录倒计时
2019/07/12 Javascript
Vue自定义全局弹窗组件操作
2020/08/11 Javascript
ant design vue datepicker日期选择器中文化操作
2020/10/28 Javascript
[06:24]DOTA2亚洲邀请赛小组赛第三日 TOP10精彩集锦
2015/02/01 DOTA
[01:11:35]Liquid vs LGD 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python实现股市信息下载的方法
2015/06/15 Python
python多线程同步之文件读写控制
2021/02/25 Python
python 中的9个实用技巧,助你提高开发效率
2020/08/30 Python
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
英国最大的女性服装零售商:Dorothy Perkins
2017/03/30 全球购物
2014年党务公开实施方案
2014/02/27 职场文书
幼儿教师暑期培训方案
2014/08/27 职场文书
毕业典礼邀请函
2015/01/31 职场文书
个人党性分析总结
2015/03/05 职场文书
2015年网管个人工作总结
2015/05/22 职场文书
幼儿园科学课教学反思
2016/03/03 职场文书
使用Redis做预定库存缓存功能
2022/04/02 Redis