Order-independent Hash Algorithm

后端 未结 3 1141
庸人自扰
庸人自扰 2020-12-17 10:48

I am currently working on a collection library for my custom programming language. I already have several data types (Collection, List, Map, Set) and implementations for the

相关标签:
3条回答
  • 2020-12-17 10:53

    Here's the pseudocode for a possible implementation:

    String hashCode = null;
    for(element : elements){
        hashCode = xor(hashCode, getHashCode(element));
    }
    return hashCode;
    

    The xor function should return a string that is as long as the longest of the two arguments. It will XOR the bits in each until it gets to the end of one of the arguments. It will then take the remaining bits from the longer string and append those on.

    This implementation will mean that the hashCode of a set will be as long as the hashCode of its longest element. Because you are XORing the bits, at the end the hashcode will be the same regardless of the order of your elements. However, as with any hashing implementation, there will be the chance for collisions.

    0 讨论(0)
  • 2020-12-17 11:01

    The JDK itself proposes the following solution to this problem. The contract of the java.util.Set interface states:

    Returns the hash code value for this set. The hash code of a set is defined to be the sum of the hash codes of the elements in the set, where the hash code of a null element is defined to be zero. This ensures that s1.equals(s2) implies that s1.hashCode()==s2.hashCode() for any two sets s1 and s2, as required by the general contract of Object.hashCode().

    An alternative to using the sum of the entries' hash codes would be to use, for example, the ^ (XOR) operator.

    The Scala language uses an ordering-invariant version of the Murmurhash algorithm (cf. the private scala.util.hashing.MurmurHash3 class) to implement the hashCode (or ##) method of its immutable sets and similar collections.

    0 讨论(0)
  • 2020-12-17 11:07

    You can calculate the hash sum sorting your collection in alphabetical order.

    There is the C# sample - I hope you can translate it in Java :)

    static String GetHash(List<String> l)
    {
        using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
        {
            return BitConverter.ToString(md5.ComputeHash(l.OrderBy(p => p).SelectMany(s => System.Text.Encoding.ASCII.GetBytes(s + (char)0)).ToArray())).Replace("-", "");
        }
    }
    
    0 讨论(0)
提交回复
热议问题