C# hashcode for array of ints

后端 未结 7 590
不思量自难忘°
不思量自难忘° 2020-11-28 13:24

I have a class that internally is just an array of integers. Once constructed the array never changes. I\'d like to pre-compute a good hashcode so that this class can be ver

相关标签:
7条回答
  • 2020-11-28 14:04

    Not very clever, but sufficient for most practical purposes:

    EDIT: changed due to comment of Henk Holterman, thanks for that.

    int hc=array.Length;
    for(int i=0;i<array.Length;++i)
    {
         hc=unchecked(hc*314159 +array[i]);
    }
    return hc;
    

    If you need something more sophisticated, look here.

    0 讨论(0)
  • 2020-11-28 14:04

    For an array of values generally between -1000 and 1000, I would probably use something like this:

    static int GetHashCode(int[] values)
    {
       int result = 0;
       int shift = 0;
       for (int i = 0; i < values.Length; i++)
       {
          shift = (shift + 11) % 21;
          result ^= (values[i]+1024) << shift;
       }
       return result;
    }
    
    0 讨论(0)
  • 2020-11-28 14:08

    I would recommend:

    HashCode.Combine(array)
    

    For .NET Core 2.1 / .NET Standard 2.1 / .NET 5 and later.

    0 讨论(0)
  • 2020-11-28 14:10

    I think choosing a good hash-algorithm would have to be based on the distribution (in a probability sense) of the integer values.

    Have a look at Wikipedia for a list of algorithms

    0 讨论(0)
  • 2020-11-28 14:12

    Any CRC (or even XOR) should be ok.

    0 讨论(0)
  • 2020-11-28 14:19

    You may use CRC32 checksum. Here is the code:

    [CLSCompliant(false)]
    public class Crc32 {
        uint[] table = new uint[256];
        uint[] Table { get { return table; } }
    
        public Crc32() {
            MakeCrcTable();
        }
        void MakeCrcTable() {
            for (uint n = 0; n < 256; n++) {
                uint value = n;
                for (int i = 0; i < 8; i++) {
                    if ((value & 1) != 0)
                        value = 0xedb88320 ^ (value >> 1);
                    else
                        value = value >> 1;
                }
                Table[n] = value;
            }
        }
        public uint UpdateCrc(uint crc, byte[] buffer, int length) {
            uint result = crc;
            for (int n = 0; n < length; n++) {
                result = Table[(result ^ buffer[n]) & 0xff] ^ (result >> 8);
            }
            return result;
        }
        public uint Calculate(Stream stream) {
            long pos = stream.Position;
            const int size = 0x32000;
            byte[] buf = new byte[size];
            int bytes = 0;
            uint result = 0xffffffff;
            do {
                bytes = stream.Read(buf, 0, size);
                result = UpdateCrc(result, buf, bytes);
            }
            while (bytes == size);
            stream.Position = pos;
            return ~result;
        }
    }
    
    0 讨论(0)
提交回复
热议问题