有哪些能够生成随机不重复字符串的算法或者函数?

2016-05-18 16:22:50 +08:00
 Specs

有哪些能够生成随机不重复字符串的算法或者函数?最好是 PHP 中的~~

10444 次点击
所在节点    PHP
73 条回复
ayuanshuai929
2016-05-18 16:36:29 +08:00
md5(time())算不算,但是不能保证永不重复,只能说重复的概率非常小
skywalkboy
2016-05-18 16:45:19 +08:00
之前看 tomcat 生产 sessionId 的时候用了函数查看是否重复,没有重复才返回
abelyao
2016-05-18 16:49:02 +08:00
@ayuanshuai929 分布式时候重复的概率还蛮大的
abelyao
2016-05-18 16:49:45 +08:00
不说长度要求的 都是耍流氓
walkman660
2016-05-18 16:51:28 +08:00
#!/bin/bash
echo $RANDOM
lslqtz
2016-05-18 16:55:50 +08:00
@ayuanshuai929 md5(time().随机字符.随机数字) 有多长来多长。
dawniii
2016-05-18 16:59:33 +08:00
@lslqtz md5 好像是多对一的。。 还是会重复
Sunyanzi
2016-05-18 17:01:25 +08:00
严格意义上讲生成一个「随机」且「不重复」的字符串是不可能的 ... 因为随机和唯一是互斥的两个条件 ...

生成不重复的字符串必须遵循一定规则 ... 这就不随机 ... 反之则一定存在碰撞概率 ... 只是这个概率或大或小而已 ...

所以对于标题的问题 ... 答案是一个都没有 ...

但如果你要的是一个「看似随机」且「没有那么容易重复」的方法的话 ... 那倒是有不少 ...

比如我个人常用的 uniqid( mt_rand( 0, 9999 ), true ) ... 碰撞条件是同一微秒内的万分之一概率 ...

或者唯一性要求不那么高的时候常用的在毫秒时间戳外面套一层摘要函数的办法 ... 如 md5( microtime() ) ...

这种方式生成速度比 uniqid 要快 ... 但碰撞条件不明且碰撞概率一定高于 uniqid ...

顺带一提楼上说的在时间戳后面增加随机字符串的方式除了拖慢执行之外毫无意义 ... 并不会降低碰撞概率 ...
yeyuexia
2016-05-18 17:09:49 +08:00
如果是 linux 或者 mac 上 试试在命令行直接敲 uuidgen 吧……
debiann
2016-05-18 17:11:03 +08:00
利用 ascii 码自己写一个很简单的吧,重复概率取决于长度
yeyuexia
2016-05-18 17:12:38 +08:00
补上一条 关于 uuid 出现冲突的可能性见 https://en.wikipedia.org/wiki/Universally_unique_identifier
话说话题是不是可以终结了?
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);
Specs
2016-05-18 17:34:30 +08:00
@skywalkboy 这种不适合存在数据库中啊~每次检查一次,如果数据量比较大的话那。。。。
Orzzzz
2016-05-18 17:47:43 +08:00
@Specs php 调用系统命令 uuidgen 啊,之后随便怎么处理那些字符串

<?php
$code = exec('uuidgen');

echo $code;
SlipStupig
2016-05-18 18:39:02 +08:00
用 100 次鼠标移动位置的坐标生成一个 RSA 1024 的字符串,基本上没什么重复的可能性!
skywalkboy
2016-05-18 18:40:10 +08:00
@Specs 用过的可以放内存中(redis),看你怎么取舍了,一般重复的概率是很小的,但是如果你一定要保证不重复,那就要比较了
vibbow
2016-05-18 18:40:44 +08:00
为什么...不用...UUID 呢...
dqh3000
2016-05-18 18:44:41 +08:00
你想要的是 uuid 算法,去看看 uuid v3 , uuid v5 之类的 RFC 吧
est
2016-05-18 18:44:52 +08:00
LZ 要的是随机字符和历史产生的不重复,还是字符串里的字符不重复?

如果是后者,只算字母数字,最大长度 26+10 位。 LZ 我没说错吧。 py 里可以这样

>>> ''.join(random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for _ in xrange(10))
'kaz2spd3hy'
kindjeff
2016-05-18 18:53:31 +08:00
@est 没看懂代码……请教一下这句代码是什么意思?下划线代表什么,为什么 for 语句可以放在同行,为什么 random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for _ in xrange(10)会报错……

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

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

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

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

© 2021 V2EX