12位纯数字兑换码的生成算法,如何尽可能保证不重复?

发布于 2022-09-04 06:59:50 字数 276 浏览 16 评论 0

在只有PHP和mysql的环境下,做一个简单的发券、核销程序。其中券的兑换码必须为12位数字,数据量不会超过千万。如何生成不重复且乱序的券码?

最糟糕的方案是纯随机,然后到表里查一遍是否重复,重复则重新生成;不重复则插入

一个自认为好点的方案是用户id加一位随机数加截取时间戳后x位
例如用户ID为123,则是3位,加随机数4位。此时剩余8位则截取时间戳后8位补上。重复概率应该就很低了

在尽可能不遍历表的情况下,还有更难以重复的生成算法吗?求不吝赐教

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陈独秀 2022-09-11 06:59:50

如果是按照用户ID和时间戳等生成md5摘要的方式的话,可以用base_convert将哈希后的md5值转为10进制,不过这样转出来的结果值长度肯定就不止12位了,还需要用字符串截取函数截取一下,但原本几十位的十进制数只截取12位那么唯一性就无法保证了,可能还不如直接截取ID加时间戳,看你的描述应该是在用户请求的时候才生成码,那么一个用户同一秒不能生成多张的情况下组合部分时间戳和用户ID还是没问题的。

冷…雨湿花 2022-09-11 06:59:50

考虑用户的ID和时间进行消息摘要算法,比如最简单内置的MD5或者SHA1,然后对于结果进行一定的压缩或者提取,转化成12位的

与之呼应 2022-09-11 06:59:50

我感觉你的想法挺好啊,还可以还原进行验证兑换码的合法性。

殊姿 2022-09-11 06:59:50

消息摘要算法太混沌了,压缩到12位后效果和随机没有区别,多了还是会碰撞。

楼主的做法(id + 时间戳 + 随机数)基本能满足不碰撞的要求了,问题在于乱序。

可以仿效线性同余生成伪随机数的方法,找个大素数a和常数b,把id + 时间戳 + 随机数生成的数字输入函数f(x) = a * x + b (mod 1,000,000,000,000)里,只要a足够大(数量级跟1,000,000,000,000相近)就很随机了。而且由于a是素数,f是可逆的,这也保证了只要输入不重复,输出也不会重复。

另外建议拼接数字时把随机数放在高位,这样运算后输出的差别更大。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文