+// ---------------------------------------------
+
+// ---------------------------------------------
+// modification to Mikkel's string hashing code
+// Return the full 64 bits ... low order bits are not random
+// but we can squeeze a few more bits out.
+
+//assumes string length even
+inline INT64 EvenStringHash64bit(INT32 * x, gs_int32_t length,
+ Hash32bit2univID hid) {
+ gs_int32_t i;
+ INT64 H;
+ INT64 xh1,xh2,y;
+
+ H=0;
+ for (i=0;i<length;i+=2) {
+ xh1=x[i]+hid[i+1];
+ xh2=x[i+1]+hid[i];
+ y=xh1*xh2;
+ H = H^y;
+ }
+ H=H^hid[length];
+ return H;
+}
+
+//assumes string length odd
+inline INT64 OddStringHash64bit(INT32 * x, gs_int32_t length,
+ Hash32bit2univID hid) {
+ gs_int32_t i;
+ INT64 H;
+ INT64 xh1,xh2,y;
+
+ H = x[0]*hid[0];
+ for (i=1;i<length;i+=2) {
+ xh1=x[i]+hid[i+1];
+ xh2=x[i+1]+hid[i];
+ y=xh1*xh2;
+ H = H^y;
+ }
+ H=H^hid[length];
+ return H;
+}
+
+//Below we have the generic algorithm for fixed length string hashing
+//For shorter strings of length < 6, it is worthwhile using
+//specialized versions with fewer tests.
+//All versions rely on the some initialization above.
+inline INT64 StringHash64bit(INT32 * x, gs_int32_t length, Hash32bit2univID hid) {
+// gs_int32_t i;
+// INT64 H=0;
+// INT32 h;
+// for (i=0;i<length;i++) H = H^(x[i]*hid[i]);
+// H=H^hid[length];
+// h = H >> 32;
+// return h;
+ if (length&1) return OddStringHash64bit(x,length,hid);
+ else return EvenStringHash64bit(x,length,hid);
+}
+
+// ---------------------------------------------
+
+