[求助] 怎么随机产生不重复的 18 位序列类似 MD5

2020-12-18 08:15:43 +08:00
 stone000
怎么随机产生不重复的 18 位序列类似 MD5 这种,或者随机生成 17 位+1 位校验位
如果产生重复的就通过校验位来处理
5474 次点击
所在节点    程序员
36 条回复
Jooooooooo
2020-12-18 10:30:31 +08:00
拼一个时间戳

可以忽略重复的可能
bnlt
2020-12-18 10:34:31 +08:00
CREATE OR REPLACE FUNCTION public.hexid(p integer)
RETURNS text
LANGUAGE plcoffee
AS $function$
b = 15

f = (r, k) ->
((r * k) + 51735) & ((1 << b) - 1)

fc = (n, ks) ->
l = n >> b
r = n & ((1 << b) - 1)

for k in ks
t = l
l = r
r = t ^ f(r, k)

(l << b) + r

r = fc(p, [24358, 25934, 52897, 8057])

return ('00000000' + r.toString(16)).slice(-8)
$function$

我找回代码了,但还是不知道里面的算法是什么🥺
入参是 1 2 3 4 这样用数据序列自增产生的,返回值看上去就是随机数,但实际是加密算法算出来,由于加密算法可逆,所以保证了产生的值不会重复。
vus520
2020-12-18 10:40:32 +08:00
难道不可以套用雪花算法吗
4771314
2020-12-18 10:45:45 +08:00
uuid
touch
2020-12-18 10:51:00 +08:00
不是应该上雪花 id 算法,保证你不重复
laminux29
2020-12-18 10:52:50 +08:00
我把 18 位,理解为由 18 个[a-z0-9]组成的字符。因为如果 18 位指的是 2^18,那就啥都别做了。

18 个由[a-z0-9]组成的字符,那就是 36^18,大约 2^93 次方。

两种方法:

第一种方法,限制没毫秒内调用次数,直接借用 Twitter 的开源分布式 ID 生成算法:snowflake 。
41bit 时间戳;

12bit 的毫秒内序列号(每毫秒最多调用 4096 次,如果需要更多次数,可以放大这部分的长度);

以上这两者,在每秒最多 4096 次调用内,保障了全局唯一。那么剩下 40bit 你自己随便找个快速 hash 算法,然后截取前面 40bit 就行了。


第二种方法,不限制每秒最多调用次数,但限制总长度。

x Bit,从 1 开始的自增 ID,x 为 2^x 的长度,由自增 + 放号业务来保障全局唯一。

剩下 93-x,随便找个快速 hash 算法,然后截取最前面的 93-xbit 就行了。
mxT52CRuqR6o5
2020-12-18 11:24:28 +08:00
用对称加密算法加密自增序列,秘钥不泄露就基本等于随机
bnlt
2020-12-18 11:33:32 +08:00
找到我用的算法的名字了:费斯妥密码
https://zh.wikipedia.org/wiki/%E8%B4%B9%E6%96%AF%E5%A6%A5%E5%AF%86%E7%A0%81
这个算法没有限制加密块的长度,所以你可以产生任意位数的结果,算法可逆保证不会重复,不需要补随机数或截取(随机数和截取理论上还是会导致重复),复合一定条件时,超过 4 轮可以实现强伪随机
lululau
2020-12-18 11:38:52 +08:00
雪花算法正解,重不重复要看生成频率
bnlt
2020-12-18 11:55:27 +08:00
雪花算法和 UUID 主要目的是让 ID 在服务器之间也不重复,但是看上去并没有那么随机,人类能从中找出一些规律知道 ID 之间的关系,比如雪花算法前面部分会暴露出两个 ID 之间的先后顺序关系。当然 UUID 也有 UUID v4 整串都是随机生成的,不会被看出规律
xiaomimix5
2020-12-18 14:15:23 +08:00
# Nano ID
A tiny, secure, URL-friendly, unique string ID generator for JavaScript.
https://github.com/ai/nanoid#readme
julyclyde
2020-12-18 15:39:56 +08:00
只要长度有限,最后必然会重复
Greatshu
2020-12-18 15:51:53 +08:00
br00k
2020-12-18 18:09:13 +08:00
把 12byte 的 MongoDB ObjectId 转成 base64,只有 16 位长度。
siyemiaokube
2020-12-18 21:52:24 +08:00
这 tm 的……这届 v 站水平真菜……

以后尽可能不和数学不好的人共事……
Ptu2sha
2020-12-18 21:58:01 +08:00
确实 有几层楼的回复是来搞笑的吗?

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

https://tanronggui.xyz/t/736606

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

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

© 2021 V2EX