Do not hash the elements of the array; instead, hash the differences of two neighboring cells:
#include <stdio.h> unsigned hashdiff(unsigned arr[], size_t siz); /* toy hash function: don't try this at home ... */ #define HASH1(v) ((v)*7654321) unsigned hashdiff(unsigned arr[], size_t siz) { unsigned idx; unsigned hash; if (siz < 1) return 0; if (siz < 2) return HASH1(arr[0]); hash = HASH1( arr[0] - arr[siz-1] ); for(idx=1; idx < siz; idx++) { hash ^= HASH1(arr[idx] - arr[idx-1] ); } return hash; } unsigned arr1[] = {1,9,8,7}; unsigned arr2[] = {9,8,7,1 }; unsigned arr3[] = {1,8,9,7 }; unsigned arr4[] = {1,9,8,5 }; int main(void) { unsigned hash; hash = hashdiff (arr1, 4); printf("%x\n", hash); hash = hashdiff (arr2, 4); printf("%x\n", hash); hash = hashdiff (arr3, 4); printf("%x\n", hash); hash = hashdiff (arr4, 4); printf("%x\n", hash); return 0; }
RESULT:
./a.out fee56452 fee56452 1100b22 fca02416
UPDATE: if you do not want the {1,2,3,4} and {11,12,13,14} with a hash equal the same value, you could increase the difference as follows:
#define HASH1(v) ((v)*7654321) #define HASH2(a,b) HASH1(3u*(a)-5u*(b)) unsigned hashdiff2(unsigned arr[], size_t siz) { unsigned idx; unsigned hash; if (siz < 1) return 0; if (siz < 2) return HASH1(arr[0]); hash = HASH2( arr[0] , arr[siz-1] ); for(idx=1; idx < siz; idx++) { hash ^= HASH2( arr[idx] , arr[idx-1] ); } return hash; }