如何才能生成一个唯一的随机数

2012-08-27 18:14:26 +08:00
 macdino
正在做一个优惠券相关的系统:
要求:生成的优惠券验证码为6位,并且唯一。
因为系统中有N个优惠券同时提供,所以这个6位不好生成唯一。
大家有什么好的想法或算法。
系统的服务并发不大,预计每天请求20W次左右。
11917 次点击
所在节点    问与答
41 条回复
stackpop
2012-08-27 18:16:30 +08:00
生成的时候做个哈希表查一下?
acalarolo
2012-08-27 18:18:35 +08:00
加上MAC地址戳?
macdino
2012-08-27 18:24:40 +08:00
@acalarolo 我提供的服务,mac地址肯定是服务器的。。
macdino
2012-08-27 18:25:43 +08:00
@stackpop 这样子只能保证最终生成的是唯一的。但是有可能需要生成N次。
dingstyle
2012-08-27 18:32:21 +08:00
uuid
summic
2012-08-27 18:32:43 +08:00
@macdino 这个有必要吧,毕竟你有6位长度限制。又不能是递增
macdino
2012-08-27 18:36:35 +08:00
@dingstyle UUID 长度32.。。
acalarolo
2012-08-27 18:44:42 +08:00
@macdino 我是指用户的MAC……难道不是用户请求时生成的?
macdino
2012-08-27 18:49:43 +08:00
@acalarolo 提供的是一个服务,应该是服务器对服务器的,而且允许通过各种手段获取,手机,短信,APP,WEB,MAIL。=====
acalarolo
2012-08-27 19:14:44 +08:00
@macdino 额,我不是互联网行业的,请容我钻下牛角尖哈……就多种获取手段而言,只要走TCP/IP的应该都有MAC地址吧,短信有号码,MAIL有MAIL地址,任何请求都应有唯一标示参数的吧……

……当然6位比较少,加MAC之类的不现实。可以这样操作:6^10=60466176,进程1由零开始步进分发,进程2由六百万开始步进分发,共分10个线程每个六百万,剩余466176备用……如果可以用拉丁字母的话……
ming
2012-08-27 19:15:27 +08:00
加个时间相关就可以了
ming
2012-08-27 19:16:30 +08:00
前3位是时间相关生成的 后3位你自己看着办
luin
2012-08-27 19:17:52 +08:00
可以用递增的数字转成高进制:

http://zihua.li/2012/05/implement-shortlink-using-base-62/
yuelang85
2012-08-27 19:24:02 +08:00
可以预先准备出来吗?如果这样的话,自增数字+字母组合,先做出来,然后一个一个的发。。。。
acalarolo
2012-08-27 19:24:29 +08:00
额,应该是10^6=1000000个……反正我的意思是每个线程有唯一的一个池子……
yuelang85
2012-08-27 19:29:23 +08:00
我想起来这里一哥们出的牛逼招数,每位都随机一下。。。。
reorx
2012-08-27 20:01:59 +08:00
既然要求唯一,就最好不要用“随机”的算法来生成了,那么其实只是看起来像随机数吧?
gockxml
2012-08-27 20:37:32 +08:00
要想通过随机生成是不可能的,因为会有概率重复。因此正确的方法应该是映射。
所以要想办法把一个数通过各种操作变换到另一个数,而且这个过程是可逆的。这个过程可以通过各种运算变得看似随机。
举个例子,二进制a=[1,1,1], b初始化为a[0],即b=[1],接下来拿a[1:]的每一个元素与b的最后一个元素做异或运算,并且添加到b中,b最终为[0,1,0],而且完全可以通过b倒推a!这里只是提供个思路,还可以通过更复杂的方法增加随机度。
附一份自己写的代码https://gist.github.com/3488007 , 希望有所帮助。
litten
2012-08-27 21:50:27 +08:00
我想起通信领域要用到这样的需求,貌似一般是做“伪随机序列”。
用到的算法叫做“M序列算法”——
详见:http://baike.baidu.com/view/3578502.htm
013231
2012-08-28 01:01:01 +08:00
很簡單的.
全部的6位正整數不過1M個, 按一個數8字節算總共不過8M字節, 完全可以全部裝入内存.
所以先生成一個長度1M的整數數組, 包含每一個6位數, 然後對這個數組洗牌. 需要數字的時候從這個數組中依次取數就行了, 用完前肯定不會有重復.
http://gist.github.com/3490375

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/46204

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX