gov.sandia.cognition.hash.Prime64Hash Maven / Gradle / Ivy
/*
* File: Prime64Hash.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Feb 10, 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.util.ObjectUtil;
/**
* Implementation of the prime-hash function using 64-bit (8-byte) precision.
* This hash function is similar to the one Java uses, but it has very bad
* properties and should only be used for benchmarking.
* @author Kevin R. Dixon
* @since 3.4.2
*/
public class Prime64Hash
extends AbstractHashFunction
{
/**
* Default prime number, {@value}.
*/
private static final long DEFAULT_PRIME = 31;
/**
* Length of the hash is 64 bits (8 bytes), {@value}.
*/
public static final int LENGTH = 8;
/**
* Default seed, the first seed from the SHA-2 512-bit hash.
*/
protected static final byte[] DEFAULT_SEED = {
(byte)0x6a, (byte)0x09, (byte)0xe6, (byte)0x67, (byte)0xf3, (byte)0xbc, (byte)0xc9, (byte)0x08
};
/**
* Creates a new instance of Prime64Hash
*/
public Prime64Hash()
{
}
@Override
public Prime64Hash clone()
{
return (Prime64Hash) super.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)
{
if( seed.length != LENGTH )
{
throw new IllegalArgumentException(
"Expected seed to be of length: " + LENGTH );
}
final long hash = hash( input, HashFunctionUtil.toLong(seed) );
HashFunctionUtil.toByteArray( hash, output );
}
/**
* Computes the prime-number hash of the given input, prime number, and seed
* @param input
* Input to hash
* @return
* 64-bit hash code of the input
*/
public static long hash(
byte[] input )
{
long seed = HashFunctionUtil.toLong(DEFAULT_SEED);
return hash( input, seed );
}
/**
* Computes the prime-number hash of the given input, prime number, and seed
* @param input
* Input to hash
* @param seed
* Seed to start the hash process
* @return
* 64-bit hash code of the input
*/
public static long hash(
byte[] input,
long seed )
{
return hash( input, DEFAULT_PRIME, seed );
}
/**
* Computes the prime-number hash of the given input, prime number, and seed
* @param input
* Input to hash
* @param prime
* Prime number to recursively multiply the input
* @param seed
* Seed to start the hash process
* @return
* 64-bit hash code of the input
*/
public static long hash(
byte[] input,
long prime,
long seed )
{
if( input == null )
{
return 0;
}
if( prime == 0 )
{
throw new IllegalArgumentException(
"Prime cannot be 0" );
}
long result = seed;
final int length = input.length;
for( int i = 0; i < length; i++ )
{
result = (result * prime) + input[i];
}
return result;
}
}