1
opengps 2020-12-18 08:17:53 +08:00
18 位重复的概率已经够低了,需要强制不重复,那就考虑下中间某几位加入毫秒级时间因素
|
2
CEBBCAT 2020-12-18 08:27:07 +08:00 via Android
递增…
|
3
loading 2020-12-18 08:30:55 +08:00 via Android
unix 时间戳改成 36 进制(字母+数字)然后再拼接一点随机
|
4
liuzhaowei55 2020-12-18 08:36:07 +08:00 via Android
产生速度?不快的话就存起来
|
5
netnr 2020-12-18 08:38:11 +08:00 via Android
c# 可以生成 GUID 再转 long 长度好像是 19 位,再截取处理一下
|
6
40EaE5uJO3Xt1VVa 2020-12-18 08:40:12 +08:00 2
时间戳已经不可重复了,用 md5 加密时间戳字符串。
字符串 1608251975 16 位 小写 b555936fee3a6904 16 位 大写 B555936FEE3A6904 32 位 小写 db59d207b555936fee3a6904d80629b4 32 位 大写 DB59D207B555936FEE3A6904D80629B4 |
7
stone000 OP 比如輸入 A 物品,得到一個唯一 18 位序列號 A18,下次再輸入 A 物品還是得到 A18
|
8
zachlhb 2020-12-18 08:53:12 +08:00 via Android
按一些规律编码再截取不就行了
|
9
bnlt 2020-12-18 08:54:10 +08:00
先用自增生成 0001 0002 这样的序列,然后用可逆对称加密算法对其加密,每次都会得到一个看似随机,而且不会重复的值。
类似功能我很早之前写过一个,用来在 PostgreSQL 里面实现类似题主的需求,数据库已经没了,代码有一份放在 runjs 上,今天想去看看,结果网站也已经关了…… 当时用的加密算法的名字忘了,但实现很简单,大概 10 行代码左右,秘钥长度和明文长度一样,照着维基百科上面对那个算法的说明写出来的,大致过程是循环替换。 有谁知道是什么加密算法吗,也帮我回忆回忆 |
10
jorneyr 2020-12-18 08:57:15 +08:00
计算的到 MD5 后,冲突时随机把中间得某 1 位,2 位,3 位的大小写变化一下,直到不冲突
|
11
TomVista 2020-12-18 08:57:27 +08:00
考虑线程安全吗?🐶
|
14
yogogo 2020-12-18 09:32:12 +08:00
我现在一个做法是先 md5(uniqid())获取一个随机串,然后再把随机串打乱获取 18 位。
|
15
rimutuyuan 2020-12-18 09:35:04 +08:00
时间戳 + 时间戳的 md5[:18]
每次生成前 sleep 1 nano second |
16
swithinzhang 2020-12-18 09:44:58 +08:00
@yogogo #14 这不是画蛇添足吗
|
17
no1xsyzy 2020-12-18 10:06:53 +08:00
产生重复用校验位处理?那还叫校验位吗?
#7 你 MD5 截前 18 位不就行了( 描述修改了你还是 append 吧 |
18
lwlizhe 2020-12-18 10:13:49 +08:00
抬个杠
md5 本身也是有冲突概率的;当然那概率小到只要不是特意针对,基本不会发生冲突的情况,所以放心大胆的把 md5 当作一般文件的校验指纹没啥问题; 但是因此 md5 的方式并不绝对完美,或者应该说有压缩的算法基本都会有冲突吧~~ |
19
ElmerZhang 2020-12-18 10:15:36 +08:00
两处 hash 方式各取一段拼成 18 位
|
20
lwlizhe 2020-12-18 10:18:44 +08:00
@lwlizhe 顺便附上 StackOverflow 上的回答,https://stackoverflow.com/questions/8852668/what-is-the-clash-rate-for-md5
|
21
Jooooooooo 2020-12-18 10:30:31 +08:00
拼一个时间戳
可以忽略重复的可能 |
22
bnlt 2020-12-18 10:34:31 +08:00 1
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 这样用数据序列自增产生的,返回值看上去就是随机数,但实际是加密算法算出来,由于加密算法可逆,所以保证了产生的值不会重复。 |
23
vus520 2020-12-18 10:40:32 +08:00
难道不可以套用雪花算法吗
|
24
4771314 2020-12-18 10:45:45 +08:00
uuid
|
25
touch 2020-12-18 10:51:00 +08:00
不是应该上雪花 id 算法,保证你不重复
|
26
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 就行了。 |
27
mxT52CRuqR6o5 2020-12-18 11:24:28 +08:00
用对称加密算法加密自增序列,秘钥不泄露就基本等于随机
|
28
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 轮可以实现强伪随机 |
29
lululau 2020-12-18 11:38:52 +08:00
雪花算法正解,重不重复要看生成频率
|
30
bnlt 2020-12-18 11:55:27 +08:00
雪花算法和 UUID 主要目的是让 ID 在服务器之间也不重复,但是看上去并没有那么随机,人类能从中找出一些规律知道 ID 之间的关系,比如雪花算法前面部分会暴露出两个 ID 之间的先后顺序关系。当然 UUID 也有 UUID v4 整串都是随机生成的,不会被看出规律
|
31
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 |
32
julyclyde 2020-12-18 15:39:56 +08:00
只要长度有限,最后必然会重复
|
33
Greatshu 2020-12-18 15:51:53 +08:00
|
34
br00k 2020-12-18 18:09:13 +08:00
把 12byte 的 MongoDB ObjectId 转成 base64,只有 16 位长度。
|
35
siyemiaokube 2020-12-18 21:52:24 +08:00 via iPhone
这 tm 的……这届 v 站水平真菜……
以后尽可能不和数学不好的人共事…… |
36
Ptu2sha 2020-12-18 21:58:01 +08:00
确实 有几层楼的回复是来搞笑的吗?
|