# SipHash [![Build Status](https://travis-ci.org/zackehh/siphash-java.svg?branch=master)](https://travis-ci.org/zackehh/siphash-java) [![Coverage Status](https://coveralls.io/repos/zackehh/siphash-java/badge.svg?branch=master&service=github)](https://coveralls.io/github/zackehh/siphash-java?branch=master) A Java implementation of the SipHash cryptographic hash family. Supports any variation, although defaults to the widely used SipHash-2-4. Can be used with either full input, or used as a streaming digest. This library was heavily influenced by [veorq's C implementation](https://github.com/veorq/siphash) and [Forward C&C's reference implementation](http://www.forward.com.au/pfod/SipHashJavaLibrary/) - I just decided it was time a Java implementation of SipHash made it onto Maven :). ## Setup `siphash` is available on Maven central, via Sonatype OSS: ``` com.zackehh siphash 1.0.0 ``` ## Usage There are two ways of using SipHash (see below). Both return a `SipHashResult` which can be used to retrieve the result in various forms. All constructors can take arguments to specify the compression rounds. For further usage, please visit the [documentation](http://www.javadoc.io/doc/com.zackehh/siphash). #### Full Input Hash The first is to simple create a `SipHash` instance and use it to repeatedly hash using the same key. The internal state is immutable, so you can hash many inputs without having to recreate a new `SipHash` instance (unless you want a new key). ```java SipHash hasher = new SipHash("0123456789ABCDEF".getBytes()); SipHashResult result = hasher.hash("my-input".getBytes()); System.out.println(result.get()); // 182795880124085484 <-- this can overflow System.out.println(result.getHex()); // "2896be26d3374ec" System.out.println(result.getHex(true)); // "02896be26d3374ec" System.out.println(result.getHex(SipHashCase.UPPER)); // "2896BE26D3374EC" System.out.println(result.getHex(true, SipHashCase.UPPER)); // "02896BE26D3374EC" ``` #### Streaming Hash The second is to use the library as a streaming hash, meaning you can apply chunks of bytes to the hash as they become available. Using this method you must create a new digest every time you want to hash a different input as the internal state is mutable. ```java SipHashDigest digest = new SipHashDigest("0123456789ABCDEF".getBytes()); digest.update("chu".getBytes()); digest.update("nked".getBytes()); digest.update(" string".getBytes()); SipHashResult result = digest.finish(); System.out.println(result.get()); // 3502906798476177428 <-- this can overflow System.out.println(result.getHex()); // "309cd32c8c793014" System.out.println(result.getHex(true)); // "309cd32c8c793014" System.out.println(result.getHex(SipHashCase.UPPER)); // "309CD32C8C793014" System.out.println(result.getHex(true, SipHashCase.UPPER)); // "309CD32C8C793014" ``` ## Contributing If you wish to contribute (awesome!), please file an issue first! All PRs should pass `mvn clean verify` and maintain 100% test coverage. ## Testing Tests are run using `mvn`. I aim to maintain 100% coverage where possible (both line and branch). Tests can be run as follows: ```bash $ mvn clean verify ```