有哪些能够生成随机不重复字符串的算法或者函数?最好是 PHP 中的~~
1
ayuanshuai929 2016-05-18 16:36:29 +08:00 via iPhone
md5(time())算不算,但是不能保证永不重复,只能说重复的概率非常小
|
2
skywalkboy 2016-05-18 16:45:19 +08:00
之前看 tomcat 生产 sessionId 的时候用了函数查看是否重复,没有重复才返回
|
3
abelyao 2016-05-18 16:49:02 +08:00
@ayuanshuai929 分布式时候重复的概率还蛮大的
|
4
abelyao 2016-05-18 16:49:45 +08:00
不说长度要求的 都是耍流氓
|
5
walkman660 2016-05-18 16:51:28 +08:00
#!/bin/bash
echo $RANDOM |
6
lslqtz 2016-05-18 16:55:50 +08:00
@ayuanshuai929 md5(time().随机字符.随机数字) 有多长来多长。
|
8
Sunyanzi 2016-05-18 17:01:25 +08:00 10
严格意义上讲生成一个「随机」且「不重复」的字符串是不可能的 ... 因为随机和唯一是互斥的两个条件 ...
生成不重复的字符串必须遵循一定规则 ... 这就不随机 ... 反之则一定存在碰撞概率 ... 只是这个概率或大或小而已 ... 所以对于标题的问题 ... 答案是一个都没有 ... 但如果你要的是一个「看似随机」且「没有那么容易重复」的方法的话 ... 那倒是有不少 ... 比如我个人常用的 uniqid( mt_rand( 0, 9999 ), true ) ... 碰撞条件是同一微秒内的万分之一概率 ... 或者唯一性要求不那么高的时候常用的在毫秒时间戳外面套一层摘要函数的办法 ... 如 md5( microtime() ) ... 这种方式生成速度比 uniqid 要快 ... 但碰撞条件不明且碰撞概率一定高于 uniqid ... 顺带一提楼上说的在时间戳后面增加随机字符串的方式除了拖慢执行之外毫无意义 ... 并不会降低碰撞概率 ... |
9
yeyuexia 2016-05-18 17:09:49 +08:00 1
如果是 linux 或者 mac 上 试试在命令行直接敲 uuidgen 吧……
|
10
debiann 2016-05-18 17:11:03 +08:00 via iPhone
利用 ascii 码自己写一个很简单的吧,重复概率取决于长度
|
11
yeyuexia 2016-05-18 17:12:38 +08:00 1
补上一条 关于 uuid 出现冲突的可能性见 https://en.wikipedia.org/wiki/Universally_unique_identifier
话说话题是不是可以终结了? |
12
hgc81538 2016-05-18 17:19:46 +08:00
<?php
$length = 32; $crypto_strong = true; $bytes = openssl_random_pseudo_bytes($length, $crypto_strong); $hex = bin2hex($bytes); print_r($hex); |
13
Specs OP @skywalkboy 这种不适合存在数据库中啊~每次检查一次,如果数据量比较大的话那。。。。
|
14
Orzzzz 2016-05-18 17:47:43 +08:00
|
15
SlipStupig 2016-05-18 18:39:02 +08:00
用 100 次鼠标移动位置的坐标生成一个 RSA 1024 的字符串,基本上没什么重复的可能性!
|
16
skywalkboy 2016-05-18 18:40:10 +08:00
@Specs 用过的可以放内存中(redis),看你怎么取舍了,一般重复的概率是很小的,但是如果你一定要保证不重复,那就要比较了
|
17
vibbow 2016-05-18 18:40:44 +08:00
为什么...不用...UUID 呢...
|
18
dqh3000 2016-05-18 18:44:41 +08:00
你想要的是 uuid 算法,去看看 uuid v3 , uuid v5 之类的 RFC 吧
|
19
est 2016-05-18 18:44:52 +08:00
LZ 要的是随机字符和历史产生的不重复,还是字符串里的字符不重复?
如果是后者,只算字母数字,最大长度 26+10 位。 LZ 我没说错吧。 py 里可以这样 >>> ''.join(random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for _ in xrange(10)) 'kaz2spd3hy' |
20
kindjeff 2016-05-18 18:53:31 +08:00
@est 没看懂代码……请教一下这句代码是什么意思?下划线代表什么,为什么 for 语句可以放在同行,为什么 random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for _ in xrange(10)会报错……
|
24
misaka19000 2016-05-18 18:59:27 +08:00 via Android
UUID
妥妥的 |
27
dphdjy 2016-05-18 20:13:33 +08:00 via Android
分布式大概用机器编码+特征码+时间
其实用 UUID 不就解决了~ |
28
Sunyanzi 2016-05-18 20:15:01 +08:00 6
@lslqtz 基本没可能和绝对没可能是天壤之别 ... 至于 md5 唯一什么的 ... 你运行一下下面代码开开眼 ..?
<?php foreach( [ [ '0', '5' ], [ '4', 'd' ] ] as $v ) echo md5( pack( 'H*', '0e306561559aa787d00bc6f70bbdfe3404cf03659e7' . $v[0] . '4f8534c00ffb659c4c8740cc942feb2da115a3f415' . $v[1] . 'cbb8607497386656d7d1f34a42059d78f5a8dd1ef' ) ), PHP_EOL; |
30
realpg 2016-05-18 21:32:59 +08:00
不说长度?
$hash=""; for ($i=1;$i<100;$i++) $hash .= md5(rand(1,999999999)); |
31
zhujinliang 2016-05-18 21:45:19 +08:00 via iPhone
@realpg 连续做伪随机并不会提高随机性
|
32
realpg 2016-05-18 21:47:04 +08:00
@zhujinliang
本题要的并不是随机性,有一定的随机度即可,关键是不重复。 |
34
loading 2016-05-18 21:56:33 +08:00 via Android
拼接,简单的随机+时间戳
第一时间我想到的是 uuid ,上面有人提到,我就不细说了。 |
35
barbery 2016-05-18 23:35:44 +08:00
echo bin2hex(random_bytes($length/2));
|
36
lianyue 2016-05-18 23:49:52 +08:00
|
37
techme 2016-05-19 08:55:32 +08:00
Guid().newID()
|
38
notgod 2016-05-19 09:00:59 +08:00
查看“ php 短网址生成程序”的算法就好了
|
39
Neveroldmilk 2016-05-19 09:26:05 +08:00
大部分语言内置的随机生成器,只能保证在一定范围内哈希值不重复,没有绝对随机的生成器。这一点可以参考 Donald Knuth 的 the art of computer programming 第二卷里的内容。
|
41
lygmqkl 2016-05-19 11:16:51 +08:00
其实我倒有个新思路
大家在上面谈到的都是怎么生成一定概率不重复的随机字符串,这些概率一般都是在单 server 和少量请求的情况下,一旦放到到复杂的架构中,比如 20 台 servers + 10k/s 请求多半都是歇菜 我想说的是利用一些简单的思路实现 100%不重复的随机字符串,具体如下: 大家只是把随机字符串妖魔化了,其实 1 , 2 , 3 , 4 , 5 不就是不重复的随机字符串吗?好吧如果你要随机字符串 md5(1) 就可以实现,或者利用拼接的方法因为你有 unique 的部分即 1, 2, 3, 4, 5 那么实现方法也很简单 $topic = new Topic(); //TODO add necessary attributes if ($topic->save()) { $randString = md5($topic->t_id); echo $randString;//c20ad4d76fe97759aa27a0c99bff6710 }else{ //save fail, do sth } demo code 是用 Yii 写的应该能看得懂 牺牲的是一次数据库写入操作,得到的是一个 unique 的 seed, 这和老实的 order 系统很接近,我唯一做的事情就是把它放到了 RESTful 架构中,真的很好用。 另外附上我前一阵写的一篇文章,希望对楼主有帮助 http://yiilib.com/topic/671/php%E7%94%9F%E6%88%90100%25%E4%B8%8D%E9%87%8D%E5%A4%8D%E9%9A%8F%E6%9C%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95 |
43
niuoh 2016-05-19 11:29:30 +08:00
function r($len=5){
$array=range(chr(33),chr(125)); shuffle($array); for($i=0;$i<$len;$i++)$result.=$array[$i]; return $result; } echo r(5); |
46
lhbc 2016-05-19 12:43:33 +08:00 via Android
单机的话,自增 uid+随机字符串
绝对不重复,有一定随机性 |
47
fyooo 2016-05-19 14:18:00 +08:00
OCaml:
let random_str length = let gen() = match Random.int(26+26+10) with n when n < 26 -> int_of_char 'a' + n | n when n < 26 + 26 -> int_of_char 'A' + n - 26 | n -> int_of_char '0' + n - 26 - 26 in let gen _ = String.make 1 (char_of_int(gen())) in String.concat ~sep:"" (Array.to_list (Array.init length ~f:gen)) |
48
fyooo 2016-05-19 14:18:52 +08:00
忽略我的回复,刚刚才看到是 PHP 节点的
|
49
9hills 2016-05-19 14:43:37 +08:00
楼上为啥有这么多重复造轮子的。。而且造的还很烂,根本不符合要求
现成的 UUID ,各个语言都有对应的库,嫌太长也有 short uuid 。 |
50
glchaos 2016-05-19 16:55:44 +08:00
随机的重要程度和唯一的重要程度哪个更高些?时效有没有要求?
|
51
ty0716 2016-05-19 17:12:58 +08:00 via iPhone
加上用户 id 就 ok 了
|
53
innoink 2016-05-19 18:05:24 +08:00 via Android
首先如果是无限数量肯定不能同时保证唯一和随机
数量不多的话我倾向于预先生成 |
54
20131115 2016-05-19 18:08:42 +08:00
说 md5 的是没考虑性能。。。生成 10 亿给大家看看
|
55
xujif 2016-05-19 18:16:45 +08:00
php 肯定是 uniqid 啊,楼上都在想什么 http://php.net/manual/zh/function.uniqid.php
|
56
cszchen 2016-05-19 19:04:49 +08:00 via iPhone
uniqid 也有概率重复,可以一个进程专门生成随机串,插入到队列,需要的时候从队列取
|
57
paulw54jrn 2016-05-19 19:07:44 +08:00
uuid4
|
58
akagi 2016-05-19 19:20:13 +08:00
@ayuanshuai929 高速调用会重复吧
|
59
pagxir 2016-05-19 19:58:30 +08:00 via Android
Des(0) des(1) des(2) ... 保证不重复,并且看似随机。
|
60
AbrahamGreyson 2016-05-19 20:14:41 +08:00 1
twitter 有个库,不过根据其算法,只能保证 x 年内不重复,自己搜吧。
|
61
a591826944 2016-05-19 20:20:07 +08:00
@lslqtz 分布式同一时间 同一函数,生成的随机数字 /字符 是相同的 所以 后面 拼多少都没有用
|
62
zhicheng 2016-05-19 20:30:53 +08:00 via Android
说 MD5 慢的,你咋不上天, 10 亿也是秒级的。
|
63
icylord 2016-05-19 21:01:02 +08:00
UUID
|
64
jfcherng 2016-05-19 22:33:58 +08:00
有限長度與不重複不是明顯互斥嗎
|
65
miaotaizi 2016-05-20 09:38:34 +08:00
@Sunyanzi 开眼了, 看了你好多的评论, 你收徒弟么, 请收下我的膝盖, 我不想做那个四年都在做同一件事情的码农.
|
66
Specs OP |
67
juice 2016-05-20 11:31:05 +08:00
可以参考 twitter 的 Snowflake 算法
|
68
necomancer 2016-05-20 12:22:10 +08:00
UUID 吧, 重复概率极小
|
69
Sunyanzi 2016-05-20 23:39:59 +08:00 1
@miaotaizi 收呀 ... 我一直有琢磨着拉个群讲讲课什么的 ... 但一直没时间来做 ... 过阵子看看吧 ..?
@juice @AbrahamGreyson Snowflake 算法从本身的设计上并没有避免多线程并发时重复生成的问题 ... @Specs 如果最终你会把内容存在数据库的话 ... 那么给相关字段上唯一索引然后生成随机字符串往里插就是 ... 只要字符串长度足够就可以完全不用管是否会重复 ... 如果插不进去就重新随机一次再插 ... 直到成功为止 ... |