php怎么生成6位的不重复的字符串
回复内容: php怎么生成6位的不重复的字符串
研究下时间戳吧,不重复这个只想到了时间戳。
当前时间的md5,截取前6位。理论上不可能重复
大型电商网站架构初期,架构师需要约55%的时间考虑订单。因为电商网站业务和网站逻辑大部分依赖订单(包括订单的状态)在运作。既然如此重要我们来分析下php如何生成高质量的订单(下面将提供php生成订单的代码片段)。写这篇文章有点心惊胆战,全部是个人之见,仅仅作为参考。
首先了解下订单生成的大致规则(部分摘录于互联网):
1、不重复。2、安全性。 2.1 不建议使用啥敏感的数据作为订单生成规则(例如:用户uid,订单自增order_id等),以为会暴露网站一些敏感信息3、不能使用大规模随机码。 why? 3.1 首先问你编程语言中的随机能做到真随机吗?,我可以不自信的告诉你至少php做不到,所以可能导致第一个不重复原则发生 3.2 如果你的订单数量到达了1000w次,你每次生成订单编码时就得对比1000w条历史数据,一般在500w的时候,你得花时间在数据库优化上(简单处理:采用分区,建立索引,然而实际性要求高,可能需要在主数据库下操作,可想你有多痛,当然对于数据库实时读写还有其他的优化办法,在此不作介绍)。4、防止并发。5、控制位数。 why? 5.1 便于查询检索 5.2 位数控制到 10~20位即可,当然网上将的是10~15缘由是利于输入,对于输入太长做好用户体验就好(新增复制订单按钮) 6、尽量具有业务意义(不是强制的,根据公司业务来) 6.1 当你业务比较庞大时候,或者后期有大规模的扩充时,建议考虑下订单的生成意义,根据公司的业务做调整。举个最简单的例子:一个卖化妆品的商城,你需要根据订单来源来(pc/移动)来生成报表,这时候可能需要 7.解决办法 7.1 类似生成 uuid ,不依赖外部流水号,完全靠时间戳和随机数生成订单号无法避免冲突,所以必须引入外部的流水号生成机制。或使用数据库,或使用apc之类的缓存。用apc之类的缓存存在一个问题,就是无法持久保持数据,服务器重启或者php宿主进程重启都会清空流水号计数器,所以可以采取缓存+数据库结合的模式——如果缓存中有流水号计数器数据则读取并累加计数,如果缓存中没有流水号计数器从数据库中还原计数器。计数器可以每隔一段时间重置一次。既然引入了自增流水号计数器,又会导致文章开头的“德国坦克问题”,所以需要用skip32算法把流水号加密(https://github.com/nlenepveu/skip32)。 订单号 = 日期前缀 + 加密流水号 // skip32 算法加密密钥 const encrypted_key = 'xxxxxxxxxxxx'; // 使用 wincache 作为流水号计数器缓存 function getorderserialnumber() { $timestamp = time(); $dateprefix = date('ymd', $timestamp); // 如果流水号计数器数据不在缓存中,则尝试从数据库中恢复 if (false === ($value = wincache_ucache_inc($dateprefix))) { wincache_lock($dateprefix); // 从数据库中获取今日的订单数 $counter = getnumberoforderstodayfromdatabase($timestamp); $value = $counter + 1; if (!wincache_ucache_add($dateprefix, $value, 60*60*24)) { $value = wincache_ucache_inc($dateprefix); } wincache_unlock($dateprefix); } return $dateprefix.str_pad(skip32::encrypt($dateprefix.encrypted_key, $value), 10, '0', str_pad_left); }
最后用的生成短网址的方法
/**
*生成随机数
*@param
*/
function randstr($m= 5) {
$new_str= '';$str= 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwsyz0123456789';for($i= 1; $i
}
使用数据库bigint自增字段(保证唯一),转成62进制缩短长度:
其实想要唯一最好的办法还是uuid。。