Skip to content

Instantly share code, notes, and snippets.

@teamday
Created June 12, 2018 17:52
Show Gist options
  • Save teamday/85be9f8485040c542c77f7f8ada06ca8 to your computer and use it in GitHub Desktop.
Save teamday/85be9f8485040c542c77f7f8ada06ca8 to your computer and use it in GitHub Desktop.
internal class ByteArrayEquityComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
if (x == null || y == null)
{
return x == y;
}
return UnsafeCompare(x, y);
}
public int GetHashCode(byte[] obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
return ComputeHash(obj);
}
private static unsafe bool UnsafeCompare(byte[] a1, byte[] a2)
{
if (a1 == a2) return true;
if (a1 == null || a2 == null || a1.Length != a2.Length)
return false;
fixed (byte* p1 = a1, p2 = a2)
{
byte* x1 = p1, x2 = p2;
int l = a1.Length;
for (int i = 0; i < l / 8; i++, x1 += 8, x2 += 8)
if (*((long*)x1) != *((long*)x2)) return false;
if ((l & 4) != 0) { if (*((int*)x1) != *((int*)x2)) return false; x1 += 4; x2 += 4; }
if ((l & 2) != 0) { if (*((short*)x1) != *((short*)x2)) return false; x1 += 2; x2 += 2; }
if ((l & 1) != 0) if (*((byte*)x1) != *((byte*)x2)) return false;
return true;
}
}
private static int ComputeHash(params byte[] data)
{
unchecked
{
const int p = 16777619;
int hash = (int)2166136261;
for (int i = 0; i < data.Length; i++)
hash = (hash ^ data[i]) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return hash;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment