将MD5或SHA1哈希代码转换为长整型(64位)

7

我需要计算一个字符串���哈希码,并将其存储到一个“long”变量中。

MD5和SHA1生成的哈希码长度超过64位(MD5-128位,SHA1-160位)。

有什么好的想法吗?

谢谢,

Doron


2
一个想法:不要这样做。你为什么觉得需要这样做呢? - Fred Foo
1
很可能是因为他们想将其用作非加密哈希,作为弱检查以确保他们不会生成多个相同的内容,并且不想存储大量的128位哈希十六进制字符串。 - Eagle-Eye
这是一个很好的方法,比如用于合成聚类键(当您不想存储长用户ID时)或将文件哈希存储在数据库驱动程序文件系统中。通过为文件存储短哈希绝对加速了重复检测。我甚至会基于文件的前N个字节存储一系列哈希值,以及另一个哈希值用于文件的最后N个字节。 - Triynko
6个回答

6
你可以截取哈希值的前64位来使用。这样会使得哈希值的强度减弱,但前64位极有可能是唯一的。对于大多数哈希值的使用场景而言,这种做法是常见且完全可行的。
你也可以将完整的哈希值存储在两个64位整数中。

1
请注意,如果安全性很重要,MD5被认为是一个非常糟糕的选择。但对于存储非机密数据的哈希值来说,它仍然是可以接受的。 - Charles Burns
5
我不同意“对于哈希的大多数用途来说,这既是常见的,也是完全可以接受的做法”的说法。在需要较高安全性或低碰撞率的情况下,安全哈希经常被使用,而使用 64 位哈希是不可接受的。 - Nick Johnson
@NickJohnson:抱歉回复晚了(几年而已)。确实,安全哈希应该超过64位,还有其他一些事情。请注意,我说的是“对于哈希的大多数用途”——在我的经验中,当许多基本数据结构出于性能原因使用哈希时,安全哈希只是九牛一毛。 - Charles Burns

2

我正在使用这个(Java):

public class SimpleLongHash {
    final MessageDigest md;
    //
    public SimpleLongHash() throws NoSuchAlgorithmException {
        md = MessageDigest.getInstance("MD5");
    }
    //
    public long hash(final String str) {
        return hash(str.getBytes());
    }
    public long hash(final byte[] buf) {
        md.reset();
        final byte[] digest = md.digest(buf);
        return (getLong(digest, 0) ^ getLong(digest, 8));
    }
    //
    private static final long getLong(final byte[] array, final int offset) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value = ((value << 8) | (array[offset+i] & 0xFF));
        }
        return value;
    }
}

2
FNV哈希算法的实现很简单。我们将其扩展到了64位,效果非常好。使用它比计算MD5或SHA1并截断结果要快得多。但是,我们不依赖它来进行加密功能,只用于哈希表等方面。
更多关于FNV的信息,包括源代码和详细解释,请访问http://isthe.com/chongo/tech/comp/fnv/

1

如果将前64位和后64位进行XOR操作,导致碰撞的概率会是多少?


0
将位逐一进行异或运算如何?例如,对于MD5,将0-63位与64-127位进行异或,即可得到64位。这样会生成一个较弱的哈希值,请检查是否符合您的要求。
此外,在您的环境不是非常受限制的情况下(例如嵌入式设备),还有一个问题,即“为什么需要缩短哈希值?”

没有必要将位进行异或操作 - 在安全哈希中,任何子集都足够。 - Nick Johnson

0

你也可以使用FooBabel Hasher来尝试不同的哈希算法。


链接指向一个已经不存在的网站。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接