前几天接到个任务,甲方先前自己找外包开发的一个产品购买小站不准备继续给外包维护了,转手抛给我们,顺便提了一堆修改意见。
其中一个意见是因为外包开发的订单网站直接用数据库自增的id作为订单号,导致订单号又短又好记,下单的人直接通过订单号就能推测出该产品的销量,为甲方业务员的吹嘘设下巨大的阻碍。
不出所料这个包袱到我的桌上。
通过搜索,我列出几种方法供领导选择:
方法\原始id值 | 优缺点 | 1 | 5 | 10 | 100 |
订单创建时间戳转年月日时分秒后加左边拼0的id,长度22 |
优点:不用改动表结构数据
缺点:懂行的人一眼就能看穿
|
2017032110445700000001 | 2017032110445700000005 | 2017032110445700000010 | 2017032110445700000100 |
所有id全加41100000,长度8 |
优点:比较短,8位容易阅读
缺点:需要改动表数据
|
41100001 | 41100005 | 41100010 | 41100100 |
给订单表增加一个字段,使用随机字符串生成给定长度 |
优点:订单号与id完全无关,难以判断销量
缺点:需要改动表结构
|
随机 | 随机 | 随机 | 随机 |
使用github插件,optimus | 优点:不用改动表结构数据 | 647890742 | 443442450 | 191221 | 1452509963 |
根据指示,似乎决定使用optimus,在github上搜,第一个就是。
先在本地搭了一个测试环境,使用composer拉下源码后,在自带的bin目录下运行
php optimus spark
得到三个配置必须参数
Prime:2147483647以下一个较大的素数
Inverse:一个逆素数,使(PRIME * INVERSE) & 2147483647 == 1
Random:一个2147483647以下的随机数
建个测试文件,设置参数就能用了。
use Jenssegers\Optimus\Optimus;
//根据测试文件和vendor所在的位置正确设置路径
require_once(__DIR__.'/../vendor/autoload.php');
$config=array(
'prime'=>653936159,
'inverse'=>7845343,
'random'=>421554952
);
$optimus=new Optimus($config['prime'],$config['inverse'],$config['random']);
$exampleId=rand(1,99999);
$encode=$optimus->encode($exampleId);
$decode=$optimus->decode($encode);
echo "raw:{$exampleId}<br>encode:{$encode}<br>decode:{$decode}";
该混淆算法使用了Donald Knuth的整型哈希,具体算式:
ENCODE = ( ( RAW * PRIME ) & ( 2^32-1 ) ) ^ RANDOM
DECODE = ( ( ENCODE ^ RANDOM ) * INVERSE ) & ( 2^32-1 )
( PRIME * INVERSE ) & ( 2^32-1 ) = 1
缺点是假如订单被打印成纸了,那么三个参数必须固定,再也不能变换。