用来标记一个字符串, 可以忍受一定的碰撞概率
用来标记一个字符串, 可以忍受一定的碰撞概率
|
1
哈希值 截取部分 转回 long ?
|
|
2
ret: unsigned long long = 0
for c in s: ret = ret * 131 + (uint8)c; |
|
ipwxJun 30, 2020
3
这是当年我刷算法题,对付 char 字符串的手写哈希算法常用的方式。虽然不一定是最好的,但是胜在写起来快。如果是 unicode 你可以网上找找,131 替换成什么。(提示:一定要是素数)
|
|
4
@ThirdFlame 这个想法不错.. 截 15 位 这个概率应该挺低的
|
|
ipwxJun 30, 2020
5
@yanshenxian 这个想法一点都不好。。。。 前 15 位相同的字符串算出来的哈希值一模一样。。。。
|
|
6
@ipwx 这个碰撞概率怎么看? 是不是只要不溢出就不会碰撞 😂
|
|
7
@ipwx 这个应该可以先用 md5 哈希下, 然后截取 8-23 位的转成 long
|
|
8
@yanshenxian 溢出也没关系的。。。你乘以 256 溢出就消失了,但是乘以一个素数(比如 131 这个数字是传统,从 NOI 银牌选手那里继承来的习惯)信息是不会完全消失的。
|
|
ipwxJun 30, 2020
9
@yanshenxian MD5 当然可以,但是更慢。
|
|
10
MURMUR3
|
|
11
@qwerthhusn 这个如果生成 64 位以及以上的话,很容易得到一个负值. 不太好用作数据库主键
|
|
12
fnv1a ?这个是一个很成熟的字符串哈希算法,我记得输出是 32bit 的整数,好像也有 64bit 的变体
|
|
CEBBCATJun 30, 2020 via Android
13
问题发出 24 分钟后,楼主在第 11 个回复中指出是想用作数据库主键
--- 根据 XY 问题,反正我个人建议楼主开门见山地托出自己遇到的业务问题 |
|
chendyJun 30, 2020
14
原来楼主是要做数据库主键?
和内容相关的主键不合适吧 |
|
p2pCoderJun 30, 2020
15
64 位 一般都很难碰撞
机器学习 深度学习里面用的最多是 mumurhash3 存过线性模型,32 位,三千万的模型碰撞位七八万 64 位,75 亿的模型,碰撞为 0 |
|
16
@CEBBCAT append 了
|
|
17
@chendy 主要是想用 insert ignore 直接插入,不想先需要判断是否存在,再得到主键
|
|
18
@p2pCoder 嗯 64 位确实好。。
|
|
msg7086Jun 30, 2020
19
主键与业务无关。整个问题的大前提就错了……
|
|
exch4ngeJun 30, 2020
20
BLAKE2 算法,支持生成长度 1 ~ 64 字节的结果
|
|
21
@msg7086 是有这个顾虑,之所以这么做还是考虑实现的简易程度,而且这些数据都是一次写入,读>>>写, 感觉也还行
|
|
msg7086Jun 30, 2020
22
|
|
23
你就是要把字符串变成整数吧,试试 crc32 ?
|
|
liuhan907Jun 30, 2020 via Android
24
|
|
25
手机点快了,直接发出去了…试试 murmur3,自定义 seed,应该刚好解决
|
|
26
@ipwx 溢出取模是 114514 年前就退出历史舞台的做法,无论你的 base 是什么 https://codeforces.com/blog/entry/60442
|
|
ysc3839Jul 1, 2020
27
fnv hash?
|
|
28
邪道玩法:aes256 加密后取若干位(前若干位和中间若干位均可)转成 long 。
这种邪道玩法的随机性有论文证明过,懒得找了。 |
|
ipwxJul 1, 2020
29
@QingchuanZhang 嘛嘛,毕竟 OI 要扣时间常量的。一般 OI 的题目不会去针对 hash 函数做针对性的攻击,所以 * 31, *131 这种简单而且只是“可以构造出攻击的例子”的方法在刷题的时候很好用,毕竟简单的 hash 函数快嘛。所以这就看楼主了,如果楼主的场景不需要那么强的防御攻击性,而且被哈希的字符串真的很随机(比如是序列化以后的神经网络参数),我觉得快一点更重要。
|
|
QingchuanZhangJul 1, 2020 via Android
30
@ipwx 现在良心出题人默认卡自然溢出 hash 了,不卡说明不太负责
|
|
QingchuanZhangJul 1, 2020 via Android
31
@ipwx 再说一次“与底数无关,只要是溢出取模,任意底数都可被同一组数据 hack”
|
|
32
|
|
lovewellNov 19, 2020
33
标记,如果你是 java 的,使用 guava 吧。。
https://guava.dev/releases/29.0-jre/api/docs/com/google/common/hash/Hashing.html |