【问题标题】:Convert MD5 to Long将 MD5 转换为长
【发布时间】:2012-03-28 12:11:06
【问题描述】:

我有一个来自 MD5 JAVA 方法的 16 字节数组。 我想将其转换为 long 以用作哈希键。 正在读取按位 XOR 到 64 的位是一个好主意......那么如何从中获得长? XOR 和 cvt 的完整代码示例请长。

【问题讨论】:

  • 如果您采用 XOR 路线,您只需将一半字节与另一半字节进行异或,因为 long 是 64 位,是长度为 16 字节的数组中的一半.更具体地说:您可以对 8 个最高有效字节和 8 个最低有效字节进行异或运算。

标签: java bit-manipulation long-integer xor


【解决方案1】:

我找到的最好的解决方案(根据我的需要...结合了速度和良好的哈希函数)是 Google 的 CityHash。输入可以是任何字节数组,包括 MD5 结果,输出是无符号的 64 位长。

CityHash 的哈希分布非常好但并不完美,而且速度非常快。

我在半小时内将 CityHash 从 C++ 移植到 C#。 Java 端口也应该很简单。

只是对位进行异或运算并不能得到很好的分布(尽管承认速度会非常快)。

我对 Java 不够熟悉,无法准确告诉您如何从字节数组中填充 long(可能有一个我不熟悉的好帮手,或者我可能会弄错 Java 中的一些算术细节) .不过,从本质上讲,您会想要像这样做一些事情

long a = md5[0] * 256 * md5[1] + 256 * 256 * md5[2] + 256 * 256 * 256 * md5[3];
long b = md5[4] * 256 * md5[5] + 256 * 256 * md5[6] + 256 * 256 * 256 * md5[7];
long result = a ^ b;

注意我没有尝试处理endianness。但是,如果您只关心一致的哈希值,那么字节序应该无关紧要。

【讨论】:

  • CityHash 广泛使用了 Java 中不可用的 SSE4 扩展。
  • @Alan:它们在 C# 中也不可用 afaik,但 C# 版本几乎与从 C# 调用 C++ 版本一样快(因此丢失 SSE4 并不比互操作调用更昂贵,给予或接受)。
  • 你应该看看Guava's Hashing
【解决方案2】:

为了清楚起见,加密摘要的任何子部分不再具有摘要的许多加密属性,特别是这些属性不再成立:

  • 反转阻力(寻找满足 H(X) 的 X)
  • 碰撞阻力(寻找 X、Y 使得 H(X) = H(Y))
  • 在可能的输出范围内随机分布

【讨论】:

    【解决方案3】:

    番石榴有一些很好的Hashing capabilities

    Hashing.md5().hashString(s).asLong();
    

    我相信上面实际上是 CityHash,但无论如何它都会生成哈希长,您可以将其用于任何您的哈希需要。 (我试过@Eric J. Java 代码,它看起来像 CityHash 32)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多