https://hashids.org/ Hashids is a small open-source library that generates short, unique, non-sequential ids from numbers.
It converts numbers like 347 into strings like “ yr8 ”, or array of numbers like [27, 986] into “ 3kTMd ”.
You can also decode those ids back. This is useful in bundling several parameters into one or simply using them as short UIDs.
比如字符串长度设置 4-6 位,等用户量大了接近 4-6 位字符能表示的用户量时, 会不会出现重复的。
1
luosuosile 2018-12-19 11:58:41 +08:00 1
我也遇到这个问题了,,帮顶吧。。本来我都打算用 uuid 了,顺带一提网上搜到的 short uuid 不太靠谱,评论都说几万条就重复了。
|
2
kkk212 OP @luosuosile 我目前用的方案是,单独建一个表添加唯一索引,随机生成 6 位的字符串,然后插入千万条记录。这样是能保证重复问题,但是用的时候增加了一条 sql 查询。hashids 优点是能直接加密反转,不过还不太敢用。
|
3
binux 2018-12-19 12:13:36 +08:00
Do you have a question or comment that involves "security" and "hashids" in the same sentence? Don't use Hashids. Here are some ways to decode:
https://hashids.org/#decoding 前面有个帖子我就说了,找个加密算法(比如 AES )算一下就行了。 |
5
jedrek 2018-12-19 12:31:48 +08:00
hashids 不是用来加密的, 这东西和 base64 是一样的东西, 区别是 hashids 可以加个盐再编码
|
8
kkk212 OP @binux 主要看到一些网站,用户主页的 id 有用用户昵称的,有用字符串的( 6 位左右)。用字符串的话,比如用 MD5 就行,但是 16 位或 32 位太长了不好看。开始没看 hashids 原理, 感觉 hashids 可以,有点缺点就是不定长和能看出来原数字的大小。谢谢,我一会再看看 aes
|
9
kkk212 OP 嗯,看了 hashids 原理明白了。但是为什么说不是用来加密的,加了盐值就和 base64 只是编码转换不一样了
|
10
kkk212 OP @jedrek 嗯,看了 hashids 原理明白了。但是为什么说不是用来加密的,加了盐值就和 base64 只是编码转换不一样了
|
11
xenme 2018-12-19 13:22:41 +08:00 via iPhone
看你要求多安全,一般安全性自己撸一个 base64 的变种,基本没人看得出来,也是最简单的加密。不要说 base64 不是加密,只是大家都知道加解密方式而已。
|
12
leonard916 2018-12-19 13:25:02 +08:00
@xenme 確實不是加密 只是把 byte[]變成字符串而已
|
13
xenme 2018-12-19 13:33:26 +08:00
有哪种加密不是把 byte[]或者 string[]变成另外一串 byte[]或者 string[]么?
只是变换的方式(加密算法)不同罢了。 只是说现在 base64 类型的加密实在没有安全性,而且更多被人用来当做一种编码方式而已。 |
14
jedrek 2018-12-19 13:51:33 +08:00
@kkk212 加了盐值是跟默认编码后结果不一样, 有了个“定制化”的编码结果. 但是编码算法是一样的.
并不是说 hashids 完全不行, 还是取决你的用途, 如果想把一长串数字缩得很短, 直观上看不出来, hashids 是个很好的方案; 但若为了不让客户端知道解码后的值, 就不应该这么做, 因为很容易就能破解, 应该考虑对称加密的算法. |
15
jedrek 2018-12-19 13:54:46 +08:00
@kkk212 加了盐值是跟默认编码后结果不一样, 有了个“定制化”的编码结果. 但是编码算法是一样的.
并不是说 hashids 完全不行, 还是取决你的用途, 如果想把一长串数字缩得很短, 直观上看不出来, hashids 是个很好的方案; 但若为了不让客户端知道解码前(此处修正)的值, 就不应该这么做, 因为很容易就能破解, 应该考虑对称加密的算法. |
16
woodensail 2018-12-19 13:58:02 +08:00
@xenme 现代密码学中,安全性不来自于算法的保密而来自于密钥的保密。所以 base64 和各种不引入外部密钥的数据编码方案都不能称之为加密。
|
17
xenme 2018-12-19 14:14:45 +08:00
@woodensail 针对楼主的需求来说,算法和密钥都是不需要公开的,安全性要求不是特别高的情况下,类似 base64/hashid 这种“加密”足够满足需求了。
|
19
woodensail 2018-12-19 14:29:31 +08:00
@xenme 同楼上,不要把希望寄托在别人不会拆包上,搞黑产的有这个耐心。
|
21
xenme 2018-12-19 14:30:54 +08:00
个人以为加盐后,hashid 足够满足你要求了。
默认 hashid 基本是 base62,6 位的话,最多可以表示 56800235584,超过 500 亿,你用户量也不可能更多了。 |
22
xenme 2018-12-19 14:39:58 +08:00
@woodensail 前面也说了,安全性要求并不是特别高的话,可以考虑 hashid,毕竟即使黑进后台了,也就知道个用户量而已或者用户真正的 ID,并不能怎么样。而且,即使用更安全的算法,能进来看到算法和 salt 的人,估计你的安全算法的密钥也暴露了。
@kkk212 这个 id 的 hash 应该是你在用户注册之后,在后台生成后返回给前台用来代替 user id 的。所以,对应的算法以及 salt 是只有后台人员才知道的。你并不需要在前台编解码,所以并没有暴露出来。 |
23
kkk212 OP @jedrek 就是用一个短的字符串代替用户 id 来显示, 不能解密也不会暴露真实的 id。目前用的方案是,生成好一个存储 6 位字符串记录的表(插入 2000 万记录), 创建新用户的时候查出来对应 id 的字符串,存到用户表里。但是用户多了,存储字符串的表查询就会慢了,并且这样得定期维护字符串表,感觉费事。
|
27
lawler 2018-12-19 16:32:30 +08:00
用户 ID + 任意固定整数 -> 转 32 进制。
例如 用户 id 1 固定整数 987412312 10 进制值是 987412313 显示 id 是 tdldqp 不定期更新任意固定整数。 |
28
chinvo 2018-12-19 16:36:19 +08:00 via iPhone
@lawler #27 为了避免重复,你只能增大这个参数而不能减小,而且还需要一个专门的字段保存过去的 ID 对应的字符串
|
29
lawler 2018-12-19 16:38:45 +08:00
@chinvo 不需要啊。出站入站时反转 userid,换句话说,明天别人拿这个 id 访问这个页面的时候,就是别人的数据了。这个值不入库的。参数只要不是负值,任意值都没问题。
|
30
zhengxiaowai 2018-12-19 16:42:07 +08:00
|
32
chinvo 2018-12-19 16:45:25 +08:00 via iPhone
我厂用 ksuid
|
34
arthasgxy 2018-12-19 16:58:30 +08:00
好奇请教一下楼上各位,我司有类似的,只不过是纯数字,不知道是不是与你们同样的目的。
每个用户,3、4 个 xxid,都是纯数字,有的长,有的短,一直不知道搞这么多有什么特别的意义? |
37
chinvo 2018-12-19 17:07:35 +08:00 via iPhone
@kkk212 #33 snowflake 呢?或者自己实现类 ksuid,把 payload 从 128bit 减到 64bit
|
39
agdhole 2018-12-20 02:04:55 +08:00
转成 int 32/64? steam 是这么做的,不过很长
|