public static long hash24_palindromic(long k0,long k1,byte[] data,int offset,int len){
  long v0=0x736f6d6570736575L ^ k0;
  long v1=0x646f72616e646f6dL ^ k1;
  long v2=0x6c7967656e657261L ^ k0;
  long v3=0x7465646279746573L ^ k1;
  long m;
  int last=(2 * len) / 8 * 8;
  int idx=0;
  int offset2=offset + len + len - 1;
  int len8=len - (len % 8);
  if (last > 0) {
    while (idx < len8) {
      m=UNSAFE.getLong(data,base + offset + idx);
      idx+=8;
      v3^=m;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0^=m;
    }
{
      m=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL);
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 8;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 16;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 24;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 32;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 40;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 48;
      idx++;
      m|=(data[offset + (idx >= len ? (len - 1 - (idx % len)) : idx)] & 0xffL) << 56;
      idx++;
      v3^=m;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0^=m;
    }
    while (idx < last) {
      m=Long.reverseBytes(UNSAFE.getLong(data,base + offset2 - (idx + 7)));
      idx+=8;
      v3^=m;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0+=v1;
      v2+=v3;
      v1=(v1 << 13) | v1 >>> 51;
      v3=(v3 << 16) | v3 >>> 48;
      v1^=v0;
      v3^=v2;
      v0=(v0 << 32) | v0 >>> 32;
      v2+=v1;
      v0+=v3;
      v1=(v1 << 17) | v1 >>> 47;
      v3=(v3 << 21) | v3 >>> 43;
      v1^=v2;
      v3^=v0;
      v2=(v2 << 32) | v2 >>> 32;
      v0^=m;
    }
  }
  m=0;
  if (0 != idx) {
    int i=0;
    while (i < (len * 2 - idx)) {
      m<<=8;
      m|=data[offset + i] & 0xffL;
      i++;
    }
  }
 else {
    for (int i=0; i < len * 2; i++) {
      m<<=8;
      m|=data[offset + (i >= len ? (len - 1 - (i % len)) : i)] & 0xffL;
    }
  }
  m|=(long)(len * 2) << 56;
  v3^=m;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  v0^=m;
  v2^=0xff;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  v0+=v1;
  v2+=v3;
  v1=(v1 << 13) | v1 >>> 51;
  v3=(v3 << 16) | v3 >>> 48;
  v1^=v0;
  v3^=v2;
  v0=(v0 << 32) | v0 >>> 32;
  v2+=v1;
  v0+=v3;
  v1=(v1 << 17) | v1 >>> 47;
  v3=(v3 << 21) | v3 >>> 43;
  v1^=v2;
  v3^=v0;
  v2=(v2 << 32) | v2 >>> 32;
  return v0 ^ v1 ^ v2^ v3;
}

public static long hash24_palindromic ( long k0 , long k1 , byte [ ] data , int offset , int len ) { long v0 = 0x736f6d6570736575L ^ k0 ; long v1 = 0x646f72616e646f6dL ^ k1 ; long v2 = 0x6c7967656e657261L ^ k0 ; long v3 = 0x7465646279746573L ^ k1 ; long m ; int last = ( 2 * len ) / 8 * 8 ; int idx = 0 ; int offset2 = offset + len + len - 1 ; int len8 = len - ( len % 8 ) ; if ( last > 0 ) { while ( idx < len8 ) { m = UNSAFE . getLong ( data , base + offset + idx ) ; idx += 8 ; v3 ^= m ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 ^= m ; } { m = ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 8 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 16 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 24 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 32 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 40 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 48 ; idx ++ ; m |= ( data [ offset + ( idx >= len ? ( len - 1 - ( idx % len ) ) : idx ) ] & 0xffL ) << 56 ; idx ++ ; v3 ^= m ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 ^= m ; } while ( idx < last ) { m = Long . reverseBytes ( UNSAFE . getLong ( data , base + offset2 - ( idx + 7 ) ) ) ; idx += 8 ; v3 ^= m ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 ^= m ; } } m = 0 ; if ( 0 != idx ) { int i = 0 ; while ( i < ( len * 2 - idx ) ) { m <<= 8 ; m |= data [ offset + i ] & 0xffL ; i ++ ; } } else { for ( int i = 0 ; i < len * 2 ; i ++ ) { m <<= 8 ; m |= data [ offset + ( i >= len ? ( len - 1 - ( i % len ) ) : i ) ] & 0xffL ; } } m |= ( long ) ( len * 2 ) << 56 ; v3 ^= m ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 ^= m ; v2 ^= 0xff ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; v0 += v1 ; v2 += v3 ; v1 = ( v1 << 13 ) | v1 > > > 51 ; v3 = ( v3 << 16 ) | v3 > > > 48 ; v1 ^= v0 ; v3 ^= v2 ; v0 = ( v0 << 32 ) | v0 > > > 32 ; v2 += v1 ; v0 += v3 ; v1 = ( v1 << 17 ) | v1 > > > 47 ; v3 = ( v3 << 21 ) | v3 > > > 43 ; v1 ^= v2 ; v3 ^= v0 ; v2 = ( v2 << 32 ) | v2 > > > 32 ; return v0 ^ v1 ^ v2 ^ v3 ; }
version of siphash which computes the hash of the input concatenated with the reversed input in order to minimize the risk of collisions ( for a collision to be an actual value , it must have the same structure as the original input , i . e . be a palindrome ) .
