如何生成固定长度唯一随机字符串?

2018-01-15 17:41:45 +08:00
 xfund4
1. 字符串长度固定在 8 位[a-zA-Z0-9],仅要求千万数据量下保证唯一
2. 不需要根据随机串解码出原值。
3. 随机串不能被猜测出。
4. 有自增 ID 可以使用,但是随机串不能有规律。
13905 次点击
所在节点    PHP
57 条回复
zjp
2018-01-15 18:31:46 +08:00
我用的是时间戳加 4 位随机数,限制 8 个字符的话时间戳范围取小一点不知道够不够
toan
2018-01-15 18:44:48 +08:00
@Magnus1k 赞同。不想碰撞的话,先生成,后随机挑。
目前我这做过一个实例,先生成可用数据池数据,比如先生出 2 万,生成的时候进行唯一检验,使用的时候从该池子里随机挑选,增加使用取数的效率。当池子数据量低于某个阈值了,就重新生成补满池子。
ylsc633
2018-01-15 18:48:45 +08:00
用这个吧 hashids

我用过,感觉还不错,没有应用到大项目里,所以 测不出性能消耗

这个只需要你保管好自己的 salt 就行了!

用的 这个包 https://github.com/ivanakimov/hashids.php

具体实践 类似于 https://www.g9zz.com/post/6ravkEd7bx 这种吧 后面是定长的,且没有特殊字符,还可反解出来
xfund4
2018-01-15 18:58:20 +08:00
谢谢诸位提供的方案, 因为有自增 ID 来为保证唯一。确实 hashids 的方案比较适合。

@chinvo @ylsc633
xfund4
2018-01-15 18:59:52 +08:00
@chinvo @Magnus1k @toan 如果没有自增 ID,并且不希望是预生成的。 有没有更好的办法呢
l1093178
2018-01-15 19:01:03 +08:00
完全随机的话,到 sqrt(62 ^ 8) ~= 14, 000, 000 这个数量级就会出现冲突( https://zh.wikipedia.org/wiki/生日問題),所以说只能考虑除了完全随机之外的方案
可以考虑用这个库: https://github.com/c2h5oh/hide
Kilerd
2018-01-15 19:03:07 +08:00
sha3
moult
2018-01-15 19:03:11 +08:00
@xfund4 不想数据库查询的话,肯定要基于一个现有的 ID 来生成了。
1、基于数据库的自增 ID 来生成,就我#15 给你的办法,比如 1-5 位由自增 ID 转到 62 进制,不够 5 位就补 0,后面三位随机生成来避免猜测性。这样肯定不会重复的。
2、基于时间戳+用户 ID,也是将随机串的其中几位来保存时间戳和用户 ID。虽然无法避免统一秒同一用户发多个请求,但是后面还有随机串在,生成重复的概率可以忽略不计。另外时间戳没必要 1970 开始,就从 2018 开始就好了,这样时间戳会小很多。
SunnyMeow
2018-01-15 19:05:24 +08:00
kaneg
2018-01-15 19:08:04 +08:00
我的一个不成熟的想法:A-Z,0-9,共 36 位,每个 ID8 位,则共有 36^8 种可能,而你的需求只要千万数量级,那么可以把总的取值范围等分为千万块,每一块大概有上万个值。使用的时候先用你的自增 ID 取一个块,然后在这一块里随机取一个值。这样的结果是每个值都不会重复,每个值是万分之一的随机,所以被猜测的可能性也很小
xupefei
2018-01-15 19:14:29 +08:00
8 位千万数据量不算很大,直接 rand 然后查重就可以做到。
查重有很多办法可以用。不过上千万的数据,普通的哈希表已经慢到不行了。可以用 bloom filter 和各种 data sketch 算法。
toan
2018-01-15 19:16:09 +08:00
@xfund4 碰撞问题没有好的办法避免。
geelaw
2018-01-15 19:17:27 +08:00
用安全的随机置换即可。
owenliang
2018-01-15 19:35:40 +08:00
随机生成字节系列,转 16 进制,去重保存
renyijiu
2018-01-15 19:40:25 +08:00
时间戳加一定长度字符串
viko16
2018-01-15 19:49:45 +08:00
实际应用上还得考虑把 "iIl1" 这类不易辨识的字母组合移除..
innoink
2018-01-15 20:08:20 +08:00
既然已经知道总数,那么预先生成存起来,然后随用随取
innoink
2018-01-15 20:09:25 +08:00
检查的时候用 bloomfilter
qfdk
2018-01-15 20:35:32 +08:00
md5 (数据+ 随便)取指定长度
julyclyde
2018-01-15 20:36:29 +08:00
固定长度就不可能唯一啊

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

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

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

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

© 2021 V2EX