/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.codec.digest;

import org.apache.commons.codec.binary.StringUtils;

/**
 * Implementation of the MurmurHash3 32-bit and 128-bit hash functions.
 *
 * <p>
 * MurmurHash is a non-cryptographic hash function suitable for general hash-based lookup. The name comes from two basic
 * operations, multiply (MU) and rotate (R), used in its inner loop. Unlike cryptographic hash functions, it is not
 * specifically designed to be difficult to reverse by an adversary, making it unsuitable for cryptographic purposes.
 * </p>
 *
 * <p>
 * This contains a Java port of the 32-bit hash function {@code MurmurHash3_x86_32} and the 128-bit hash function
 * {@code MurmurHash3_x64_128} from Austin Applyby's original {@code c++} code in SMHasher.
 * </p>
 *
 * <p>
 * This is public domain code with no copyrights. From home page of
 * <a href="https://github.com/aappleby/smhasher">SMHasher</a>:
 * </p>
 *
 * <blockquote> "All MurmurHash versions are public domain software, and the author disclaims all copyright to their
 * code." </blockquote>
 *
 * <p>
 * Original adaption from Apache Hive. That adaption contains a {@code hash64} method that is not part of the original
 * MurmurHash3 code. It is not recommended to use these methods. They will be removed in a future release. To obtain a
 * 64-bit hash use half of the bits from the {@code hash128x64} methods using the input data converted to bytes.
 * <p>
 *
 * @see <a href="https://en.wikipedia.org/wiki/MurmurHash">MurmurHash</a>
 * @see <a href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp"> Original MurmurHash3 c++
 *      code</a>
 * @see <a href=
 *      "https://github.com/apache/hive/blob/master/storage-api/src/java/org/apache/hive/common/util/Murmur3.java">
 *      Apache Hive Murmer3</a>
 * @since 1.13
 */
public final class MurmurHash3 {

    /**
     * A random number to use for a hash code.
     *
     * @deprecated This is not used internally and will be removed in a future release.
     */
    @Deprecated
    public static final long NULL_HASHCODE = 2862933555777941757L;

    /**
     * A default seed to use for the murmur hash algorithm.
     * Has the value {@code 104729}.
     */
    public static final int DEFAULT_SEED = 104729;

    /** TODO Replace on Java 8 with Long.BYTES. */
    static final int LONG_BYTES = Long.SIZE / Byte.SIZE;

    /** TODO Replace on Java 8 with Integer.BYTES. */
    static final int INTEGER_BYTES = Integer.SIZE / Byte.SIZE;

    /** TODO Replace on Java 8 with Short.BYTES. */
    static final int SHORT_BYTES = Short.SIZE / Byte.SIZE;

    // Constants for 32-bit variant
    private static final int C1_32 = 0xcc9e2d51;
    private static final int C2_32 = 0x1b873593;
    private static final int R1_32 = 15;
    private static final int R2_32 = 13;
    private static final int M_32 = 5;
    private static final int N_32 = 0xe6546b64;

    // Constants for 128-bit variant
    private static final long C1 = 0x87c37b91114253d5L;
    private static final long C2 = 0x4cf5ad432745937fL;
    private static final int R1 = 31;
    private static final int R2 = 27;
    private static final int R3 = 33;
    private static final int M = 5;
    private static final int N1 = 0x52dce729;
    private static final int N2 = 0x38495ab5;

    /** No instance methods. */
    private MurmurHash3() {
    }

    /**
     * Generates 32-bit hash from two longs with a default seed value.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * int hash = MurmurHash3.hash32x86(ByteBuffer.allocate(16)
     *                                            .putLong(data1)
     *                                            .putLong(data2)
     *                                            .array(), offset, 16, seed);
     * </pre>
     *
     * @param data1 The first long to hash
     * @param data2 The second long to hash
     * @return The 32-bit hash
     * @see #hash32x86(byte[], int, int, int)
     */
    public static int hash32(final long data1, final long data2) {
        return hash32(data1, data2, DEFAULT_SEED);
    }

    /**
     * Generates 32-bit hash from two longs with the given seed.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int hash = MurmurHash3.hash32x86(ByteBuffer.allocate(16)
     *                                            .putLong(data1)
     *                                            .putLong(data2)
     *                                            .array(), offset, 16, seed);
     * </pre>
     *
     * @param data1 The first long to hash
     * @param data2 The second long to hash
     * @param seed The initial seed value
     * @return The 32-bit hash
     * @see #hash32x86(byte[], int, int, int)
     */
    public static int hash32(final long data1, final long data2, final int seed) {
        int hash = seed;
        final long r0 = Long.reverseBytes(data1);
        final long r1 = Long.reverseBytes(data2);

        hash = mix32((int) r0, hash);
        hash = mix32((int) (r0 >>> 32), hash);
        hash = mix32((int) (r1), hash);
        hash = mix32((int) (r1 >>> 32), hash);

        hash ^= LONG_BYTES * 2;
        return fmix32(hash);
    }

    /**
     * Generates 32-bit hash from a long with a default seed value.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * int hash = MurmurHash3.hash32x86(ByteBuffer.allocate(8)
     *                                            .putLong(data)
     *                                            .array(), offset, 8, seed);
     * </pre>
     *
     * @param data The long to hash
     * @return The 32-bit hash
     * @see #hash32x86(byte[], int, int, int)
     */
    public static int hash32(final long data) {
        return hash32(data, DEFAULT_SEED);
    }

    /**
     * Generates 32-bit hash from a long with the given seed.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int hash = MurmurHash3.hash32x86(ByteBuffer.allocate(8)
     *                                            .putLong(data)
     *                                            .array(), offset, 8, seed);
     * </pre>
     *
     * @param data The long to hash
     * @param seed The initial seed value
     * @return The 32-bit hash
     * @see #hash32x86(byte[], int, int, int)
     */
    public static int hash32(final long data, final int seed) {
        int hash = seed;
        final long r0 = Long.reverseBytes(data);

        hash = mix32((int) r0, hash);
        hash = mix32((int) (r0 >>> 32), hash);

        hash ^= LONG_BYTES;
        return fmix32(hash);
    }

    /**
     * Generates 32-bit hash from the byte array with a default seed.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * int hash = MurmurHash3.hash32(data, offset, data.length, seed);
     * </pre>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @param data The input byte array
     * @return The 32-bit hash
     * @see #hash32(byte[], int, int, int)
     * @deprecated Use {@link #hash32x86(byte[], int, int, int)}. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static int hash32(final byte[] data) {
        return hash32(data, 0, data.length, DEFAULT_SEED);
    }

    /**
     * Generates 32-bit hash from a string with a default seed.
     * <p>
     * Before 1.14 the string was converted using default encoding.
     * Since 1.14 the string is converted to bytes using UTF-8 encoding.
     * </p>
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
     * int hash = MurmurHash3.hash32(bytes, offset, bytes.length, seed);
     * </pre>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @param data The input string
     * @return The 32-bit hash
     * @see #hash32(byte[], int, int, int)
     * @deprecated Use {@link #hash32x86(byte[], int, int, int)} with the bytes returned from
     * {@link String#getBytes(java.nio.charset.Charset)}. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static int hash32(final String data) {
        final byte[] bytes = StringUtils.getBytesUtf8(data);
        return hash32(bytes, 0, bytes.length, DEFAULT_SEED);
    }

    /**
     * Generates 32-bit hash from the byte array with the given length and a default seed.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * int hash = MurmurHash3.hash32(data, offset, length, seed);
     * </pre>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @param data The input byte array
     * @param length The length of array
     * @return The 32-bit hash
     * @see #hash32(byte[], int, int, int)
     * @deprecated Use {@link #hash32x86(byte[], int, int, int)}. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static int hash32(final byte[] data, final int length) {
        return hash32(data, length, DEFAULT_SEED);
    }

    /**
     * Generates 32-bit hash from the byte array with the given length and seed. This is a
     * helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int hash = MurmurHash3.hash32(data, offset, length, seed);
     * </pre>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @param data The input byte array
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 32-bit hash
     * @see #hash32(byte[], int, int, int)
     * @deprecated Use {@link #hash32x86(byte[], int, int, int)}. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static int hash32(final byte[] data, final int length, final int seed) {
        return hash32(data, 0, length, seed);
    }

    /**
     * Generates 32-bit hash from the byte array with the given offset, length and seed.
     *
     * <p>This is an implementation of the 32-bit hash function {@code MurmurHash3_x86_32}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @param data The input byte array
     * @param offset The offset of data
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 32-bit hash
     * @deprecated Use {@link #hash32x86(byte[], int, int, int)}. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static int hash32(final byte[] data, final int offset, final int length, final int seed) {
        int hash = seed;
        final int nblocks = length >> 2;

        // body
        for (int i = 0; i < nblocks; i++) {
            final int index = offset + (i << 2);
            final int k = getLittleEndianInt(data, index);
            hash = mix32(k, hash);
        }

        // tail
        // ************
        // Note: This fails to apply masking using 0xff to the 3 remaining bytes.
        // ************
        final int index = offset + (nblocks << 2);
        int k1 = 0;
        switch (offset + length - index) {
        case 3:
            k1 ^= data[index + 2] << 16;
        case 2:
            k1 ^= data[index + 1] << 8;
        case 1:
            k1 ^= data[index];

            // mix functions
            k1 *= C1_32;
            k1 = Integer.rotateLeft(k1, R1_32);
            k1 *= C2_32;
            hash ^= k1;
        }

        hash ^= length;
        return fmix32(hash);
    }

    /**
     * Generates 32-bit hash from the byte array with a seed of zero.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 0;
     * int hash = MurmurHash3.hash32x86(data, offset, data.length, seed);
     * </pre>
     *
     * @param data The input byte array
     * @return The 32-bit hash
     * @see #hash32x86(byte[], int, int, int)
     * @since 1.14
     */
    public static int hash32x86(final byte[] data) {
        return hash32x86(data, 0, data.length, 0);
    }

    /**
     * Generates 32-bit hash from the byte array with the given offset, length and seed.
     *
     * <p>This is an implementation of the 32-bit hash function {@code MurmurHash3_x86_32}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * @param data The input byte array
     * @param offset The offset of data
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 32-bit hash
     * @since 1.14
     */
    public static int hash32x86(final byte[] data, final int offset, final int length, final int seed) {
        int hash = seed;
        final int nblocks = length >> 2;

        // body
        for (int i = 0; i < nblocks; i++) {
            final int index = offset + (i << 2);
            final int k = getLittleEndianInt(data, index);
            hash = mix32(k, hash);
        }

        // tail
        final int index = offset + (nblocks << 2);
        int k1 = 0;
        switch (offset + length - index) {
        case 3:
            k1 ^= (data[index + 2] & 0xff) << 16;
        case 2:
            k1 ^= (data[index + 1] & 0xff) << 8;
        case 1:
            k1 ^= (data[index] & 0xff);

            // mix functions
            k1 *= C1_32;
            k1 = Integer.rotateLeft(k1, R1_32);
            k1 *= C2_32;
            hash ^= k1;
        }

        hash ^= length;
        return fmix32(hash);
    }

    /**
     * Generates 64-bit hash from a long with a default seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * The method does not produce the same result as either half of the hash bytes from
     * {@linkplain #hash128x64(byte[])} with the same byte data from the {@code long}.
     * This method will be removed in a future release.</p>
     *
     * <p>Note: The sign extension bug in {@link #hash64(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * <p>This is a helper method that will produce the same result as:</p>
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * long hash = MurmurHash3.hash64(ByteBuffer.allocate(8)
     *                                          .putLong(data)
     *                                          .array(), offset, 8, seed);
     * </pre>
     *
     * @param data The long to hash
     * @return The 64-bit hash
     * @see #hash64(byte[], int, int, int)
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[])} with the bytes from the {@code long}.
     */
    @Deprecated
    public static long hash64(final long data) {
        long hash = DEFAULT_SEED;
        long k = Long.reverseBytes(data);
        final int length = LONG_BYTES;
        // mix functions
        k *= C1;
        k = Long.rotateLeft(k, R1);
        k *= C2;
        hash ^= k;
        hash = Long.rotateLeft(hash, R2) * M + N1;
        // finalization
        hash ^= length;
        hash = fmix64(hash);
        return hash;
    }

    /**
     * Generates 64-bit hash from an int with a default seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * The method does not produce the same result as either half of the hash bytes from
     * {@linkplain #hash128x64(byte[])} with the same byte data from the {@code int}.
     * This method will be removed in a future release.</p>
     *
     * <p>Note: The sign extension bug in {@link #hash64(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * <p>This is a helper method that will produce the same result as:</p>
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * long hash = MurmurHash3.hash64(ByteBuffer.allocate(4)
     *                                          .putInt(data)
     *                                          .array(), offset, 4, seed);
     * </pre>
     *
     * @param data The int to hash
     * @return The 64-bit hash
     * @see #hash64(byte[], int, int, int)
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[])} with the bytes from the {@code int}.
     */
    @Deprecated
    public static long hash64(final int data) {
        long k1 = Integer.reverseBytes(data) & (-1L >>> 32);
        final int length = INTEGER_BYTES;
        long hash = DEFAULT_SEED;
        k1 *= C1;
        k1 = Long.rotateLeft(k1, R1);
        k1 *= C2;
        hash ^= k1;
        // finalization
        hash ^= length;
        hash = fmix64(hash);
        return hash;
    }

    /**
     * Generates 64-bit hash from a short with a default seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * The method does not produce the same result as either half of the hash bytes from
     * {@linkplain #hash128x64(byte[])} with the same byte data from the {@code short}.
     * This method will be removed in a future release.</p>
     *
     * <p>Note: The sign extension bug in {@link #hash64(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * <p>This is a helper method that will produce the same result as:</p>
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * long hash = MurmurHash3.hash64(ByteBuffer.allocate(2)
     *                                          .putShort(data)
     *                                          .array(), offset, 2, seed);
     * </pre>
     *
     * @param data The short to hash
     * @return The 64-bit hash
     * @see #hash64(byte[], int, int, int)
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[])} with the bytes from the {@code short}.
     */
    @Deprecated
    public static long hash64(final short data) {
        long hash = DEFAULT_SEED;
        long k1 = 0;
        k1 ^= ((long) data & 0xff) << 8;
        k1 ^= ((long) ((data & 0xFF00) >> 8) & 0xff);
        k1 *= C1;
        k1 = Long.rotateLeft(k1, R1);
        k1 *= C2;
        hash ^= k1;

        // finalization
        hash ^= SHORT_BYTES;
        hash = fmix64(hash);
        return hash;
    }

    /**
     * Generates 64-bit hash from a byte array with a default seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * The method does not produce the same result as either half of the hash bytes from
     * {@linkplain #hash128x64(byte[])} with the same byte data.
     * This method will be removed in a future release.</p>
     *
     * <p>Note: The sign extension bug in {@link #hash64(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * <p>This is a helper method that will produce the same result as:</p>
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * long hash = MurmurHash3.hash64(data, offset, data.length, seed);
     * </pre>
     *
     * @param data The input byte array
     * @return The 64-bit hash
     * @see #hash64(byte[], int, int, int)
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[])}.
     */
    @Deprecated
    public static long hash64(final byte[] data) {
        return hash64(data, 0, data.length, DEFAULT_SEED);
    }

    /**
     * Generates 64-bit hash from a byte array with the given offset and length and a default seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * The method does not produce the same result as either half of the hash bytes from
     * {@linkplain #hash128x64(byte[])} with the same byte data.
     * This method will be removed in a future release.</p>
     *
     * <p>Note: The sign extension bug in {@link #hash64(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * <p>This is a helper method that will produce the same result as:</p>
     *
     * <pre>
     * int seed = 104729;
     * long hash = MurmurHash3.hash64(data, offset, length, seed);
     * </pre>
     *
     * @param data The input byte array
     * @param offset The offset of data
     * @param length The length of array
     * @return The 64-bit hash
     * @see #hash64(byte[], int, int, int)
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[], int, int, int)}.
     */
    @Deprecated
    public static long hash64(final byte[] data, final int offset, final int length) {
        return hash64(data, offset, length, DEFAULT_SEED);
    }

    /**
     * Generates 64-bit hash from a byte array with the given offset, length and seed.
     *
     * <p><strong>This is not part of the original MurmurHash3 {@code c++} implementation.</strong></p>
     *
     * <p>This is a Murmur3-like 64-bit variant.
     * This method will be removed in a future release.</p>
     *
     * <p>This implementation contains a sign-extension bug in the seed initialization.
     * This manifests if the seed is negative.</p>
     *
     * <p>This algorithm processes 8 bytes chunks of data in a manner similar to the 16 byte chunks
     * of data processed in the MurmurHash3 {@code MurmurHash3_x64_128} method. However the hash
     * is not mixed with a hash chunk from the next 8 bytes of data. The method will not return
     * the same value as the first or second 64-bits of the function
     * {@link #hash128(byte[], int, int, int)}.</p>
     *
     * <p>Use of this method is not advised. Use the first long returned from
     * {@link #hash128x64(byte[], int, int, int)}.<p>
     *
     * @param data The input byte array
     * @param offset The offset of data
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 64-bit hash
     * @deprecated Not part of the MurmurHash3 implementation.
     * Use half of the hash bytes from {@link #hash128x64(byte[], int, int, int)}.
     */
    @Deprecated
    public static long hash64(final byte[] data, final int offset, final int length, final int seed) {
        // ************
        // Note: This fails to apply masking using 0xffffffffL to the seed.
        // ************
        long hash = seed;
        final int nblocks = length >> 3;

        // body
        for (int i = 0; i < nblocks; i++) {
            final int index = offset + (i << 3);
            long k = getLittleEndianLong(data, index);

            // mix functions
            k *= C1;
            k = Long.rotateLeft(k, R1);
            k *= C2;
            hash ^= k;
            hash = Long.rotateLeft(hash, R2) * M + N1;
        }

        // tail
        long k1 = 0;
        final int index = offset + (nblocks << 3);
        switch (offset + length - index) {
        case 7:
            k1 ^= ((long) data[index + 6] & 0xff) << 48;
        case 6:
            k1 ^= ((long) data[index + 5] & 0xff) << 40;
        case 5:
            k1 ^= ((long) data[index + 4] & 0xff) << 32;
        case 4:
            k1 ^= ((long) data[index + 3] & 0xff) << 24;
        case 3:
            k1 ^= ((long) data[index + 2] & 0xff) << 16;
        case 2:
            k1 ^= ((long) data[index + 1] & 0xff) << 8;
        case 1:
            k1 ^= ((long) data[index] & 0xff);
            k1 *= C1;
            k1 = Long.rotateLeft(k1, R1);
            k1 *= C2;
            hash ^= k1;
        }

        // finalization
        hash ^= length;
        hash = fmix64(hash);

        return hash;
    }

    /**
     * Generates 128-bit hash from the byte array with a default seed.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * int hash = MurmurHash3.hash128(data, offset, data.length, seed);
     * </pre>
     *
     * <p>Note: The sign extension bug in {@link #hash128(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * @param data The input byte array
     * @return The 128-bit hash (2 longs)
     * @see #hash128(byte[], int, int, int)
     */
    public static long[] hash128(final byte[] data) {
        return hash128(data, 0, data.length, DEFAULT_SEED);
    }

    /**
     * Generates 128-bit hash from the byte array with a seed of zero.
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 0;
     * int hash = MurmurHash3.hash128x64(data, offset, data.length, seed);
     * </pre>
     *
     * @param data The input byte array
     * @return The 128-bit hash (2 longs)
     * @see #hash128x64(byte[], int, int, int)
     * @since 1.14
     */
    public static long[] hash128x64(final byte[] data) {
        return hash128x64(data, 0, data.length, 0);
    }

    /**
     * Generates 128-bit hash from a string with a default seed.
     * <p>
     * Before 1.14 the string was converted using default encoding.
     * Since 1.14 the string is converted to bytes using UTF-8 encoding.
     * </p>
     * This is a helper method that will produce the same result as:
     *
     * <pre>
     * int offset = 0;
     * int seed = 104729;
     * byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
     * int hash = MurmurHash3.hash128(bytes, offset, bytes.length, seed);
     * </pre>
     *
     * <p>Note: The sign extension bug in {@link #hash128(byte[], int, int, int)} does not effect
     * this result as the default seed is positive.</p>
     *
     * @param data The input String
     * @return The 128-bit hash (2 longs)
     * @see #hash128(byte[], int, int, int)
     * @deprecated Use {@link #hash128x64(byte[])} using the bytes returned from
     * {@link String#getBytes(java.nio.charset.Charset)}.
     */
    @Deprecated
    public static long[] hash128(final String data) {
        final byte[] bytes = StringUtils.getBytesUtf8(data);
        return hash128(bytes, 0, bytes.length, DEFAULT_SEED);
    }

    /**
     * Generates 128-bit hash from the byte array with the given offset, length and seed.
     *
     * <p>This is an implementation of the 128-bit hash function {@code MurmurHash3_x64_128}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * <p>This implementation contains a sign-extension bug in the seed initialization.
     * This manifests if the seed is negative.<p>
     *
     * @param data The input byte array
     * @param offset The first element of array
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 128-bit hash (2 longs)
     * @deprecated Use {@link #hash128x64(byte[], int, int, int)}. This corrects the seed initialization.
     */
    @Deprecated
    public static long[] hash128(final byte[] data, final int offset, final int length, final int seed) {
        // ************
        // Note: This deliberately fails to apply masking using 0xffffffffL to the seed
        // to maintain behavioral compatibility with the original version.
        // The implicit conversion to a long will extend a negative sign
        // bit through the upper 32-bits of the long seed. These should be zero.
        // ************
        return hash128x64Internal(data, offset, length, seed);
    }

    /**
     * Generates 128-bit hash from the byte array with the given offset, length and seed.
     *
     * <p>This is an implementation of the 128-bit hash function {@code MurmurHash3_x64_128}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * @param data The input byte array
     * @param offset The first element of array
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 128-bit hash (2 longs)
     * @since 1.14
     */
    public static long[] hash128x64(final byte[] data, final int offset, final int length, final int seed) {
        // Use an unsigned 32-bit integer as the seed
        return hash128x64Internal(data, offset, length, seed & 0xffffffffL);
    }

    /**
     * Generates 128-bit hash from the byte array with the given offset, length and seed.
     *
     * <p>This is an implementation of the 128-bit hash function {@code MurmurHash3_x64_128}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * @param data The input byte array
     * @param offset The first element of array
     * @param length The length of array
     * @param seed The initial seed value
     * @return The 128-bit hash (2 longs)
     */
    private static long[] hash128x64Internal(final byte[] data, final int offset, final int length, final long seed) {
        long h1 = seed;
        long h2 = seed;
        final int nblocks = length >> 4;

        // body
        for (int i = 0; i < nblocks; i++) {
            final int index = offset + (i << 4);
            long k1 = getLittleEndianLong(data, index);
            long k2 = getLittleEndianLong(data, index + 8);

            // mix functions for k1
            k1 *= C1;
            k1 = Long.rotateLeft(k1, R1);
            k1 *= C2;
            h1 ^= k1;
            h1 = Long.rotateLeft(h1, R2);
            h1 += h2;
            h1 = h1 * M + N1;

            // mix functions for k2
            k2 *= C2;
            k2 = Long.rotateLeft(k2, R3);
            k2 *= C1;
            h2 ^= k2;
            h2 = Long.rotateLeft(h2, R1);
            h2 += h1;
            h2 = h2 * M + N2;
        }

        // tail
        long k1 = 0;
        long k2 = 0;
        final int index = offset + (nblocks << 4);
        switch (offset + length - index) {
        case 15:
            k2 ^= ((long) data[index + 14] & 0xff) << 48;
        case 14:
            k2 ^= ((long) data[index + 13] & 0xff) << 40;
        case 13:
            k2 ^= ((long) data[index + 12] & 0xff) << 32;
        case 12:
            k2 ^= ((long) data[index + 11] & 0xff) << 24;
        case 11:
            k2 ^= ((long) data[index + 10] & 0xff) << 16;
        case 10:
            k2 ^= ((long) data[index + 9] & 0xff) << 8;
        case 9:
            k2 ^= data[index + 8] & 0xff;
            k2 *= C2;
            k2 = Long.rotateLeft(k2, R3);
            k2 *= C1;
            h2 ^= k2;

        case 8:
            k1 ^= ((long) data[index + 7] & 0xff) << 56;
        case 7:
            k1 ^= ((long) data[index + 6] & 0xff) << 48;
        case 6:
            k1 ^= ((long) data[index + 5] & 0xff) << 40;
        case 5:
            k1 ^= ((long) data[index + 4] & 0xff) << 32;
        case 4:
            k1 ^= ((long) data[index + 3] & 0xff) << 24;
        case 3:
            k1 ^= ((long) data[index + 2] & 0xff) << 16;
        case 2:
            k1 ^= ((long) data[index + 1] & 0xff) << 8;
        case 1:
            k1 ^= data[index] & 0xff;
            k1 *= C1;
            k1 = Long.rotateLeft(k1, R1);
            k1 *= C2;
            h1 ^= k1;
        }

        // finalization
        h1 ^= length;
        h2 ^= length;

        h1 += h2;
        h2 += h1;

        h1 = fmix64(h1);
        h2 = fmix64(h2);

        h1 += h2;
        h2 += h1;

        return new long[] { h1, h2 };
    }

    /**
     * Gets the little-endian long from 8 bytes starting at the specified index.
     *
     * @param data The data
     * @param index The index
     * @return The little-endian long
     */
    private static long getLittleEndianLong(final byte[] data, final int index) {
        return (((long) data[index    ] & 0xff)      ) |
               (((long) data[index + 1] & 0xff) <<  8) |
               (((long) data[index + 2] & 0xff) << 16) |
               (((long) data[index + 3] & 0xff) << 24) |
               (((long) data[index + 4] & 0xff) << 32) |
               (((long) data[index + 5] & 0xff) << 40) |
               (((long) data[index + 6] & 0xff) << 48) |
               (((long) data[index + 7] & 0xff) << 56);
    }

    /**
     * Gets the little-endian int from 4 bytes starting at the specified index.
     *
     * @param data The data
     * @param index The index
     * @return The little-endian int
     */
    private static int getLittleEndianInt(final byte[] data, final int index) {
        return ((data[index    ] & 0xff)      ) |
               ((data[index + 1] & 0xff) <<  8) |
               ((data[index + 2] & 0xff) << 16) |
               ((data[index + 3] & 0xff) << 24);
    }

    /**
     * Performs the intermediate mix step of the 32-bit hash function {@code MurmurHash3_x86_32}.
     *
     * @param k The data to add to the hash
     * @param hash The current hash
     * @return The new hash
     */
    private static int mix32(int k, int hash) {
        k *= C1_32;
        k = Integer.rotateLeft(k, R1_32);
        k *= C2_32;
        hash ^= k;
        return Integer.rotateLeft(hash, R2_32) * M_32 + N_32;
    }

    /**
     * Performs the final avalanche mix step of the 32-bit hash function {@code MurmurHash3_x86_32}.
     *
     * @param hash The current hash
     * @return The final hash
     */
    private static int fmix32(int hash) {
        hash ^= (hash >>> 16);
        hash *= 0x85ebca6b;
        hash ^= (hash >>> 13);
        hash *= 0xc2b2ae35;
        hash ^= (hash >>> 16);
        return hash;
    }

    /**
     * Performs the final avalanche mix step of the 64-bit hash function {@code MurmurHash3_x64_128}.
     *
     * @param hash The current hash
     * @return The final hash
     */
    private static long fmix64(long hash) {
        hash ^= (hash >>> 33);
        hash *= 0xff51afd7ed558ccdL;
        hash ^= (hash >>> 33);
        hash *= 0xc4ceb9fe1a85ec53L;
        hash ^= (hash >>> 33);
        return hash;
    }

    /**
     * Generates 32-bit hash from input bytes. Bytes can be added incrementally and the new
     * hash computed.
     *
     * <p>This is an implementation of the 32-bit hash function {@code MurmurHash3_x86_32}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * @since 1.14
     */
    public static class IncrementalHash32x86 {

        /** The size of byte blocks that are processed together. */
        private static final int BLOCK_SIZE = 4;

        /** Up to 3 unprocessed bytes from input data. */
        private final byte[] unprocessed = new byte[3];

        /** The number of unprocessed bytes in the tail data. */
        private int unprocessedLength;

        /** The total number of input bytes added since the start. */
        private int totalLen;

        /**
         * The current running hash.
         * This must be finalised to generate the 32-bit hash value.
         */
        private int hash;

        /**
         * Starts a new incremental hash.
         *
         * @param seed The initial seed value
         */
        public final void start(final int seed) {
            // Reset
            unprocessedLength = totalLen = 0;
            this.hash = seed;
        }

        /**
         * Adds the byte array to the current incremental hash.
         *
         * @param data The input byte array
         * @param offset The offset of data
         * @param length The length of array
         */
        public final void add(final byte[] data, final int offset, final int length) {
            if (length <= 0) {
                // Nothing to add
                return;
            }
            totalLen += length;

            // Process the bytes in blocks of 4.
            // New bytes must be added to any current unprocessed bytes,
            // then processed in blocks of 4 and the remaining bytes saved:
            //
            //    |--|---------------------------|--|
            // unprocessed
            //                main block
            //                                remaining

            // Check if the unprocessed bytes and new bytes can fill a block of 4.
            // Make this overflow safe in the event that length is Integer.MAX_VALUE.
            // Equivalent to: (unprocessedLength + length < BLOCK_SIZE)
            if (unprocessedLength + length - BLOCK_SIZE < 0) {
                // Not enough so add to the unprocessed bytes
                System.arraycopy(data, offset, unprocessed, unprocessedLength, length);
                unprocessedLength += length;
                return;
            }

            // Combine unprocessed bytes with new bytes.
            int newOffset;
            int newLength;
            if (unprocessedLength > 0) {
                int k = -1;
                switch (unprocessedLength) {
                case 1:
                    k = orBytes(unprocessed[0], data[offset], data[offset + 1], data[offset + 2]);
                    break;
                case 2:
                    k = orBytes(unprocessed[0], unprocessed[1], data[offset], data[offset + 1]);
                    break;
                case 3:
                    k = orBytes(unprocessed[0], unprocessed[1], unprocessed[2], data[offset]);
                    break;
                default:
                    throw new IllegalStateException("Unprocessed length should be 1, 2, or 3: " + unprocessedLength);
                }
                hash = mix32(k, hash);
                // Update the offset and length
                final int consumed = BLOCK_SIZE - unprocessedLength;
                newOffset = offset + consumed;
                newLength = length - consumed;
            } else {
                newOffset = offset;
                newLength = length;
            }

            // Main processing of blocks of 4 bytes
            final int nblocks = newLength >> 2;

            for (int i = 0; i < nblocks; i++) {
                final int index = newOffset + (i << 2);
                final int k = getLittleEndianInt(data, index);
                hash = mix32(k, hash);
            }

            // Save left-over unprocessed bytes
            final int consumed = (nblocks << 2);
            unprocessedLength = newLength - consumed;
            if (unprocessedLength != 0) {
                System.arraycopy(data, newOffset + consumed, unprocessed, 0, unprocessedLength);
            }
        }

        /**
         * Generate the 32-bit hash value. Repeat calls to this method with no additional data
         * will generate the same hash value.
         *
         * @return The 32-bit hash
         */
        public final int end() {
            // Allow calling end() again after adding no data to return the same result.
            return finalise(hash, unprocessedLength, unprocessed, totalLen);
        }

        /**
         * Finalize the running hash to the output 32-bit hash by processing remaining bytes
         * and performing final mixing.
         *
         * @param hash The running hash
         * @param unprocessedLength The number of unprocessed bytes in the tail data.
         * @param unprocessed Up to 3 unprocessed bytes from input data.
         * @param totalLen The total number of input bytes added since the start.
         * @return The 32-bit hash
         */
        int finalise(final int hash, final int unprocessedLength, final byte[] unprocessed, final int totalLen) {
            int result = hash;
            int k1 = 0;
            switch (unprocessedLength) {
            case 3:
                k1 ^= (unprocessed[2] & 0xff) << 16;
            case 2:
                k1 ^= (unprocessed[1] & 0xff) << 8;
            case 1:
                k1 ^= (unprocessed[0] & 0xff);

                // mix functions
                k1 *= C1_32;
                k1 = Integer.rotateLeft(k1, R1_32);
                k1 *= C2_32;
                result ^= k1;
            }

            // finalization
            result ^= totalLen;
            return fmix32(result);
        }

        /**
         * Combines the bytes using an Or operation ({@code | } in a little-endian representation
         * of a 32-bit integer; byte 1 will be the least significant byte, byte 4 the most
         * significant.
         *
         * @param b1 The first byte
         * @param b2 The second byte
         * @param b3 The third byte
         * @param b4 The fourth byte
         * @return The 32-bit integer
         */
        private static int orBytes(final byte b1, final byte b2, final byte b3, final byte b4) {
            return (b1 & 0xff) | ((b2 & 0xff) << 8) | ((b3 & 0xff) << 16) | ((b4 & 0xff) << 24);
        }
    }

    /**
     * Generates 32-bit hash from input bytes. Bytes can be added incrementally and the new
     * hash computed.
     *
     * <p>This is an implementation of the 32-bit hash function {@code MurmurHash3_x86_32}
     * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.</p>
     *
     * <p>This implementation contains a sign-extension bug in the finalization step of
     * any bytes left over from dividing the length by 4. This manifests if any of these
     * bytes are negative.<p>
     *
     * @deprecated Use IncrementalHash32x86. This corrects the processing of trailing bytes.
     */
    @Deprecated
    public static class IncrementalHash32 extends IncrementalHash32x86 {

        /**
         * {@inheritDoc}
         *
         * <p>This implementation contains a sign-extension bug in the finalization step of
         * any bytes left over from dividing the length by 4. This manifests if any of these
         * bytes are negative.<p>
         *
         * @deprecated Use IncrementalHash32x86. This corrects the processing of trailing bytes.
         */
        @Override
        @Deprecated
        int finalise(final int hash, final int unprocessedLength, final byte[] unprocessed, final int totalLen) {
            int result = hash;
            // ************
            // Note: This fails to apply masking using 0xff to the 3 remaining bytes.
            // ************
            int k1 = 0;
            switch (unprocessedLength) {
            case 3:
                k1 ^= unprocessed[2] << 16;
            case 2:
                k1 ^= unprocessed[1] << 8;
            case 1:
                k1 ^= unprocessed[0];

                // mix functions
                k1 *= C1_32;
                k1 = Integer.rotateLeft(k1, R1_32);
                k1 *= C2_32;
                result ^= k1;
            }

            // finalization
            result ^= totalLen;
            return fmix32(result);
        }
    }
}
