Today we needed to hash one unsigned integer into another to allow anonymising of user data. I found http://www.concentric.net/~Ttwang/tech/inthash.htm which has a list of hashing algorithms which can be easily used in c#. It’s important to test these hashing algorithms to see if duplicate hashes are created, as they were by the first 2 algorithms tried. The algorithm used in the end was tested for an input integer of 1 to 1,000,000 without any duplicates.
static void Main(string[] args) { List<Int32> results = new List<int>(); for (int c = 1; c < 1000000; c++) results.Add(hash32shiftmult(c)); Console.WriteLine("Added hashes to results table, looking for matches."); for (int i = 0; i < results.Count; i++) { if(i%10000 == 0) Console.Write(i + " "); for (int j = 0; j < results.Count; j++) { if (i != j) if (results[i].Equals(results[j])) Console.WriteLine("rnfound at " + i + " (" + results[i] + ") and " + j + " (" + results[j] + ")"); } } Console.ReadLine(); } static int mix(int a, int b, int c) { a=a-b; a=a-c; a=a^(c >> 13); b=b-c; b=b-a; b=b^(a << 8); c=c-a; c=c-b; c=c^(b >> 13); a=a-b; a=a-c; a=a^(c >> 12); b=b-c; b=b-a; b=b^(a << 16); c=c-a; c=c-b; c=c^(b >> 5); a=a-b; a=a-c; a=a^(c >> 3); b=b-c; b=b-a; b=b^(a << 10); c=c-a; c=c-b; c=c^(b >> 15); return c; } static int hash(int a) { a = (a+0x7ed55d6) + (a<<12); a = (a^0xc761c2c) ^ (a>>19); a = (a+0x165667b1) + (a<<5); a = (a+0xd3a264c) ^ (a<<9); a = (a+0xfd70465) + (a<<3); a = (a^0xb55a4f9) ^ (a>>16); return a; } static int hash32shiftmult(int key) { int c2=0x27d4eb2d; // a prime or an odd constant key = (key ^ 61) ^ (key >> 16); key = key + (key << 3); key = key ^ (key >> 4); key = key * c2; key = key ^ (key >> 15); return key; }