BearRui(AK-47)
花开有时,错过了一日便错过了一季,就象人生错过了相遇,就不再找寻到美丽的相聚
随笔- 39  文章- 2  评论- 1288 
博客园  首页  新随笔  联系  管理  订阅 订阅
产生唯一随机码的方法分析。

  现在的WEB中经常会需要产生一些邀请码、激活码。需要是唯一并且随机的。下面总结下一些常用的产生随机码的方法,并分享自己的1个方法:

 

1. 自己写代码产生随机的数字和字母组合,每产生1个去数据库查询该随机码是否已存在,如果已存在,则重新产生,直到不重复为止。

     优点:没发现有啥优点。     

     缺点:产生速度慢,还要查询数据库,当数据量大的时候,可能重复的机率会比较高,要查询多次数据库.

 

2. guid,该方法应该是用的比较多的。     

  优点:使用简单方便,不用自己编写额外的代码     

  缺点:占用数据库空间相对较大,特别是根据guid查询速度比较慢(毕竟是字符串)。

 

3. 主键+随机码的方式,我们产生的随机码保存到数据库肯定会有个主键,用该主键+随机字符来组合。产生步骤:     

  1) 先从id生成器中获取id,比如是155.     

  2)填充成固定位数(比如8位)的字符串(不够位数的左边填0,超过位数直接使用该数字),得到:00000155     

  3)在每个数字后面随机插入1个字母或其它非数字符号,得到:0A0F0R0Y0H1K5L5M

   这样就可以得到1个随机的唯一的邀请码了。    

  优点:使用也比较简单,不用查询数据库。最大的优点是查询的时候,可以根据邀请码直接得到主键id,     

     然后根据id去数据库查询(速度很快),再比较查询出来的邀请码和用户提交的邀请码是否一致。    

  缺点:需要使用id产生器,如果主键是数据库自增长的就不太好用(需要先插入数据库获取id,再更新邀请码)。

 

4. 有时候产品经理说,我要求邀请码都是数字的。why?no why? 我喜欢。*(&^(^%&^$&^$ 把方法3变通下就可以实现唯一的纯数字随机码了。    

  1) 获取id: 155    

  2) 转换成8进制:233    

  3) 转为字符串,并在后面加'9'字符:2339    

  4)在后面随机产生若干个随机数字字符:2003967524987 

   转为8进制后就不会出现9这个字符,然后在后面加个'9',这样就能确定唯一性。最后在后面产生一些随机数字就可以。

      优缺点同方法3

 

目前方法3,4方法在我们产品中都使用了,感觉还可以。 


PS:以上是个人浅见,有更好方法的同学请分享下。^_^ 

[作者]:BearRui(AK-47)
[博客]: http://www.cnblogs.com/BearsTaR/
[声明]:本博所有文章版权归作者所有(除特殊说明以外),转载请注明出处.
绿色通道:好文要顶关注我收藏该文与我联系
posted on 2010-10-19 09:38 BearRui(AK-47) 阅读(4476) 评论(40) 编辑 收藏
发表评论
2101147
 回复 引用 查看   
#1楼 2010-10-19 09:40 | ffffff      
还不错呀,楼主可以参考一下,吉日嘎拉序列号生成器模块,灵活,好用,不重复。呵呵,我正在用呢。
 回复 引用 查看   
#2楼[楼主] 2010-10-19 09:41 | BearRui(AK-47)      
@ffffff
谢谢,序号生成器跟这个不太一样,序号生成器之需要唯一就行,而且一般是递增。我们需要唯一+随机(不容易猜测)。

 回复 引用 查看   
#3楼 2010-10-19 09:47 | 西狐      
GUID
 回复 引用   
#4楼 2010-10-19 09:50 | mr.ing官方[未注册用户]
不错..刚好用到这个..
 回复 引用 查看   
#5楼[楼主] 2010-10-19 09:51 | BearRui(AK-47)      
@mr.ing官方
呵呵,谢谢!

 回复 引用 查看   
#6楼[楼主] 2010-10-19 09:52 | BearRui(AK-47)      
@西狐
各种方法都有优点缺点,看自己的需求选择,^_^

 回复 引用 查看   
#7楼 2010-10-19 10:01 | heros      
12当然都不会出现重复码,各种场景也都适用。
34有局限性,有些需求是基于一个键生成n个码的,我就遇到这样的需求,1个主键要对应生成数十万个不同的码,这时候1方法不能用,34也不能用。
我的做法是在主键之上,再加一个递增键值,对生成的码进行转码处理,转码算法要注意不能重复,也不能很容易就猜解。
当然这个方法也有缺点,在固定码位的情况下,会有大量码浪费,也就是要保证码位足够长。

 回复 引用 查看   
#8楼 2010-10-19 10:01 | szyicol      
熊又出没了!!


查询字符串要慢多少

 回复 引用 查看   
#9楼[楼主] 2010-10-19 10:06 | BearRui(AK-47)      
@heros
对,其实最主要还是看需求,你的的需求可以综合3,4方法一起使用,先根据id转8进制+'9',然后用方法3产生1个递增的数字,8位填充,填充随机字母,然后把2个合并在一起就可以。

 回复 引用 查看   
#10楼[楼主] 2010-10-19 10:07 | BearRui(AK-47)      
@szyicol
^_^

要看数据量,如果数据库量超过50W,不建索引的话,速度就会明显慢下来,如果建立索引的话,在插入的时候因重建索引就会慢点。反正我比较反对用字符串进行查询。

 回复 引用   
#11楼 2010-10-19 10:10 | 赖小天2[未注册用户]
直接用时间不就行了,时间不可能有重复的吧
 回复 引用 查看   
#12楼 2010-10-19 10:10 | 不死鸟之魂      
如果是类似“邀请码”这类的话,其实就不在乎位数,也就是说长度不是问题。那么,可以rand一个32位的在hash一下,就可以了。32位长度就是目前IPv4地址个数,出现重复的概率比较低。当然,为了防止重复,可以查询数据库,也就是博主所说的方法1。
事实上,位数越大,出现重复的概率就越低。你要是能够在短时间内产生连续好几个重复的数,那你直接去买彩票算了。

还有,“邀请码”可以设置时间的,过期不候。那么,即使产生重复的,只要在时间范围之外就不管了。

 回复 引用 查看   
#13楼 2010-10-19 10:12 | 林发      
不错
 回复 引用 查看   
#14楼 2010-10-19 10:12 | heros      
@赖小天2
时间是不重复,但计算机中的时间取值是有位数的。单纯的用时间是可能被猜解的。

 回复 引用 查看   
#15楼[楼主] 2010-10-19 10:13 | BearRui(AK-47)      
@赖小天2
用时间不可靠,当系统并发很高,而且采用集群的方式的话,很难保证不产生相同的时间戳。

 回复 引用 查看   
#16楼[楼主] 2010-10-19 10:21 | BearRui(AK-47)      
@不死鸟之魂
其实长度影响却是不大,用你的rand 32位的方法,还不如直接用guid。

我个人觉的影响比较大是查询速度,当数据库比较大的时候。

 回复 引用 查看   
#17楼[楼主] 2010-10-19 10:24 | BearRui(AK-47)      
@林发
谢谢,^_^

 回复 引用 查看   
#18楼 2010-10-19 10:35 | csz_fj      
转8进制那个方法不错。独辟蹊径。
 回复 引用 查看   
#19楼 2010-10-19 10:38 | quange      
为什么不能使用时间+随机数+KEY 然后MD5呢
 回复 引用 查看   
#20楼[楼主] 2010-10-19 10:49 | BearRui(AK-47)      
引用csz_fj:转8进制那个方法不错。独辟蹊径。


谢谢,^_^

 回复 引用 查看   
#21楼[楼主] 2010-10-19 10:50 | BearRui(AK-47)      
引用quange:为什么不能使用时间+随机数+KEY 然后MD5呢


思路差不多,实现方式可以很多样,你说的也可以。

不过不需要MD5,如果用MD5的话,你怎么根据MD5获取到对应的KEY?

 回复 引用 查看   
#22楼 2010-10-19 11:43 | 大白      
只是邀请码而已,又不是什么序列号。你弄个时间的ticks,就可以 了。然后累加。时间总是向前的。应该不会重复的。就算把系统的时间调整提前,重复的几率也不大。时间的刻度,足够大到你用的。差一秒就差好多。当然,不排除一次生成几千万或亿的,并且调整系统时间的。。只是如果非得考虑系统时间调整,那也没办法。
 回复 引用 查看   
#23楼[楼主] 2010-10-19 12:13 | BearRui(AK-47)      
@大白
所谓的邀请码,肯定不能随便让别人猜测到,你用时间累加,很容易被猜测到

 回复 引用 查看   
#24楼 2010-10-19 12:30 | 不死鸟之魂      
@BearRui(AK-47)
不存在数据库查询问题。在有索引的情况下,定位是很快的。除非你没事老向数据库select。

 回复 引用 查看   
#25楼 2010-10-19 12:51 | allentranks      
8进制那个不错,有想法!个人觉得还是Guid比较好。邀请码用完就删了呗~不好删要留着,建索引呗~ 另外,guid应该不是字符串吧?是一个长度为128的位序列
 回复 引用 查看   
#26楼[楼主] 2010-10-19 13:12 | BearRui(AK-47)      
@allentranks
guid你保存到数据库不就是varchar吗

 回复 引用 查看   
#27楼 2010-10-19 15:38 | Cocos      
你能保证它唯一吗?
 回复 引用 查看   
#28楼 2010-10-19 15:45 | hui      
@BearRui(AK-47)
SQL Server 有个类型uniqueidentifier .

 回复 引用 查看   
#29楼[楼主] 2010-10-19 16:00 | BearRui(AK-47)      
引用Cocos:你能保证它唯一吗?

当然能保证唯一啊,不知道你觉的哪里有问题。

 回复 引用 查看   
#30楼[楼主] 2010-10-19 16:01 | BearRui(AK-47)      
引用hui:
@BearRui(AK-47)
SQL Server 有个类型uniqueidentifier .


哦,SQL Server不清楚,这个uniqueidentifier是专门直接保存guid的?

 回复 引用 查看   
#31楼 2010-10-19 16:08 | 吉日嘎拉 不仅权通用权限      
有时候啥文章能上头条,都说不定的,哈哈。

 回复 引用 查看   
#32楼[楼主] 2010-10-19 16:11 | BearRui(AK-47)      
@吉日嘎拉 不仅权通用权限
hoho,还真没注意,一不小心上头条了,看来该文章也能说点是非。

 回复 引用 查看   
#33楼 2010-10-19 16:13 | 吉日嘎拉 不仅权通用权限      
@BearRui(AK-47)

对我来说,人人都有高兴的权利,上了头条,作者都会小小开心一下,谁叫那些大牛不写文章了,也让草根偶尔高兴一下,也未必是坏事,哈哈。

人人都有上头条的权利嘛,别人不高兴了,但是还是有人高兴的嘛。

 回复 引用 查看   
#34楼[楼主] 2010-10-19 16:23 | BearRui(AK-47)      
呵呵,博客园一般只有是非比较多的才能上头条吗。
 回复 引用 查看   
#35楼 2010-10-19 22:59 | 创新学习者      
MS SQL Server 有个类型uniqueidentifier .然后GUID 。我经常这么干啊。也可以作为邀请码。
 回复 引用 查看   
#36楼 2010-10-20 09:02 | coolypf      
3,4可以做如下改进:

生成随机串,插入数据库,获取id。

邀请码=f(id, 随机串)

验证 随机串(邀请码)==select(id(邀请码))

 回复 引用 查看   
#37楼[楼主] 2010-10-20 09:10 | BearRui(AK-47)      
@coolypf
原理差不多,实现方式可以多样化,^_^

 回复 引用 查看   
#38楼 2010-10-20 09:12 | coolypf      
@BearRui(AK-47)
少了一次update,看你似乎对此很在意@@

 回复 引用 查看   
#39楼[楼主] 2010-10-20 09:16 | BearRui(AK-47)      
@coolypf
如果主键是自增的话用你这种方式比较合适,如果主键是系统产生的,则不需要update

 回复 引用   
#40楼 2011-05-19 15:25 | littlear[未注册用户]
关键字"UUID"~在根据自己需要的长度和要求加工~比如MD5啥的.
刷新评论列表  刷新页面  返回页首
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

验证码: 验证码 看不清,换一个

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1855319 aFu8tElXUIo=
首页博问闪存新闻园子招聘知识库
最新IT新闻:
· 传免费对讲机应用Voxer欲融资2000万美元
· 在线编程挑战平台Interview Street帮程序员通过编程竞赛进入名企
· Pinterest发展势头超Facebook:融合社交与电商
· Facebook广告合作伙伴针对时间线推出新服务
· 顶级天使投资人罗恩·康维:创业融资环境非常好
» 更多新闻...
最新知识库文章:
· 编程的艺术:漂亮的代码和漂亮的软件
· GIT分支管理是一门艺术
· 编程:是一门艺术
· 编程是一门艺术吗?
· 对Java初学者的忠告
» 更多知识库文章...

China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务

抓虾
google reader
鲜果
哪吒
QQ邮箱
http://wap.feedsky.com/BearRui
昵称:BearRui(AK-47)
园龄:5年10个月
荣誉:推荐博客
粉丝:127
关注:3

搜索

 

最新随笔

  • 1. 产生唯一随机码的方法分析。
  • 2. URL中允许携带sessionid带来的安全隐患。
  • 3. JS 实现完美include
  • 4. 基于模板的excel导出
  • 5. 实现if elseif else的jsp标签。
  • 6. 记一复杂页面的前端优化(2) - 其他优化
  • 7. 记一复杂页面的前端优化(1) - 不一样的延迟加载
  • 8. 名站技术分析 — tudou网首页下列菜单的弹出效果
  • 9. LESS 让css也支持变量,运算符,include,嵌套规则等等
  • 10. CSS技巧 — 不使用图片实现圆角、阴影、渐变等功能

随笔分类(38)

  • .NET(11)
  • CSS(3)
  • JAVA(2)
  • javascript(4)
  • Life(5)
  • WEB(4)
  • 高性能WEB开发(5)
  • 浏览器(1)
  • 名站技术分析(3)

随笔档案(39)

  • 2010年10月 (1)
  • 2010年8月 (3)
  • 2010年7月 (5)
  • 2010年6月 (4)
  • 2010年5月 (6)
  • 2006年6月 (4)
  • 2006年5月 (7)
  • 2006年4月 (9)

积分与排名

  • 积分 - 178246
  • 排名 - 485

最新评论

阅读排行榜

评论排行榜

推荐排行榜

Copyright ©2012 BearRui(AK-47)