
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 时间戳已经不可重复了,用 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 14v45mJPBYJW8dT7 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 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 确实 有几层楼的回复是来搞笑的吗? |