Skip to content

Commit f98eb36

Browse files
committed
Add hash feature
1 parent 4e3d49a commit f98eb36

File tree

5 files changed

+76
-1
lines changed

5 files changed

+76
-1
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## v0.4.1
44

55
* add bitAt() utility
6+
* add hash feature
67

78
## v0.4.0
89

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ to blindly paste code snippets from
3232
It's main features include:
3333

3434
* **Creation** from a wide variety of sources: multiple arrays, integers, streams, random, strings, files, ...
35-
* **Transformation** with many built-in: append, xor, and, or, shifts, shuffle, reverse, sort, ...
35+
* **Transformation** with many built-in: append, xor, and, hash, shifts, shuffle, reverse, sort, ...
3636
* **Validators** with the ability to arbitrarily combine multiple ones with logical expressions
3737
* **Parsing and Encoding** in most common binary-to-text-encodings: [hex](https://en.wikipedia.org/wiki/Hexadecimal), [base64](https://en.wikipedia.org/wiki/Base64), ...
3838
* **Immutable, Mutable and Read-Only** versions
@@ -194,6 +194,13 @@ Bytes copy = Bytes.wrap(array).copy(3, 17); //copy partial array
194194
Bytes resized = Bytes.wrap(array).resize(3); //from {3, 9, 2, 1} to {9, 2, 1}
195195
```
196196

197+
**Hashing** the internal byte array using the [`MessageDigest`](https://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html) Java crypto API:
198+
199+
```java
200+
Bytes hash = Bytes.wrap(array).sha256();
201+
Bytes hash = Bytes.wrap(array).hash("MD5");
202+
```
203+
197204
Other transformers:
198205

199206
```java

src/main/java/at/favre/lib/bytes/Bytes.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,41 @@ public Bytes resize(int newByteLength) {
782782
return transform(new BytesTransformer.ResizeTransformer(newByteLength));
783783
}
784784

785+
786+
/**
787+
* Calculates sha256 on the underlying byte array and returns a byte instance containing the hash.
788+
*
789+
* @return sha256 (32 bytes) hash of internal byte array
790+
* @throws IllegalArgumentException if the message digest algorithm can not be found in the security providers
791+
* @see <a href="https://en.wikipedia.org/wiki/Secure_Hash_Algorithms">Secure Hash Algorithms</a>
792+
*/
793+
public Bytes hashSha256() {
794+
return hash(BytesTransformer.MessageDigestTransformer.ALGORITHM_SHA_256);
795+
}
796+
797+
/**
798+
* Calculates sha512 on the underlying byte array and returns a byte instance containing the hash.
799+
*
800+
* @return sha512 hash (64 bytes) of internal byte array
801+
* @throws IllegalArgumentException if the message digest algorithm can not be found in the security providers
802+
* @see <a href="https://en.wikipedia.org/wiki/Secure_Hash_Algorithms">Secure Hash Algorithms</a>
803+
*/
804+
public Bytes hashSha512() {
805+
return hash(BytesTransformer.MessageDigestTransformer.ALGORITHM_SHA_512);
806+
}
807+
808+
/**
809+
* Calculates hash with provided algorithm on the underlying byte array and returns a byte instance
810+
* containing the hash.
811+
*
812+
* @param algorithm same format as passed to {@link java.security.MessageDigest#getInstance(String)}
813+
* @return hash of internal byte array
814+
* @throws IllegalArgumentException if the message digest algorithm can not be found in the security providers
815+
*/
816+
public Bytes hash(String algorithm) {
817+
return transform(new BytesTransformer.MessageDigestTransformer(algorithm));
818+
}
819+
785820
/**
786821
* Generic transformation of this instance.
787822
* <p>

src/main/java/at/favre/lib/bytes/BytesTransformer.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
package at.favre.lib.bytes;
2323

2424
import java.math.BigInteger;
25+
import java.security.MessageDigest;
26+
import java.security.NoSuchAlgorithmException;
2527
import java.util.*;
2628

2729
/**
@@ -314,4 +316,28 @@ public byte[] transform(byte[] currentArray, boolean inPlace) {
314316
return out;
315317
}
316318
}
319+
320+
/**
321+
* Converts to hash
322+
*/
323+
class MessageDigestTransformer implements BytesTransformer {
324+
final static String ALGORITHM_SHA_256 = "SHA-256";
325+
final static String ALGORITHM_SHA_512 = "SHA-512";
326+
327+
private final MessageDigest messageDigest;
328+
329+
MessageDigestTransformer(String digestName) {
330+
try {
331+
this.messageDigest = MessageDigest.getInstance(digestName);
332+
} catch (NoSuchAlgorithmException e) {
333+
throw new IllegalArgumentException("could not get message digest algorithm " + digestName, e);
334+
}
335+
}
336+
337+
@Override
338+
public byte[] transform(byte[] currentArray, boolean inPlace) {
339+
messageDigest.update(currentArray);
340+
return messageDigest.digest();
341+
}
342+
}
317343
}

src/test/java/at/favre/lib/bytes/BytesTransformTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ public void bitSwitchOutOfBounds() throws Exception {
266266
Bytes.from(4).switchBit(32, true);
267267
}
268268

269+
@Test
270+
public void hash() throws Exception {
271+
assertEquals(Bytes.parseHex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), Bytes.from("").hashSha256());
272+
assertEquals(Bytes.parseHex("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), Bytes.from("").hashSha512());
273+
}
274+
269275
@Test
270276
public void transform() throws Exception {
271277
assertArrayEquals(example_bytes_two, Bytes.from(example_bytes_two).transform(new BytesTransformer() {

0 commit comments

Comments
 (0)