我的 java 哈希码的 MD5,它是 int 32 位

问题描述 投票:0回答:2

我正在寻求实现我的 ConsistentHashing,我可以为其提供良好的 HashingFunction。这里解释了使用 SortedMap 的一个不错的实现:https://weblogs.java.net/blog/tomwhite/archive/2007/11/consistency_hash.html

现在就像帖子中建议的那样,我想使用像 MD5 这样具有良好随机性的加密函数。我知道 MD5 会返回固有的 128 位输出,但是我需要随机的 32 位。以下的基数会很高吗?

(1) MD5 输出的前 4 个字节是否足够随机?在这种情况下,我可以只取 128 位 MD5 哈希值中的前 32 位:

   class MD5Hashing implements HashFunction{
        @Override
        public int getHash(String key) throws Exception{
                MessageDigest digest = MessageDigest.getInstance("MD5");
                byte[] byteArray = digest.digest(key.getBytes("UTF-8"));
                ByteBuffer buffer = ByteBuffer.wrap(byteArray);
                return buffer.getInt()& 0x7fffffff;
        }
    }

(2) 如果我只使用 String 的内部 Horner 算法,该算法对 String 中的所有字符使用 31x+y 会怎样?

class StringHashing implements HashFunction{
    @Override
    public int getHash(String key) throws Exception{
        return key.hashCode()& 0x7fffffff; 
    }
}

(3) 我的内部一致散列(如上面的链接)只是一个 TreeMap 我是否应该使用 BigInteger 来仍然能够从 MD5 或其他加密算法获取所有 128 位?

private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>(); 

编辑: 看起来两者都不好,我什至尝试从 MD5 哈希值中获取最后 4 个字节。缓冲区.getInt(12)。

运行 5000 个随机字符串后就是分布。 {host4.a.b.com=1599,host3.a.b.com=1075,host2.a.b.com=238,host1.a.b.com=2088}

java hash
2个回答
0
投票

发现 Murmur hash 具有将字符串输入转换为 32 位哈希输出的 API。也给了我一个非常好的分布。

{host4.a.b.com=1665,host3.a.b.com=1373,host2.a.b.com=648,host1.a.b.com=1314}

http://d3s.mff.cuni.cz/~holub/sw/javamurmurhash/
public static int hash32( final String text) {...}

0
投票

显然截断某些哈希值并不会降低其安全性,而只是增加冲突,如其他响应中所述:

https://security.stackexchange.com/questions/97377/secure-way-to-shorten-a-hash

对于这个问题,我无法理解

a.b.com
算法到底是如何工作的,也许你可以进一步解释它,分析你得到的不规则分布是否取决于所取的样本(仅5000个输入,或者可能仅是ASCII,或者其他)。

© www.soinside.com 2019 - 2024. All rights reserved.