有没有什么生成随机不重复的唯一 ID 且足够短的好办法?

2020-10-16 00:46:30 +08:00
 kaiki
B 站的 bv 号那种就感觉可以,但是太长,我想生成只有几位的数字+大小写字母组合的随机字符表作为 ID,但是怕万一随机出以前出过的 ID
9835 次点击
所在节点    问与答
67 条回复
0bit
2020-10-16 07:57:34 +08:00
用 uuid v4 生成,然后转成 short uuid
yuzo555
2020-10-16 08:06:32 +08:00
楼主要求短,那么 hash 算法肯定重复概率高。
又想要短,又想要无规律,只能用楼主自己在 #7 提出来的方案了。
black11black
2020-10-16 08:11:39 +08:00
@Perry 服了,大神当然都是不处理边际情况的,不用回了 block 了
cmdOptionKana
2020-10-16 08:22:00 +08:00
第一考虑总量。另一个思路是考虑频率,比如,如果生成 ID 的间隔必然超过一秒,那用 timestamp 转 64 进制,再加个两位随机字符就可以了。
cmdOptionKana
2020-10-16 08:24:47 +08:00
@black11black 这个 block 冤枉了,忽略小概率情况是很常见的做法,小规模系统连密码库的 nonce (要求唯一性) 都可以采用随机数。
Perry
2020-10-16 08:25:14 +08:00
@black11black 使用正确的情况下,大部分 hash 或者 GUID 的碰撞概率都是 astronomically low 的,如果你觉得这算是边际情况的话那你可以去处理。听到与自己观点不一样的声音就 block 对方这个行为有点巨婴了。
black11black
2020-10-16 08:27:42 +08:00
@cmdOptionKana 问题是你不做,真撞了怎么办呢,比如现在有个坏东西,故意给你传两份 md5 一样的 hexstring
workg
2020-10-16 09:47:21 +08:00
Date.now().toString(36) + Math.random().toString(36).slice(2) ?
cmdOptionKana
2020-10-16 10:04:15 +08:00
@workg 看情况,Date.now()精确到毫秒,如果一秒内并发生成很少 ID,则可以除以 1000 精确到秒,这样 ID 可以短些。另外 toString 最高只能转为 36 进制,如果用其他方法转为 64 进制,还可以再缩短 ID 长度。
Maboroshii
2020-10-16 10:19:23 +08:00
snowflake 转 base32
imdong
2020-10-16 10:19:32 +08:00
先给楼主分享自己有过的两个类似的经验吧:

15 年,公司接了一个电商买公交乘车码的东西,乘客手机购买后生成数字序列号给司机验证后可乘车。

由于需要手输,所以数字要短,当时做过一些研究,楼主可以参考一下结论(一定量情况下,直接随机数和瞎搞胡搞的看起来随机的没差):

![image.png]( https://i.loli.net/2020/10/16/7wYaKPWrDjBNgkt.png)

![image.png]( https://i.loli.net/2020/10/16/qFEaijgyPBhs7rD.png)

然后附上我前段时间搞得一个离线 CDK,里面又一些思路楼主可以参考:

顺序生成,但是通过在二进制上一定的变换,可以得到看似随机的结果,但和原值一一对应,不重复。

https://www.qs5.org/Post/680.html

( 15 年时我还很菜,别喷,虽然我现在依然菜,但谁喷我 ,我就画圈圈骂谁。)
mcluyu
2020-10-16 10:25:26 +08:00
uuidgen
threebr
2020-10-16 10:29:30 +08:00
感觉就是找一个有序数列到同样长度无序数列能够一一对应的函数,不行就像 19l 说的,预生成这样的对应列表
newtype0092
2020-10-16 10:33:12 +08:00
@black11black 你的每段代码都处理了因为 cpu 二极管电位异常导致计算结果不正确的异常了么?
没有的话请 block 我,这种边际情况都不处理你不配和我们讨论~
manhere
2020-10-16 10:51:32 +08:00
hashids
shuqin2333
2020-10-16 11:09:49 +08:00
short uuid
gamexg
2020-10-16 11:29:04 +08:00
https://hashids.org/
https://github.com/pjebs/optimus-go

都是直接对 id 进行可逆加密的办法。
另外也可以考虑直接用 aes 等方式加密。
cmdOptionKana
2020-10-16 11:29:45 +08:00
@imdong 随机唯一码,如果不是事先生成,一般思路都是 时间+设备码+随机数,传统的 UUID 与现在流行的 snowflake 都是这个思路。如果不加入一些环境常数(比如随时间而变化、随设备而变化、随地点变化),那肯定不管怎么折腾都只是一个随机数(随机数+随机数=随机数)。
cheng6563
2020-10-16 12:59:44 +08:00
全随机是真的会重的,一般要带上时间,但这样就长了。可以预先随机一些 ID 放池子里,用一个取一个,只是这样比较慢
imdong
2020-10-16 13:20:19 +08:00
@cmdOptionKana 这个不是真正的随机,是可以用于数据库自增字段,然后对自增字段进行一定的处理,使其变得看起来像是随机数一样(结果定长)。

而且连续两个数之间可能看不出规律(不知道处理方式的情况下)。

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

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

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

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

© 2021 V2EX