3 个版本
使用旧的 Rust 2015
0.1.3 | 2018 年 7 月 2 日 |
---|---|
0.1.2 | 2018 年 7 月 2 日 |
0.1.0 | 2018 年 7 月 2 日 |
#1898 in Rust 模式
609 个月下载量
39KB
293 行
djb_hash
Rust 中的常用 Daniel J. Bernstein 风格哈希函数库。
lib.rs
:
本库收集了基于 Daniel J. Bernstein 设计的简单且快速的哈希函数。由于这些哈希函数非常简单,因此它们具有一些已知的限制,如果用于 HashMap 中的键哈希等,应极其小心地使用。大多数函数都容易受到键冲突的影响,这可能导致如果暴露给外部恶意行为者时发生 DOS 攻击。
尽管如此,许多其他语言,如 Java、JS、Python 和 PHP,都有它们内部的版本,并且认为在处理这些情况的可互操作代码时,Rust 也应该有可用的哈希函数。
理解哈希名称
哈希名称基于创建哈希所使用的数学函数。以下以 "X33a" 为例进行说明: "X##" 是乘法阶段,因此在将下一个要哈希的数据字节附加到现有哈希值之前,现有哈希值将乘以给定的数字,在本例中为 33。这个数字始终是质数,为了使计算尽可能快,只使用二进制倍数 + 或 - 一的质数。原因是实际乘法很慢,但位移(在二进制中相当于乘法)以及加法或减法要快得多。对于 33,它被转换为 5 的移位(乘以 32),然后将其添加到原始数字中,等于最终的 33。
接下来是 "a" 部分。"a" 代表 "add"。在上面的计算完成后,将下一个要哈希的字节添加到运行哈希总和中,以形成新的哈希总和中。一些哈希函数而不是添加使用 XOR(按位异或),在示例中 "a" 的位置会有 "x"。使用 XOR 通常会更好地将新字节的效应分布到更多的哈希位上,但在使用单字节进行更长的哈希时,其效果不太明显。
最后,可能有一个或多个“Xxx”后缀。后缀“U32”表示内部使用32位无符号整数哈希总和,而不是常规的64位。通常,即使在64位平台上,32位操作也可以更快,并且可能更适合某些应用。Rust默认情况下,总是从其finish()函数返回64位哈希,但由于通常只需要32位哈希,我添加了32位版本。为了在只需要32位时避免将数据转换为64位然后再转换回32位,可以使用finish_u32()函数代替常规的finish()函数,所有32位哈希版本都可以使用。
后缀的最后一个“Xxx”部分表示一些附加操作或其他特殊化,就像在某些应用中做的那样。一个很好的例子是PHP,其中高位始终设置为1,因为它们使用零哈希值来检测内部未设置的哈希。