package com.zackehh.siphash; import static com.zackehh.siphash.SipHashConstants.DEFAULT_C; import static com.zackehh.siphash.SipHashConstants.DEFAULT_D; import static com.zackehh.siphash.SipHashConstants.INITIAL_V0; import static com.zackehh.siphash.SipHashConstants.INITIAL_V1; import static com.zackehh.siphash.SipHashConstants.INITIAL_V2; import static com.zackehh.siphash.SipHashConstants.INITIAL_V3; /** * Main entry point for SipHash, providing a basic hash * interface. Assuming you have your full String to hash, * you can simply provide it to ${@link SipHash#hash(byte[])}. * * This class can be initialized and stored in case the * developer wishes to use the same key over and over again. * * This avoids the overhead of having to create the initial * key over and over again. * *
 * {@code
 * List inputs = Arrays.asList("input1", "input2", "input3");
 * SipHash hasher = new SipHash("this key is mine".getBytes());
 * for (int i = 0; i < inputs.size(); i++) {
 *     hasher.hash(inputs.get(i));
 * }
 * }
 * 
*/ public class SipHash { /** * The values of SipHash-c-d, to determine which of the SipHash * family we're using for this hash. */ private final int c, d; /** * Initial seeded value of v0. */ private final long v0; /** * Initial seeded value of v1. */ private final long v1; /** * Initial seeded value of v2. */ private final long v2; /** * Initial seeded value of v3. */ private final long v3; /** * Accepts a 16 byte key input, and uses it to initialize * the state of the hash. This uses the default values of * c/d, meaning that we default to SipHash-2-4. * * @param key a 16 byte key input */ public SipHash(byte[] key){ this(key, DEFAULT_C, DEFAULT_D); } /** * Accepts a 16 byte key input, and uses it to initialize * the state of the hash. This constructor allows for * providing the c/d values, allowing the developer to * select any of the SipHash family to use for hashing. * * @param key a 16 byte key input * @param c the number of compression rounds * @param d the number of finalization rounds */ public SipHash(byte[] key, int c, int d){ this.c = c; this.d = d; SipHashKey hashKey = new SipHashKey(key); this.v0 = (INITIAL_V0 ^ hashKey.k0); this.v1 = (INITIAL_V1 ^ hashKey.k1); this.v2 = (INITIAL_V2 ^ hashKey.k0); this.v3 = (INITIAL_V3 ^ hashKey.k1); } /** * The basic hash implementation provided in the library. * Assuming you have your full input, you can provide it and * it will be hashed based on the values which were provided * to the constructor of this class. * * @param data the bytes to hash * @return a ${@link SipHashResult} instance */ public SipHashResult hash(byte[] data) { SipHashDigest digest = new SipHashDigest(v0, v1, v2, v3, c, d); for (byte aData : data) { digest.update(aData); } return digest.finish(); } }