diff --git a/src/NetMQ/Core/Transports/Ipc/IpcAddress.cs b/src/NetMQ/Core/Transports/Ipc/IpcAddress.cs index 2ccf12484..e8e5e68b7 100644 --- a/src/NetMQ/Core/Transports/Ipc/IpcAddress.cs +++ b/src/NetMQ/Core/Transports/Ipc/IpcAddress.cs @@ -39,15 +39,67 @@ public void Resolve(string name, bool ip4Only) { m_name = name; - int hash = name.GetHashCode(); - if (hash < 0) - hash = -hash; - hash = hash%55536; - hash += 10000; + uint hash = GetMurmurHash(name); + int port = (int)(hash % 55536); + port += 10000; + this.Address = new IPEndPoint(IPAddress.Loopback, port); + } + + /// + /// Calculate hash values using the MurmurHash algorithm + /// + /// input + /// hash value + private static uint GetMurmurHash(string name) + { + const uint seed = 0xc58f1a7b; + const uint m = 0x5bd1e995; + const int r = 24; + + uint hash = seed ^ (uint)name.Length; + int length = name.Length; + int currentIndex = 0; + + while (length >= 4) + { + uint k = unchecked((uint)(name[currentIndex] | + (name[currentIndex + 1] << 8) | + (name[currentIndex + 2] << 16) | + (name[currentIndex + 3] << 24))); + + k = unchecked(k * m); + k ^= k >> r; + k = unchecked(k * m); - this.Address = new IPEndPoint(IPAddress.Loopback, hash); + hash = unchecked(hash * m); + hash ^= k; + + currentIndex += 4; + length -= 4; + } + + switch (length) + { + case 3: + hash ^= unchecked((uint)(name[currentIndex + 2] << 16)); + goto case 2; + case 2: + hash ^= unchecked((uint)(name[currentIndex + 1] << 8)); + goto case 1; + case 1: + hash ^= name[currentIndex]; + hash = unchecked(hash * m); + break; + } + + hash ^= hash >> 13; + hash = unchecked(hash * m); + hash ^= hash >> 15; + + return hash; } + [DisallowNull] public IPEndPoint? Address { get; private set; }