This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-codec.git
The following commit(s) were added to refs/heads/master by this push: new e772d31 [CODEC-273] Add Path APIs to org.apache.commons.codec.digest.DigestUtils similar to File APIs. e772d31 is described below commit e772d31a5d0db091bdb68d12b3c2fe79ba979bda Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Thu Dec 26 09:23:42 2019 -0500 [CODEC-273] Add Path APIs to org.apache.commons.codec.digest.DigestUtils similar to File APIs. --- pom.xml | 1 + src/changes/changes.xml | 1 + .../apache/commons/codec/digest/DigestUtils.java | 75 +++++++++++++++++++++- .../commons/codec/digest/DigestUtilsTest.java | 38 ++++++++--- .../codec/digest/MessageDigestAlgorithmsTest.java | 30 ++++++++- src/test/resources/empty.bin | 0 6 files changed, 134 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 43a17f5..3cfac9d 100644 --- a/pom.xml +++ b/pom.xml @@ -280,6 +280,7 @@ limitations under the License. <configuration> <excludes> <exclude>src/test/resources/bla.tar.xz</exclude> + <exclude>src/test/resources/empty.bin</exclude> </excludes> </configuration> </plugin> diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 7bcef52..d947376 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -52,6 +52,7 @@ The <action> type attribute can be add,update,fix,remove. <action issue="CODEC-267" dev="aherbert" due-to="Claude Warren" type="add">Add MurmurHash3.hash32x86 methods and IncrementalHash32x86 to fix sign extension error in hash32 methods.</action> <action issue="CODEC-269" dev="aherbert" type="fix">Allow repeat calls to MurmurHash3.IncrementalHash32.end() to generate the same value.</action> <action issue="CODEC-272" dev="ggregory" type="add" due-to="Behrang, Alex Herbert, Gary Gregory">Add RandomAccessFile digest methods #31.</action> + <action issue="CODEC-273" dev="ggregory" type="add" due-to="Gary Gregory">Add Path APIs to org.apache.commons.codec.digest.DigestUtils similar to File APIs.</action> </release> <release version="1.13" date="2019-07-20" description="Feature and fix release."> diff --git a/src/main/java/org/apache/commons/codec/digest/DigestUtils.java b/src/main/java/org/apache/commons/codec/digest/DigestUtils.java index da921d3..631306b 100644 --- a/src/main/java/org/apache/commons/codec/digest/DigestUtils.java +++ b/src/main/java/org/apache/commons/codec/digest/DigestUtils.java @@ -20,11 +20,14 @@ package org.apache.commons.codec.digest; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.RandomAccessFile; import java.io.IOException; import java.io.InputStream; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -118,6 +121,24 @@ public class DigestUtils { } /** + * Reads through a File and returns the digest for the data + * + * @param messageDigest + * The MessageDigest to use (e.g. MD5) + * @param data + * Data to digest + * @param options + * options How to open the file + * @return the digest + * @throws IOException + * On error reading from the stream + * @since 1.14 + */ + public static byte[] digest(final MessageDigest messageDigest, final Path data, final OpenOption... options) throws IOException { + return updateDigest(messageDigest, data, options).digest(); + } + + /** * Reads through a RandomAccessFile using non-blocking-io (NIO) and returns the digest for the data * * @param messageDigest The MessageDigest to use (e.g. MD5) @@ -1267,6 +1288,26 @@ public class DigestUtils { return digest; } + /** + * Reads through a Path and updates the digest for the data + * + * @param digest + * The MessageDigest to use (e.g. MD5) + * @param path + * Data to digest + * @param options + * options How to open the file + * @return the digest + * @throws IOException + * On error reading from the stream + * @since 1.14 + */ + public static MessageDigest updateDigest(final MessageDigest digest, final Path path, final OpenOption... options) throws IOException { + try (final BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(path, options))) { + return updateDigest(digest, inputStream); + } + } + /** * Reads through a RandomAccessFile and updates the digest for the data using non-blocking-io (NIO) @@ -1398,6 +1439,22 @@ public class DigestUtils { } /** + * Reads through a File and returns the digest for the data + * + * @param data + * Data to digest + * @param options + * options How to open the file + * @return the digest + * @throws IOException + * On error reading from the stream + * @since 1.14 + */ + public byte[] digest(final Path data, final OpenOption... options) throws IOException { + return updateDigest(messageDigest, data, options).digest(); + } + + /** * Reads through a byte array and returns the digest for the data. * * @param data @@ -1449,6 +1506,22 @@ public class DigestUtils { } /** + * Reads through a File and returns the digest for the data + * + * @param data + * Data to digest + * @param options + * options How to open the file + * @return the digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.11 + */ + public String digestAsHex(final Path data, final OpenOption... options) throws IOException { + return Hex.encodeHexString(digest(data, options)); + } + + /** * Reads through an InputStream and returns the digest for the data * * @param data diff --git a/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java b/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java index 906d245..c5002be 100644 --- a/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java +++ b/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java @@ -26,6 +26,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.MessageDigest; import java.util.Random; @@ -44,6 +46,8 @@ import org.junit.Test; */ public class DigestUtilsTest { + private static final String EMPTY_STRING = ""; + private final byte[] testData = new byte[1024 * 1024]; private File testFile; @@ -68,6 +72,10 @@ public class DigestUtilsTest { return testFile; } + Path getTestPath() { + return testFile.toPath(); + } + RandomAccessFile getTestRandomAccessFile() { return testRandomAccessFileWrapper; } @@ -106,7 +114,7 @@ public class DigestUtilsTest { @Test public void testMd2Hex() throws IOException { // Examples from RFC 1319 - assertEquals("8350e5a3e24c153df2275c9f80692773", DigestUtils.md2Hex("")); + assertEquals("8350e5a3e24c153df2275c9f80692773", DigestUtils.md2Hex(EMPTY_STRING)); assertEquals("32ec01ec4a6dac72c0ab96fb34c0b5d1", DigestUtils.md2Hex("a")); @@ -159,7 +167,7 @@ public class DigestUtilsTest { @Test public void testMd5Hex() throws IOException { // Examples from RFC 1321 - assertEquals("d41d8cd98f00b204e9800998ecf8427e", DigestUtils.md5Hex("")); + assertEquals("d41d8cd98f00b204e9800998ecf8427e", DigestUtils.md5Hex(EMPTY_STRING)); assertEquals("0cc175b9c0f1b6a831c399e269772661", DigestUtils.md5Hex("a")); @@ -278,10 +286,10 @@ public class DigestUtilsTest { } @Test - public void testSha224() { + public void testSha224_StringAsHex() { assumeJava8(); assertEquals("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", - new DigestUtils(MessageDigestAlgorithms.SHA_224).digestAsHex((""))); + new DigestUtils(MessageDigestAlgorithms.SHA_224).digestAsHex(EMPTY_STRING)); assertEquals("730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", new DigestUtils(MessageDigestAlgorithms.SHA_224).digestAsHex("The quick brown fox jumps over the lazy dog")); @@ -289,6 +297,20 @@ public class DigestUtilsTest { } @Test + public void testSha224_FileAsHex() throws IOException { + assumeJava8(); + assertEquals("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", + new DigestUtils(MessageDigestAlgorithms.SHA_224).digestAsHex(new File("src/test/resources/empty.bin"))); + } + + @Test + public void testSha224_PathAsHex() throws IOException { + assumeJava8(); + assertEquals("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", + new DigestUtils(MessageDigestAlgorithms.SHA_224).digestAsHex(Paths.get("src/test/resources/empty.bin"))); + } + + @Test public void testSha256() throws IOException { // Examples from FIPS 180-2 assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", @@ -342,7 +364,7 @@ public class DigestUtilsTest { // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-224_Msg0.pdf assertEquals( "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", - DigestUtils.sha3_224Hex("")); + DigestUtils.sha3_224Hex(EMPTY_STRING)); } @Test @@ -353,7 +375,7 @@ public class DigestUtilsTest { // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-256_Msg0.pdf assertEquals( "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", - DigestUtils.sha3_256Hex("")); + DigestUtils.sha3_256Hex(EMPTY_STRING)); } @Test @@ -364,7 +386,7 @@ public class DigestUtilsTest { // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-384_Msg0.pdf assertEquals( "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", - DigestUtils.sha3_384Hex("")); + DigestUtils.sha3_384Hex(EMPTY_STRING)); } @Test @@ -375,7 +397,7 @@ public class DigestUtilsTest { // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-512_Msg0.pdf assertEquals( "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", - DigestUtils.sha3_512Hex("")); + DigestUtils.sha3_512Hex(EMPTY_STRING)); } @Test diff --git a/src/test/java/org/apache/commons/codec/digest/MessageDigestAlgorithmsTest.java b/src/test/java/org/apache/commons/codec/digest/MessageDigestAlgorithmsTest.java index f1b7295..03db8c5 100644 --- a/src/test/java/org/apache/commons/codec/digest/MessageDigestAlgorithmsTest.java +++ b/src/test/java/org/apache/commons/codec/digest/MessageDigestAlgorithmsTest.java @@ -23,6 +23,9 @@ import java.io.RandomAccessFile; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.nio.ByteBuffer; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -107,6 +110,10 @@ public class MessageDigestAlgorithmsTest { return digestUtilsTest.getTestFile(); } + private Path getTestPath() { + return digestUtilsTest.getTestPath(); + } + private RandomAccessFile getTestRandomAccessFile() { return digestUtilsTest.getTestRandomAccessFile(); } @@ -152,8 +159,9 @@ public class MessageDigestAlgorithmsTest { public void testDigestFile() throws IOException { Assume.assumeTrue(DigestUtils.isAvailable(messageDigestAlgorithm)); Assert.assertArrayEquals(digestTestData(), - DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm), getTestFile())); - Assert.assertArrayEquals(digestTestData(), DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm),getTestFile())); + DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm), getTestFile())); + Assert.assertArrayEquals(digestTestData(), + DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm), getTestFile())); } @Test @@ -164,6 +172,24 @@ public class MessageDigestAlgorithmsTest { Assert.assertArrayEquals(digestTestData(), DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm),new ByteArrayInputStream(getTestData()))); } + private void testDigestPath(OpenOption... options) throws IOException { + Assume.assumeTrue(DigestUtils.isAvailable(messageDigestAlgorithm)); + Assert.assertArrayEquals(digestTestData(), + DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm), getTestPath(), options)); + Assert.assertArrayEquals(digestTestData(), + DigestUtils.digest(DigestUtils.getDigest(messageDigestAlgorithm), getTestPath(), options)); + } + + @Test + public void testDigestPathOpenOptionsEmpty() throws IOException { + testDigestPath(); + } + + @Test + public void testDigestPathStandardOpenOptionRead() throws IOException { + testDigestPath(StandardOpenOption.READ); + } + @Test public void testGetMessageDigest() { Assume.assumeTrue(DigestUtils.isAvailable(messageDigestAlgorithm)); diff --git a/src/test/resources/empty.bin b/src/test/resources/empty.bin new file mode 100644 index 0000000..e69de29