平时都是使用 md5 做哈希,但是有时候感觉 32 位太长了,有点浪费,想问下大家除了 md5 ,还有没有其他优秀的哈希算法?比较短的
1
mengzhuo 2022-08-15 18:06:44 +08:00
fnv
|
2
InDom 2022-08-15 18:06:58 +08:00 6
substr(md5(""), 8, 16);
|
3
mengzhuo 2022-08-15 18:09:01 +08:00
ps md5 是 128 位的
|
4
lululau 2022-08-15 18:10:08 +08:00 1
%2
|
5
seki 2022-08-15 18:10:55 +08:00
crc32 ?
越短越容易碰撞 |
9
murmur 2022-08-15 18:16:21 +08:00
crc32 ,我们是做 url 二级索引的,url 多了一级索引查的很郁闷,所以先 hash 一次然后二次查询
|
10
ysc3839 2022-08-15 18:19:28 +08:00
CRC32 FNV1a-32 CityHash32 等,一般一些简单用途我会选 FNV1a-32 ,因为它非常简单。
|
11
ysc3839 2022-08-15 18:25:19 +08:00
再补充一个 MurmurHash
|
12
Bromine0x23 2022-08-15 18:38:36 +08:00
看起来不需要防碰撞,那就 CRC
或者 https://en.wikipedia.org/wiki/List_of_hash_functions 里面挑一个 |
13
AX5N 2022-08-15 18:53:07 +08:00
CRC3 CRC4 CRC8 CRC16 CRC32 CRC64
|
14
lmshl 2022-08-15 18:56:24 +08:00
substr 解君忧
|
15
zengxs 2022-08-15 19:06:40 +08:00
md5 默认是 hex 格式输出,你可以输出成 base64 ,这样去掉占位的 = 号,就只有 22 位字符了
|
16
hgc81538 2022-08-15 19:16:54 +08:00
續 15 樓
md5 編碼成 base94 ? |
17
hsfzxjy 2022-08-15 21:13:09 +08:00 via Android
xxhash 家族
|
18
raaaaaar 2022-08-15 21:17:27 +08:00
直接所有 ascill 相加成 16 进制😁
|
19
mitu9527 2022-08-15 21:19:09 +08:00
防碰撞哈希算法就没短的,感觉你要的是快速哈希算法,比如 Murmur 或者 CRC ,快且短,但是容易发生冲突。
|
20
tool2d 2022-08-15 21:44:01 +08:00
把 MD5 断尾没问题,你可以自己做碰撞概率测试,每个 bit 概率是一样的。
|
21
changnet 2022-08-15 21:58:15 +08:00
非标准 base64 算法。把数字,小写字母,大写字母和一些特殊字符都用上,变成 N 进制,重新再编码这样就短了。一个 uuid 都可以编码到 22 个字符以下,只是字符看你能不能接受
|
22
Juszoe 2022-08-15 22:15:51 +08:00
哈希截断挺常见的,很多标准库都会有这种操作
|
23
missdeer 2022-08-15 22:19:17 +08:00 via Android
md2 ,md4
|
24
etnperlong 2022-08-15 22:21:51 +08:00
可以试试 blake2/3 ?
https://www.blake2.net/ |
25
felixlong 2022-08-15 22:22:11 +08:00
SipHash 不是专门设计来解决你这个问题的嘛?
|
26
kenvix 2022-08-15 22:22:44 +08:00
CRC32 ,短到你用一个 int 就能存
|
27
CRVV 2022-08-16 02:07:01 +08:00
https://security.stackexchange.com/a/72685
直接截前面一段就行,要多长截多长 但是 md5 本来就是比较差的算法,再截一下就更差了,如果需要防碰撞就换个 sha256 之类的吧 |
28
bl4ckoooooH4t 2022-08-16 08:48:17 +08:00
jhash 算法。 计算字符串的哈希,得到 4 字节哈希值。https://github.com/ysmood/jhash
|
29
bigtear 2022-08-16 08:51:34 +08:00
wyhash ,输出字符串长度 16 位,而且是目前最快且安全的算法
|
30
bigtear 2022-08-16 08:54:55 +08:00
而且 [wyhash is the default hashing algorithm of the great great Zig, V, Nim and Go (since 1.17) language]( https://github.com/wangyi-fudan/wyhash)
|
31
newmlp 2022-08-16 12:40:30 +08:00
xxhash
|
32
mutalisk 2022-08-16 14:36:19 +08:00
cityhash murmurhash
|
33
msg7086 2022-08-16 15:27:21 +08:00
xxhash 挺好的,非密码安全的哈希,速度也快。
|
34
t6attack 2022-08-17 04:16:40 +08:00
md5 这类散列算法,得到的字符串,其实是 16 进制数据的字符串表达。这个字符串直接占用 32 个字节,但是用来表达数据的字符却仅限 0~f 。
如果数据量放大到亿级,这种空间浪费就很巨大了。 如果允许以二进制方式存储数据,那么最简单粗暴的方式,是直接把散列字串当 hex 压入二进制数据。 比如这个 md5:a6307d508e9020d93273a7c086d9735f 字符串方式直接存储: 肉眼观察:a6307d508e9020d93273a7c086d9735f 实际存储:61 36 33 30 37 64 35 30 38 65 39 30 32 30 64 39 33 32 37 33 61 37 63 30 38 36 64 39 37 33 35 66 占用空间:32 字节 二进制方式存储: 肉眼观察:(乱码) 实际存储:a6 30 7d 50 8e 90 20 d9 32 73 a7 c0 86 d9 73 5f 占用空间:16 字节 ↑↑实际存储与 md5 一致 其他思路: 以字符串模式存储数据的情况下,让更多字符参与表达数据,提升空间利用率,缩短数据长度. 压入二进制以后再 base64 一下: 肉眼观察:pjB9UI6QINkyc6fAhtlzXw== 实际存储:70 6A 42 39 55 49 36 51 49 4E 6B 79 63 36 66 41 68 74 6C 7A 58 77 3D 3D 占用空间:24 字节 将 16 进制转换为 36 进制: 肉眼观察:2izcpdgz4p6o8rmbxptszbuqn 实际存储:32 69 7A 63 70 64 67 7A 34 70 36 6F 38 72 6D 62 78 70 74 73 7A 62 75 71 6E 占用空间:25 字节 |