/*
* File: HashFunctionUtilTest.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 java.io.UnsupportedEncodingException;
import java.util.Arrays;
import junit.framework.TestCase;
import java.util.Random;
/**
* Unit tests for HashFunctionUtilTest.
*
* @author krdixon
*/
public class HashFunctionUtilTest
extends TestCase
{
/**
* Random number generator to use for a fixed random seed.
*/
public final Random RANDOM = new Random( 1 );
/**
* Default tolerance of the regression tests, {@value}.
*/
public final double TOLERANCE = 1e-5;
/**
* Number of samples to draw, {@value}.
*/
public final int NUM_SAMPLES = 10;
/**
* Tests for class HashFunctionUtilTest.
* @param testName Name of the test.
*/
public HashFunctionUtilTest(
String testName)
{
super(testName);
}
/**
* Tests the constructors of class HashFunctionUtilTest.
*/
public void testConstructors()
{
System.out.println( "Constructors" );
HashFunctionUtil instance = new HashFunctionUtil();
assertNotNull( instance );
}
/**
* Test of toByteArray method, of class HashFunctionUtil.
*/
public void testToByteArray_int()
{
System.out.println("toByteArray");
int value = 0;
for( int n = 0; n < NUM_SAMPLES; n++ )
{
value = RANDOM.nextInt();
byte[] r1 = HashFunctionUtil.toByteArray(value);
assertEquals( 4, r1.length );
byte[] r2 = new byte[4];
HashFunctionUtil.toByteArray(value,r2);
assertTrue( HashFunctionTestHarness.byteArrayEquals(r1, r2) );
assertEquals( (byte) (0xff & (value >>> 24)), r1[0] );
assertEquals( (byte) (0xff & (value >>> 16)), r1[1] );
assertEquals( (byte) (0xff & (value >>> 8)), r1[2] );
assertEquals( (byte) (0xff & (value) ), r1[3] );
}
byte[] output = new byte[5];
try
{
HashFunctionUtil.toByteArray(value, output);
fail( "Input length must be 4" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
output = new byte[3];
try
{
HashFunctionUtil.toByteArray(value, output);
fail( "Input length must be 4" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* Test of toByteArray method, of class HashFunctionUtil.
*/
public void testToByteArray_long()
{
System.out.println("toByteArray");
long value = 0L;
for( int n = 0; n < NUM_SAMPLES; n++ )
{
value = RANDOM.nextLong();
byte[] r1 = HashFunctionUtil.toByteArray(value);
assertEquals( 8, r1.length );
byte[] r2 = new byte[8];
HashFunctionUtil.toByteArray(value, r2);
assertTrue( HashFunctionTestHarness.byteArrayEquals(r1, r2) );
assertEquals( (byte) (0xff & (value >>> 56)), r1[0] );
assertEquals( (byte) (0xff & (value >>> 48)), r1[1] );
assertEquals( (byte) (0xff & (value >>> 40)), r1[2] );
assertEquals( (byte) (0xff & (value >>> 32)), r1[3] );
assertEquals( (byte) (0xff & (value >>> 24)), r1[4] );
assertEquals( (byte) (0xff & (value >>> 16)), r1[5] );
assertEquals( (byte) (0xff & (value >>> 8)), r1[6] );
assertEquals( (byte) (0xff & (value) ), r1[7] );
}
byte[] output = new byte[7];
try
{
HashFunctionUtil.toByteArray(value, output);
fail( "Input length must be 8" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
output = new byte[9];
try
{
HashFunctionUtil.toByteArray(value, output);
fail( "Input length must be 8" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* Test of combineHash method, of class HashFunctionUtil.
*/
public void testCombineHash()
{
System.out.println("combineHash");
HashFunction hash = new Eva64Hash();
byte[] x1 = new byte[ 100 ];
RANDOM.nextBytes(x1);
byte[] x2 = new byte[ 10 ];
RANDOM.nextBytes(x2);
boolean ordered = false;
byte[] r12 = HashFunctionUtil.combineHash(hash, ordered, x1, x2 );
byte[] r21 = HashFunctionUtil.combineHash(hash, ordered, x2, x1 );
System.out.println( "Unordered12: " + HashFunctionUtil.toHexString(r12) );
System.out.println( "Unordered21: " + HashFunctionUtil.toHexString(r21) );
assertEquals( HashFunctionUtil.toHexString(r12),
HashFunctionUtil.toHexString(r21) );
ordered = true;
byte[] o12 = HashFunctionUtil.combineHash(hash, ordered, x1, x2 );
byte[] o21 = HashFunctionUtil.combineHash(hash, ordered, x2, x1 );
System.out.println( "Ordered12: " + HashFunctionUtil.toHexString(o12) );
System.out.println( "Ordered21: " + HashFunctionUtil.toHexString(o21) );
assertFalse( HashFunctionUtil.toHexString(r12).equals(
HashFunctionUtil.toHexString(o12) ) );
assertFalse( HashFunctionUtil.toHexString(r21).equals(
HashFunctionUtil.toHexString(o21) ) );
assertFalse( HashFunctionUtil.toHexString(o12).equals(
HashFunctionUtil.toHexString(o21) ) );
}
/**
* Test of toHexString method, of class HashFunctionUtil.
*/
public void testToHexString()
{
System.out.println("toHexString");
byte[] bytes = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF };
String result = HashFunctionUtil.toHexString(bytes);
System.out.println( "Bytes: " + result );
assertEquals( "0123456789abcdef", result );
}
/**
* toInteger
*/
public void testToInteger()
{
System.out.println( "toInteger" );
for( int n = 0; n < NUM_SAMPLES; n++ )
{
int x = RANDOM.nextInt();
byte[] b = HashFunctionUtil.toByteArray(x);
int y = HashFunctionUtil.toInteger(b);
assertEquals( x, y );
}
byte[] badb = new byte[ 5 ];
try
{
HashFunctionUtil.toInteger(badb);
fail( "Wrong length!" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
assertEquals( 0, HashFunctionUtil.toInteger(badb,0) );
assertEquals( 0, HashFunctionUtil.toInteger(badb,1) );
try
{
HashFunctionUtil.toInteger(badb, 2);
fail( "Out of bounds" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* toLong
*/
public void testToLong()
{
System.out.println( "toLong" );
for( int n = 0; n < NUM_SAMPLES; n++ )
{
long x = RANDOM.nextLong();
byte[] b = HashFunctionUtil.toByteArray(x);
long y = HashFunctionUtil.toLong(b);
assertEquals( x, y );
}
byte[] badb = new byte[ 9 ];
try
{
HashFunctionUtil.toLong(badb);
fail( "Wrong length!" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
assertEquals( 0, HashFunctionUtil.toLong(badb,0) );
assertEquals( 0, HashFunctionUtil.toLong(badb,1) );
try
{
HashFunctionUtil.toLong(badb, 2);
fail( "Out of bounds" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* toHexString(int)
*/
public void testToHexStringInt()
{
System.out.println( "toHexString" );
for( int i = 0; i < NUM_SAMPLES; i++ )
{
int value = RANDOM.nextInt();
assertEquals( HashFunctionUtil.toHexString( HashFunctionUtil.toByteArray(value)),
HashFunctionUtil.toHexString(value) );
}
}
/**
* toHexString(long)
*/
public void testToHexStringLong()
{
System.out.println( "toHexString" );
for( int i = 0; i < NUM_SAMPLES; i++ )
{
long value = RANDOM.nextInt();
assertEquals( HashFunctionUtil.toHexString( HashFunctionUtil.toByteArray(value)),
HashFunctionUtil.toHexString(value) );
}
}
/**
* salt
* @throws UnsupportedEncodingException
*/
public void testSalt()
throws UnsupportedEncodingException
{
System.out.println( "salt" );
// These are salts/passwords from the Sun hack... just checking.
String salt = "drogers";
String password = "magnet";
String expected = "83437c10ac27a63caedfdcb871ae693b";
HashFunction hash = new MD5Hash();
String result = HashFunctionUtil.toHexString(HashFunctionUtil.salt(hash, salt.getBytes("UTF-8"), password.getBytes("UTF-8") ));
assertEquals( expected, result );
salt = "jcampbell";
password = "grape";
expected = "ba8d1d9740ab78e5e7f3541f71a6bbdd";
result = HashFunctionUtil.toHexString(HashFunctionUtil.salt(hash, salt.getBytes("UTF-8"), password.getBytes("UTF-8") ));
assertEquals( expected, result );
salt = "rebekah";
password = "63000";
expected = "62dd0bd92bf4fafae73c531ee5108c77";
result = HashFunctionUtil.toHexString(HashFunctionUtil.salt(hash, salt.getBytes("UTF-8"), password.getBytes("UTF-8") ));
assertEquals( expected, result );
}
public void testFromHexString()
{
System.out.println( "fromHexString" );
byte[] b1 = SHA1Hash.hash( "hello".getBytes() );
String h1 = HashFunctionUtil.toHexString(b1);
byte[] r1 = HashFunctionUtil.fromHexString(h1);
String j1 = HashFunctionUtil.toHexString(r1);
assertEquals( h1, j1 );
assertTrue( Arrays.equals(b1, r1) );
}
public void testIsPrime()
{
System.out.println( "isPrime" );
long[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181,
191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337,
347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587,
593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
941, 947, 953, 967, 971, 977, 983, 991, 997 };
for( int i = 0; i < primes.length; i++ )
{
assertTrue( HashFunctionUtil.isPrime( primes[i] ) );
}
for( int i = 0; i < NUM_SAMPLES; i++ )
{
boolean keepGoing = true;
long num = 0;
while( keepGoing )
{
num = Math.abs(RANDOM.nextLong()) % primes[primes.length-1];
keepGoing = false;
for( int j = 0; j < primes.length; j++ )
{
if( num == primes[j] )
{
keepGoing = true;
break;
}
}
}
assertFalse( num + " is not prime!", HashFunctionUtil.isPrime(num) );
}
}
public void testNextPrime()
{
System.out.println( "nextPrime" );
for( int i = 0; i < NUM_SAMPLES; i++ )
{
long value = Math.abs(RANDOM.nextLong()) % 10000;
long next = HashFunctionUtil.nextPrime(value);
assertTrue( HashFunctionUtil.isPrime(next) );
for( long j = value; j < next; j++ )
{
assertFalse( HashFunctionUtil.isPrime(j) );
}
}
}
}