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 相关文章推荐
PHPMailer 中文使用说明小结
Jan 22 PHP
基于PHP生成静态页的实现方法
May 10 PHP
深入理解PHP几个算法:PHP冒泡、PHP二分法、PHP求素数、PHP乘法表
Jun 06 PHP
php解析json数据实例
Aug 19 PHP
Yii获取当前url和域名的方法
Jun 08 PHP
php上传大文件失败的原因及应对策略
Oct 20 PHP
PHP设置头信息及取得返回头信息的方法
Jan 25 PHP
Zend Framework教程之模型Model用法简单实例
Mar 04 PHP
利用PHP命令行模式采集股票趋势信息
Aug 09 PHP
php下载远程大文件(获取远程文件大小)的实例
Jun 17 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
May 13 PHP
PHP程序守护进程化实现方法详解
Jul 16 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
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
js不是基础的基础
2006/12/24 Javascript
通过Mootools 1.2来操纵HTML DOM元素
2009/09/15 Javascript
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
c#和Javascript操作同一json对象的实现代码
2012/01/17 Javascript
js如何取消事件冒泡
2013/09/23 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
JavaScript中的类数组对象介绍
2014/12/30 Javascript
JS正则子匹配实例分析
2016/12/22 Javascript
NestJs 静态目录配置详解
2019/03/12 Javascript
解决Layui当中的导航条动态添加后渲染失败的问题
2019/09/25 Javascript
CKEditor扩展插件:自动排版功能autoformat插件实现方法详解
2020/02/06 Javascript
vue单应用在ios系统中实现微信分享功能操作
2020/09/07 Javascript
[02:16]DOTA2超级联赛专访Burning 逆袭需要抓住机会
2013/06/24 DOTA
[01:29:31]VP VS VG Supermajor小组赛胜者组第二轮 BO3第一场 6.2
2018/06/03 DOTA
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
[49:21]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第二场 11.05
2020/11/06 DOTA
python的即时标记项目练习笔记
2014/09/18 Python
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
python通过微信发送邮件实现电脑关机
2018/06/20 Python
Python实现基于POS算法的区块链
2018/08/07 Python
Django uwsgi Nginx 的生产环境部署详解
2019/02/02 Python
python函数与方法的区别总结
2019/06/23 Python
Python 读取串口数据,动态绘图的示例
2019/07/02 Python
html5 postMessage前端跨域并前端监听的方法示例
2018/11/01 HTML / CSS
英国家喻户晓的家居商店:The Range
2019/03/25 全球购物
一套软件测试笔试题
2014/07/25 面试题
竞争上岗演讲稿
2014/01/05 职场文书
信息专业大学生自我评价分享
2014/01/17 职场文书
饭店服务员岗位职责
2015/02/09 职场文书
毕业生自荐信范文
2015/03/05 职场文书
党员转正申请报告
2015/05/15 职场文书
mysql批量新增和存储的方法实例
2021/04/07 MySQL
python 常用的异步框架汇总整理
2021/06/18 Python