h ^= h >> 16; h *= 0x85ebca6b; // 2,246,822,507 h ^= h >> 13; h *= 0xc2b2ae35; // 3,266,489,909 h ^= h >> 16;
时间: 2024-04-23 07:26:19 浏览: 10
这段代码是对哈希值进行加强雪崩测试的过程。具体来说,它包括以下步骤:
1. `h ^= h >> 16`:将哈希值右移 16 位后,与原哈希值进行异或运算,这样可以将哈希值的高 16 位和低 16 位进行混合,增强哈希值的随机性和复杂性。
2. `h *= 0x85ebca6b`:将哈希值乘以一个常数,这个常数是一个大质数(2,246,822,507),可以保证哈希值的范围更广,增强哈希值的随机性和复杂性。
3. `h ^= h >> 13`:将哈希值右移 13 位后,与原哈希值进行异或运算,这样可以将哈希值的高 13 位和低 19 位进行混合,增强哈希值的随机性和复杂性。
4. `h *= 0xc2b2ae35`:将哈希值再次乘以一个常数,这个常数也是一个大质数(3,266,489,909),可以进一步增强哈希值的随机性和复杂性。
5. `h ^= h >> 16`:将哈希值右移 16 位后,与原哈希值进行异或运算,这样可以将哈希值的高 16 位和低 16 位进行混合,最终得到最终的哈希值。
通过这些加强雪崩测试的步骤,可以有效地提高哈希函数的安全性和可靠性,避免哈希碰撞和哈希冲突等问题。
相关问题
代码块2:unsigned int Murmurhash3(string input_data,unsigned int seed){ unsigned int h = seed; //声明常量 const unsigned int c1 = 0xcc9e2d51; // 3,432,918,353 const unsigned int c2 = 0x1b873593; // 461,845,907 const int r1 = 15; const int r2 = 13; const int m = 5; const int n = 0xe6546b64; //3,864,292,196 //分块处理 int blkNums = input_data.size()/4; //1.一个块一个块地处理,这是第一部分地工作 for(int i=0;i<blkNums;i++){ unsigned int K = getBlkno(input_data,i); K *= c1; K = _rotl(K,r1); K *= c2; K = _rotl(K,r2); h = h*m + n; } //2.处理剩余量 string remaining_bytes = input_data.substr(blkNums*4); unsigned int k = 0; switch (remaining_bytes.size()){ case 3:k^=remaining_bytes[2]<<16; case 2:k^=remaining_bytes[1]<<8; case 1:k^=remaining_bytes[0]; } k = k * c1; k = _rotl(k,r1); k = k * c2; h ^= k; h ^= input_data.size(); //3.加强雪崩测试 h ^= h >> 16; h *= 0x85ebca6b; // 2,246,822,507 h ^= h >> 13; h *= 0xc2b2ae35; // 3,266,489,909 h ^= h >> 16; return h; }
这段代码是一个实现MurmurHash3算法的函数,用于计算字符串的哈希值,并返回一个32位无符号整数。
MurmurHash3算法是一种非加密型哈希算法,具有高效、快速、分布均匀等特点。该算法将输入的字符串分成多个块进行处理,其中每个块都被视为一个32位无符号整数。通过对所有块进行一系列位运算和移位操作,最终得到一个32位的哈希值。
函数的输入参数包括一个字符串input_data和一个种子值seed。其中,input_data是要计算哈希值的字符串,seed是用于初始化哈希值的种子值。
函数首先将seed赋值给变量h,作为哈希值的初始值。然后,声明一些常量和变量,用于在后续的计算中使用。
接着,函数将input_data分成若干个4字节的块,对每个块进行一系列的位运算和移位操作,最终得到一个中间的哈希值。具体地,函数分为以下三个步骤:
1. 分块处理
函数首先计算input_data中包含的块数blkNums,然后对每个块进行处理。具体地,对于第i个块,函数调用getBlkno(input_data,i)函数获取该块对应的32位无符号整数K,然后对K进行一系列的位运算和移位操作,最终得到一个中间值,并将该中间值与h进行合并,得到新的哈希值。
2. 处理剩余量
如果input_data的长度不是块大小(即4的倍数),则会存在一些剩余的字符,需要单独处理。函数首先将剩余的字符存储到变量remaining_bytes中,然后根据remaining_bytes的长度,将其转换为一个32位的无符号整数k。对k进行一系列的位运算和移位操作,最终得到一个中间值,并将该中间值与h进行合并,得到新的哈希值。
3. 加强雪崩测试
最后,函数对哈希值进行一系列的加强雪崩测试,以增加哈希值的随机性和分布均匀性。具体地,函数将哈希值h右移16位,然后与h进行异或操作,再将结果乘以常量0x85ebca6b,再右移13位,再与h进行异或操作,最后将结果乘以常量0xc2b2ae35,并将最终结果返回。
总体来说,这段代码实现了MurmurHash3算法的核心部分,通过对字符串的分块处理和位运算操作,计算出了一个32位无符号整数的哈希值。
#include<bits/stdc++.h> using namespace std; unsigned int getBlkno(string &input_data,int idx){ string s = input_data.substr(idx*4,4); unsigned int res = 0; for(int i=0;i<4;i++){ res += s[i]<<(24-i*8); } return res; } unsigned int Murmurhash3(string input_data,unsigned int seed){ unsigned int h = seed; //声明常量 const unsigned int c1 = 0xcc9e2d51; // 3,432,918,353 const unsigned int c2 = 0x1b873593; // 461,845,907 const int r1 = 15; const int r2 = 13; const int m = 5; const int n = 0xe6546b64; //3,864,292,196 //分块处理 int blkNums = input_data.size()/4; //1.一个块一个块地处理,这是第一部分地工作 for(int i=0;i<blkNums;i++){ unsigned int K = getBlkno(input_data,i); K *= c1; K = _rotl(K,r1); K *= c2; K = _rotl(K,r2); h = h*m + n; } //2.处理剩余量 string remaining_bytes = input_data.substr(blkNums*4); unsigned int k = 0; switch (remaining_bytes.size()){ case 3:k^=remaining_bytes[2]<<16; case 2:k^=remaining_bytes[1]<<8; case 1:k^=remaining_bytes[0]; } k = k * c1; k = _rotl(k,r1); k = k * c2; h ^= k; h ^= input_data.size(); //3.加强雪崩测试 h ^= h >> 16; h *= 0x85ebca6b; // 2,246,822,507 h ^= h >> 13; h *= 0xc2b2ae35; // 3,266,489,909 h ^= h >> 16; return h; } int main(){ string input_data = "Jack"; int seed = 123; cout<<"Murmurhash3(Jack,123) = "<<Murmurhash3(input_data,seed); system("pause"); }
这段代码中有一些问题,需要进行修改:
1. 代码开头应该包含头文件 `#include<iostream>`,否则无法使用 `cout` 和 `system` 函数。
2. 在 `getBlkno` 函数中,需要将 `s[i]` 强制转换为 `unsigned int` 类型,否则会出现类型不匹配的错误。
3. 在 `Murmurhash3` 函数中,需要将 `h` 和 `K` 声明为 `unsigned int` 类型,否则会出现类型不匹配的错误。
4. 在 `Murmurhash3` 函数中,需要将 `_rotl` 函数改为 `_rotr` 函数,否则会出现未定义的错误。
5. 在 `Murmurhash3` 函数中,需要将 `h ^= h >> 16` 改为 `h ^= h >> 13`,否则会出现错误的哈希值。
修改后的代码如下: