C# 将部分MD5哈希代码转换为长
我正在使用MD5算法对磁盘哈希表的键进行散列(我知道这是否是用于此目的的最佳算法值得怀疑,但我现在就使用它。这个问题可以推广到任何生成字节数组的算法)。我的问题是: 哈希代码的大小决定了哈希表中的组合(桶)数量。因为MD5是128位的,所以有大量的组合(~3.4e38),这对于我来说太大了。所以我想做的是从MD5生成的字节数组中提取前n位,并将它们转换成一个长(或ulong)值。由于MD5生成一个字节数组,如果我想要整数个字节,这将很容易做到,但这会导致组合数量的大幅增加。我发现单比特版本要复杂得多 目标:C# 将部分MD5哈希代码转换为长,c#,arrays,hash,byte,md5,C#,Arrays,Hash,Byte,Md5,我正在使用MD5算法对磁盘哈希表的键进行散列(我知道这是否是用于此目的的最佳算法值得怀疑,但我现在就使用它。这个问题可以推广到任何生成字节数组的算法)。我的问题是: 哈希代码的大小决定了哈希表中的组合(桶)数量。因为MD5是128位的,所以有大量的组合(~3.4e38),这对于我来说太大了。所以我想做的是从MD5生成的字节数组中提取前n位,并将它们转换成一个长(或ulong)值。由于MD5生成一个字节数组,如果我想要整数个字节,这将很容易做到,但这会导致组合数量的大幅增加。我发现单比特版本要复杂
n = 10 // I.e. I want 2^10 combinations
long pos = someFcn(byte[] key, n)
其中key是被散列的值,n是我想要使用的MD5结果的位数。那么,Pos将是0到1023之间的整数(在n=10的情况下)。如果n=11,代码将从0到2^11-1=2027,等等。必须稍微快速/高效
看起来没那么难,但我还是逃避不了。任何帮助都将不胜感激。谢谢 获取前10位,例如:
int result = ((int)key[0] << 2) | (((int)key[1] >> 6) & 0x03)
int结果=((int)键[0]>6)和0x03)
获取前10位,例如:
int result = ((int)key[0] << 2) | (((int)key[1] >> 6) & 0x03)
int结果=((int)键[0]>6)和0x03)
首先,将前四个字节转换为整数,使用。不管怎样,它都会得到四个字节,但这可能不会使它的速度明显变慢,因为在剩下的计算中,您使用的是32位寄存器,而复杂的东西,如“如果小于16,那么使用前两个字节执行此操作”只会使它变得更复杂
然后,给定该整数,取最低的N位。如果您确实希望编译时不知道特定位数[两个存储桶的幂]的话,
~(-1)首先,将前四个字节转换成一个整数,使用。不管怎样,它都会得到四个字节,但这可能不会使它变得更慢,因为在剩下的计算中,您使用的是32位寄存器,以及复杂的东西,如“如果小于16,则对前两个字节执行此操作”只会让事情变得更复杂
然后,给定该整数,取最小的N位。如果您确实想要编译时未知的特定位数[两个桶数的幂],如果您有这样一个数组
unsigned char data[2000];
然后,您可以将前n位刮除为一个整数,如下所示:
typedef unsigned long long int MyInt;
MyInt scrape(size_t n, unsigned char * data)
{
MyInt result = 0;
size_t b;
for (b = 0; b < n / 8; ++b)
{
result <<= 8;
result += data[b];
}
const size_t remaining_bits = n % 8;
result <<= remaining_bits;
result += (data[b] >> (8 - remaining_bits));
return result;
}
typedef无符号长整型MyInt;
MyInt刮取(大小,无符号字符*数据)
{
MyInt结果=0;
尺寸b;
对于(b=0;b 结果如果你有这样一个数组
unsigned char data[2000];
然后,您可以将前n位刮除为一个整数,如下所示:
typedef unsigned long long int MyInt;
MyInt scrape(size_t n, unsigned char * data)
{
MyInt result = 0;
size_t b;
for (b = 0; b < n / 8; ++b)
{
result <<= 8;
result += data[b];
}
const size_t remaining_bits = n % 8;
result <<= remaining_bits;
result += (data[b] >> (8 - remaining_bits));
return result;
}
typedef无符号长整型MyInt;
MyInt刮取(大小,无符号字符*数据)
{
MyInt结果=0;
尺寸b;
对于(b=0;b 结果你需要一些位移位。我不知道C#语法,但是。你需要一些位移位。但是我不知道C#语法。有符号整数上的右移位定义得好吗?它不在C中,但我不知道C#。是的,它定义得好。新的位与符号位相同。有符号整数上的右移位定义得好吗?没有在C中,但我不知道C#。是的,它定义得很好。新的位与符号位相同。非常好。谢谢,Random832等。将使用非常简单的东西,如:UInt64 pos=42;UInt64 mask=~(-1)如果你对数字进行硬编码,我建议只硬编码15或0xF,“技巧”是针对N是可变的情况。非常好。谢谢,Random832等。将使用非常简单的方法,如:UInt64 pos=42;UInt64 mask=~(-1)如果你要硬编码这个数字,我建议你只硬编码15或0xF,这个“技巧”是指如果N是可变的。