All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.hash.Eva64Hash Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                Eva64Hash.java
 * Authors:             Kevin R. Dixon
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 *
 * Copyright Jan 26, 2011, Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the U.S. Government.
 * Export of this program may require a license from the United States
 * Government. See CopyrightHistory.txt for complete details.
 *
 */
package gov.sandia.cognition.hash;

import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.util.ObjectUtil;

/**
 * This implements the 64-bit "evahash" due to Robert Jenkins.  This is a Java
 * port of Jenkins's C implementation.
 * @author Kevin R. Dixon
 * @since  3.4.2
 */
@PublicationReference(
    author="Robert J. Jenkins, Jr.",
    title="Hash Functions for Hash Table Lookup",
    type=PublicationType.WebPage,
    year=1997,
    url="http://burtleburtle.net/bob/hash/evahash.html"
)
public class Eva64Hash 
    extends AbstractHashFunction
{

    /**
     * Length of the hash in bytes, {@value}.
     */
    public static final int LENGTH = 8;

    /**
     * Default seed: ( 0, 0, 0, 0, 0, 0, 0, 0 ).
     */
    protected static final byte[] DEFAULT_SEED = HashFunctionUtil.toByteArray(0L);

    /** 
     * Creates a new instance of Eva64Hash 
     */
    public Eva64Hash()
    {
        super();
    }

    @Override
    public Eva64Hash clone()
    {
        Eva64Hash clone = (Eva64Hash) super.clone();
        return clone;
    }

    @Override
    public int length()
    {
        return LENGTH;
    }

    @Override
    public byte[] getDefaultSeed()
    {
        return ObjectUtil.deepCopy(DEFAULT_SEED);
    }

    @Override
    public void evaluateInto(
        byte[] input,
        byte[] output,
        byte[] seed)
    {
        long result = hash( input, HashFunctionUtil.toLong(seed) );
        HashFunctionUtil.toByteArray(result, output);
    }

    /**
     * Computes the Eva64Hash of the given input and the seed
     * @param input
     * Input to consider
     * @param seed
     * Seed to offset the hash
     * @return
     * long representing the 64-bit hash function
     */
    public static long hash(
        byte[] input,
        long seed )
    {

        // First calculate the first part by hashing the string from the given
        // initial value.
        final int part1 = Eva32Hash.hash( input, (int) seed );

        // Now calculate another part using the first part as the initial value.
        final int part2 = Eva32Hash.hash( input, part1 );

        // Finally combine them. Note: While it may make more sense to have
        // part1 as the high 32 bits, part2 is the high 32 bits because of how
        // the 64-bit hash code is created in the C code.
        return ((part2 & 0xFFFFFFFFL) << 32)
            +  ((part1 & 0xFFFFFFFFL));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy