我一直在对 Mathematica 10.4 的 32 位和 64 位 Windows 版本进行一些逆向工程,这就是我发现的:
32 位
它使用Fowler–Noll–Vo hash function(FNV-1,之前有乘法),16777619 作为 FNV 素数,84696351 作为偏移基础。此函数应用于表达式数据地址的Murmur3-32 散列值(MMA 使用指针来保存每个数据的一个实例)。地址最终被解析为值 - 对于简单的机器整数,该值是立即的,对于其他人来说有点棘手。 Murmur3-32 实现函数实际上包含一个附加参数(默认为 4,特殊情况下的行为与 Wikipedia 中一样),它选择从输入中的表达式结构中选择多少位。由于普通表达式在内部表示为指针数组,因此可以通过重复将 4(字节 = 32 位)添加到表达式的基指针来获取第一个、第二个等。因此,将 8 传递给函数将给出第二个指针,12 将给出第三个,依此类推。由于内部结构(大整数、机器整数、机器实数、大实数等)具有不同的成员变量(例如,机器整数只有一个指向 int 的指针,一个复数的 2 个指向数字的指针等),对于每个表达式结构有一个“包装器”将其内部成员组合在一个 32 位散列中(基本上是 FNV-1 轮)。最简单的哈希表达式是一个整数。
murmur3_32() 函数的种子为 1131470165,n=0 和其他参数与维基百科中的一样。
所以我们有:
hash_of_number = 16777619 * (84696351 ^ murmur3_32( &number ))
用“^”表示异或。
我真的没有尝试过——指针是使用WINAPI EncodePointer() 编码的,所以它们不能在运行时被利用。 (可能值得在带有 EncodePonter 修改版本的 Wine 下的 Linux 中运行?)
64 位
它使用 FNV-1 64 位散列函数,0xAF63BD4C8601B7DF 作为偏移基础,0x100000001B3 作为 FNV 素数,以及 SIP64-24 散列(here 的参考代码)和前 64 位 0x0AE3F68FE7126BBF21F98EF7F39DE1 作为 k最后 64 位为 k1。该函数应用于表达式的基指针并在内部解析。与 32 位的 murmur3 一样,还有一个附加参数(默认为 8)来选择从输入表达式结构中选择多少个指针。对于每种表达式类型,都有一个包装器通过 FNV-1 64 位循环将结构成员压缩为单个哈希。
对于机器整数,我们有:
hash_number_64bit = 0x100000001B3 * (0xAF63BD4C8601B7DF ^ SIP64_24( &number ))
再一次,我并没有真正尝试过。有人可以试试吗?
不适合胆小的人
如果您查看他们的notes on internal implementation,他们会说“每个表达式都包含一种特殊形式的哈希码,用于模式匹配和评估。”
他们所指的哈希码是由这些函数生成的——在普通表达式包装函数的某个时刻,有一个赋值将计算出的哈希放入表达式结构本身。
了解他们如何将这些哈希用于模式匹配目的当然很酷。所以我尝试运行 bigInteger 包装器,看看会发生什么——这是最简单的复合表达式。
它开始检查返回 1 的东西——不知道是什么。
所以它执行
var1 = 16777619 * (67918732 ^ hashMachineInteger(1));
with hashMachineInteger() 就是我们之前所说的——包括值。
然后它从结构 (bignum_length) 中读取 bigInt 的字节长度并运行
result = 16777619 * (v10 ^ murmur3_32(v6, 4 * v4));
请注意,如果 4 * bignum_length 大于 8,则调用 murmur3_32()(可能与机器整数 $MaxMachineNumber 2^32^32 的最大值有关,并且与 bigInt 应该是什么相反)。
所以,最终的代码是
if (bignum_length > 8){
result = 16777619 * (16777619 * (67918732 ^ ( 16777619 * (84696351 ^ murmur3_32( 1, 4 )))) ^ murmur3_32( &bignum, 4 * bignum_length ));
}
我对这种结构的性质提出了一些假设。许多 XOR 的存在以及 16777619 + 67918732 = 84696351 的事实可能会让人们认为某种循环结构被用来检查模式 - 即减去偏移量并除以素数,或类似的东西。 Cassandra 软件使用 Murmur 哈希算法生成令牌 - 请参阅 these images 了解我对“循环结构”的含义。也许每个表达式都使用了各种素数 - 仍然必须检查。
希望对你有帮助