求一个设计思路:如何生成一个唯一的8位的看起来像是随机字母的 码 .内详
程序员文章站
2022-04-21 12:25:27
...
唯一码 随机码 更具体的需求是这样的
数据库里可能会逐渐插入不超过10w条记录,想加一个字段,每一条记录的这个字段的值 都是一个8位的码
1.看起来像是随机码 比如DLKPOWND OUICHGEB 等等
2.不能被"轻易"破解 比如id=1 对应AAAAAAAA id=2对应 AAAAAAAB 当然这个描述可能跟第一条有所重复 反正就是要对方没法轻易猜到一个码进行查找就能查到结果(10W条对应2088亿种可能,如果只是靠猜基本上无法命中).
3.希望能在这条记录插入输入库之前就获得这样一个码并且不需要去检索数据库是否已存在.这一条可能我描述的不够清楚,是这样的:事实上我可以用substr(rand(0,25),1,$str)循环八次来生成一个码,然后去数据库查找,如果还没有的话,就插入,这样也是唯一的. 但是这是最后的选择,更希望能像MD5那样传入时间戳就能生成一个唯一的而非去通过检索数据库来判断是否唯一. 时间戳只是个举例不一定非要用时间戳做种子
大致就是这样,如果没说明白可以提出来我再补充.求指点下思路或者给出方法~~谢谢
自增id是唯一的,所以得到字符串也是唯一的
算法应该算是很简单的
数据库里可能会逐渐插入不超过10w条记录,想加一个字段,每一条记录的这个字段的值 都是一个8位的码
1.看起来像是随机码 比如DLKPOWND OUICHGEB 等等
2.不能被"轻易"破解 比如id=1 对应AAAAAAAA id=2对应 AAAAAAAB 当然这个描述可能跟第一条有所重复 反正就是要对方没法轻易猜到一个码进行查找就能查到结果(10W条对应2088亿种可能,如果只是靠猜基本上无法命中).
3.希望能在这条记录插入输入库之前就获得这样一个码并且不需要去检索数据库是否已存在.这一条可能我描述的不够清楚,是这样的:事实上我可以用substr(rand(0,25),1,$str)循环八次来生成一个码,然后去数据库查找,如果还没有的话,就插入,这样也是唯一的. 但是这是最后的选择,更希望能像MD5那样传入时间戳就能生成一个唯一的而非去通过检索数据库来判断是否唯一. 时间戳只是个举例不一定非要用时间戳做种子
大致就是这样,如果没说明白可以提出来我再补充.求指点下思路或者给出方法~~谢谢
回复讨论(解决方案)
最多10万条?
也就是说自增的id为1到99999了
按5位补齐前导的0,即 00001到99999
在其后附加个位(当然是你指定的)为 000011 到 999999
然后做 base64 编码
echo base64_encode('000011'), PHP_EOL;echo base64_encode('999999'), PHP_EOL;/*MDAwMDExOTk5OTk5*/必要的话,在对结果做一下“凯撒加密”(字典移位)
自增id是唯一的,所以得到字符串也是唯一的
算法应该算是很简单的
用自增ID做种子是很不错的选择,因为它10w的范围内是唯一的 而截取八位后的当前时间戳不是
但是这样是不是也要先存入,拿到ID酸楚码再更新至数据库? 能否查数据库或者写数据库之前拿到码 或者在insert的时候插入符合要求的码
既然是变形自增id,也就没有必要存到库中了吧?
做一下逆运算不就还原了吗?
用自增ID做种子是很不错的选择,因为它10w的范围内是唯一的 而截取八位后的当前时间戳不是
但是这样是不是也要先存入,拿到ID酸楚码再更新至数据库? 能否查数据库或者写数据库之前拿到码 或者在insert的时候插入符合要求的码
base64_encode(base_convert(time(), 10, 36));把当前时间转化为36进制(8位数),在用base64_encode加密可以不,确保唯一了,也不用查数据库。
用时间也是一个办法,不过光 time 是不行的。
谁能保证两个请求不在同一秒钟内得到响应呢?
或许这样可行
echo base_convert(str_replace('.', '', $_SERVER['REQUEST_TIME_FLOAT']), 10, 36);
但精确到毫秒,对于高性能的服务器可能还是个问题
define('ONLY','FDSAR2432FDS');
echo base64_encode(ONLY.'000011'), PHP_EOL;
echo base64_encode(ONLY.'999999'), PHP_EOL;
下一篇: PHP编码转换_PHP教程