Skip to content

Commit 625cedf

Browse files
author
Gary Gregory
committed
[CODEC-272] Add RandomAccessFile digest methods #31.
- This is a slightly different version from #31 - Refactor updateDigest(MessageDigest,RandomAccessFile) into an new private updateDigest(MessageDigest,FileChannel) as possible public candidate. - Do NOT seek to 0 on a RandomAccessFile before calling updateDigest(): We do not do this for ByteBuffer input, so do not do it here and be consistent to assume that when the caller says 'digest this' then do it from where the input stands (like a stream). - Add methods in the file to keep methods in alphabetical order. - Closes #31.
1 parent 3ab9ce4 commit 625cedf

4 files changed

Lines changed: 199 additions & 104 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The <action> type attribute can be add,update,fix,remove.
4949
<action issue="CODEC-264" dev="aherbert" due-to="Claude Warren" type="add">Add MurmurHash3.hash128x64 methods to fix sign extension error during seeding in hash128 methods.</action>
5050
<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>
5151
<action issue="CODEC-269" dev="aherbert" type="fix">Allow repeat calls to MurmurHash3.IncrementalHash32.end() to generate the same value.</action>
52+
<action issue="CODEC-272" dev="ggregory" type="add" due-to="Behrang, Alex Herbert, Gary Gregory">Add RandomAccessFile digest methods #31.</action>
5253
</release>
5354

5455
<release version="1.13" date="2019-07-20" description="Feature and fix release.">

src/main/java/org/apache/commons/codec/digest/DigestUtils.java

Lines changed: 155 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import java.io.BufferedInputStream;
2121
import java.io.File;
2222
import java.io.FileInputStream;
23+
import java.io.RandomAccessFile;
2324
import java.io.IOException;
2425
import java.io.InputStream;
2526
import java.nio.ByteBuffer;
27+
import java.nio.channels.FileChannel;
2628
import java.security.MessageDigest;
2729
import java.security.NoSuchAlgorithmException;
2830

@@ -115,6 +117,19 @@ public static byte[] digest(final MessageDigest messageDigest, final InputStream
115117
return updateDigest(messageDigest, data).digest();
116118
}
117119

120+
/**
121+
* Reads through a RandomAccessFile using non-blocking-io (NIO) and returns the digest for the data
122+
*
123+
* @param messageDigest The MessageDigest to use (e.g. MD5)
124+
* @param data Data to digest
125+
* @return the digest
126+
* @throws IOException On error reading from the stream
127+
* @since 1.14
128+
*/
129+
public static byte[] digest(final MessageDigest messageDigest, final RandomAccessFile data) throws IOException {
130+
return updateDigest(messageDigest, data).digest();
131+
}
132+
118133
/**
119134
* Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
120135
*
@@ -699,6 +714,32 @@ public static byte[] sha3_224(final String data) {
699714
return sha3_224(StringUtils.getBytesUtf8(data));
700715
}
701716

717+
/**
718+
* Calculates the SHA3-224 digest and returns the value as a hex string.
719+
*
720+
* @param data
721+
* Data to digest
722+
* @return SHA3-224 digest as a hex string
723+
* @since 1.12
724+
*/
725+
public static String sha3_224Hex(final byte[] data) {
726+
return Hex.encodeHexString(sha3_224(data));
727+
}
728+
729+
/**
730+
* Calculates the SHA3-224 digest and returns the value as a hex string.
731+
*
732+
* @param data
733+
* Data to digest
734+
* @return SHA3-224 digest as a hex string
735+
* @throws IOException
736+
* On error reading from the stream
737+
* @since 1.12
738+
*/
739+
public static String sha3_224Hex(final InputStream data) throws IOException {
740+
return Hex.encodeHexString(sha3_224(data));
741+
}
742+
702743
/**
703744
* Calculates the SHA3-224 digest and returns the value as a hex string.
704745
*
@@ -749,6 +790,32 @@ public static byte[] sha3_256(final String data) {
749790
return sha3_256(StringUtils.getBytesUtf8(data));
750791
}
751792

793+
/**
794+
* Calculates the SHA3-256 digest and returns the value as a hex string.
795+
*
796+
* @param data
797+
* Data to digest
798+
* @return SHA3-256 digest as a hex string
799+
* @since 1.12
800+
*/
801+
public static String sha3_256Hex(final byte[] data) {
802+
return Hex.encodeHexString(sha3_256(data));
803+
}
804+
805+
/**
806+
* Calculates the SHA3-256 digest and returns the value as a hex string.
807+
*
808+
* @param data
809+
* Data to digest
810+
* @return SHA3-256 digest as a hex string
811+
* @throws IOException
812+
* On error reading from the stream
813+
* @since 1.12
814+
*/
815+
public static String sha3_256Hex(final InputStream data) throws IOException {
816+
return Hex.encodeHexString(sha3_256(data));
817+
}
818+
752819
/**
753820
* Calculates the SHA3-256 digest and returns the value as a hex string.
754821
*
@@ -799,6 +866,32 @@ public static byte[] sha3_384(final String data) {
799866
return sha3_384(StringUtils.getBytesUtf8(data));
800867
}
801868

869+
/**
870+
* Calculates the SHA3-384 digest and returns the value as a hex string.
871+
*
872+
* @param data
873+
* Data to digest
874+
* @return SHA3-384 digest as a hex string
875+
* @since 1.12
876+
*/
877+
public static String sha3_384Hex(final byte[] data) {
878+
return Hex.encodeHexString(sha3_384(data));
879+
}
880+
881+
/**
882+
* Calculates the SHA3-384 digest and returns the value as a hex string.
883+
*
884+
* @param data
885+
* Data to digest
886+
* @return SHA3-384 digest as a hex string
887+
* @throws IOException
888+
* On error reading from the stream
889+
* @since 1.12
890+
*/
891+
public static String sha3_384Hex(final InputStream data) throws IOException {
892+
return Hex.encodeHexString(sha3_384(data));
893+
}
894+
802895
/**
803896
* Calculates the SHA3-384 digest and returns the value as a hex string.
804897
*
@@ -849,6 +942,32 @@ public static byte[] sha3_512(final String data) {
849942
return sha3_512(StringUtils.getBytesUtf8(data));
850943
}
851944

945+
/**
946+
* Calculates the SHA3-512 digest and returns the value as a hex string.
947+
*
948+
* @param data
949+
* Data to digest
950+
* @return SHA3-512 digest as a hex string
951+
* @since 1.12
952+
*/
953+
public static String sha3_512Hex(final byte[] data) {
954+
return Hex.encodeHexString(sha3_512(data));
955+
}
956+
957+
/**
958+
* Calculates the SHA3-512 digest and returns the value as a hex string.
959+
*
960+
* @param data
961+
* Data to digest
962+
* @return SHA3-512 digest as a hex string
963+
* @throws IOException
964+
* On error reading from the stream
965+
* @since 1.12
966+
*/
967+
public static String sha3_512Hex(final InputStream data) throws IOException {
968+
return Hex.encodeHexString(sha3_512(data));
969+
}
970+
852971
/**
853972
* Calculates the SHA3-512 digest and returns the value as a hex string.
854973
*
@@ -987,54 +1106,6 @@ public static String sha512Hex(final byte[] data) {
9871106
return Hex.encodeHexString(sha512(data));
9881107
}
9891108

990-
/**
991-
* Calculates the SHA3-224 digest and returns the value as a hex string.
992-
*
993-
* @param data
994-
* Data to digest
995-
* @return SHA3-224 digest as a hex string
996-
* @since 1.12
997-
*/
998-
public static String sha3_224Hex(final byte[] data) {
999-
return Hex.encodeHexString(sha3_224(data));
1000-
}
1001-
1002-
/**
1003-
* Calculates the SHA3-256 digest and returns the value as a hex string.
1004-
*
1005-
* @param data
1006-
* Data to digest
1007-
* @return SHA3-256 digest as a hex string
1008-
* @since 1.12
1009-
*/
1010-
public static String sha3_256Hex(final byte[] data) {
1011-
return Hex.encodeHexString(sha3_256(data));
1012-
}
1013-
1014-
/**
1015-
* Calculates the SHA3-384 digest and returns the value as a hex string.
1016-
*
1017-
* @param data
1018-
* Data to digest
1019-
* @return SHA3-384 digest as a hex string
1020-
* @since 1.12
1021-
*/
1022-
public static String sha3_384Hex(final byte[] data) {
1023-
return Hex.encodeHexString(sha3_384(data));
1024-
}
1025-
1026-
/**
1027-
* Calculates the SHA3-512 digest and returns the value as a hex string.
1028-
*
1029-
* @param data
1030-
* Data to digest
1031-
* @return SHA3-512 digest as a hex string
1032-
* @since 1.12
1033-
*/
1034-
public static String sha3_512Hex(final byte[] data) {
1035-
return Hex.encodeHexString(sha3_512(data));
1036-
}
1037-
10381109
/**
10391110
* Calculates the SHA-512 digest and returns the value as a hex string.
10401111
*
@@ -1049,62 +1120,6 @@ public static String sha512Hex(final InputStream data) throws IOException {
10491120
return Hex.encodeHexString(sha512(data));
10501121
}
10511122

1052-
/**
1053-
* Calculates the SHA3-224 digest and returns the value as a hex string.
1054-
*
1055-
* @param data
1056-
* Data to digest
1057-
* @return SHA3-224 digest as a hex string
1058-
* @throws IOException
1059-
* On error reading from the stream
1060-
* @since 1.12
1061-
*/
1062-
public static String sha3_224Hex(final InputStream data) throws IOException {
1063-
return Hex.encodeHexString(sha3_224(data));
1064-
}
1065-
1066-
/**
1067-
* Calculates the SHA3-256 digest and returns the value as a hex string.
1068-
*
1069-
* @param data
1070-
* Data to digest
1071-
* @return SHA3-256 digest as a hex string
1072-
* @throws IOException
1073-
* On error reading from the stream
1074-
* @since 1.12
1075-
*/
1076-
public static String sha3_256Hex(final InputStream data) throws IOException {
1077-
return Hex.encodeHexString(sha3_256(data));
1078-
}
1079-
1080-
/**
1081-
* Calculates the SHA3-384 digest and returns the value as a hex string.
1082-
*
1083-
* @param data
1084-
* Data to digest
1085-
* @return SHA3-384 digest as a hex string
1086-
* @throws IOException
1087-
* On error reading from the stream
1088-
* @since 1.12
1089-
*/
1090-
public static String sha3_384Hex(final InputStream data) throws IOException {
1091-
return Hex.encodeHexString(sha3_384(data));
1092-
}
1093-
1094-
/**
1095-
* Calculates the SHA3-512 digest and returns the value as a hex string.
1096-
*
1097-
* @param data
1098-
* Data to digest
1099-
* @return SHA3-512 digest as a hex string
1100-
* @throws IOException
1101-
* On error reading from the stream
1102-
* @since 1.12
1103-
*/
1104-
public static String sha3_512Hex(final InputStream data) throws IOException {
1105-
return Hex.encodeHexString(sha3_512(data));
1106-
}
1107-
11081123
/**
11091124
* Calculates the SHA-512 digest and returns the value as a hex string.
11101125
*
@@ -1207,6 +1222,27 @@ public static MessageDigest updateDigest(final MessageDigest digest, final File
12071222
}
12081223
}
12091224

1225+
/**
1226+
* Reads through a RandomAccessFile and updates the digest for the data using non-blocking-io (NIO).
1227+
*
1228+
* TODO Decide if this should be public.
1229+
*
1230+
* @param digest The MessageDigest to use (e.g. MD5)
1231+
* @param data Data to digest
1232+
* @return the digest
1233+
* @throws IOException On error reading from the stream
1234+
* @since 1.14
1235+
*/
1236+
private static MessageDigest updateDigest(final MessageDigest digest, final FileChannel data) throws IOException {
1237+
final ByteBuffer buffer = ByteBuffer.allocate(STREAM_BUFFER_LENGTH);
1238+
while (data.read(buffer) > 0) {
1239+
buffer.flip();
1240+
digest.update(buffer);
1241+
buffer.clear();
1242+
}
1243+
return digest;
1244+
}
1245+
12101246
/**
12111247
* Reads through an InputStream and updates the digest for the data
12121248
*
@@ -1231,6 +1267,21 @@ public static MessageDigest updateDigest(final MessageDigest digest, final Input
12311267
return digest;
12321268
}
12331269

1270+
1271+
/**
1272+
* Reads through a RandomAccessFile and updates the digest for the data using non-blocking-io (NIO)
1273+
*
1274+
* @param digest The MessageDigest to use (e.g. MD5)
1275+
* @param data Data to digest
1276+
* @return the digest
1277+
* @throws IOException On error reading from the stream
1278+
* @since 1.14
1279+
*/
1280+
public static MessageDigest updateDigest(final MessageDigest digest, final RandomAccessFile data)
1281+
throws IOException {
1282+
return updateDigest(digest, data.getChannel());
1283+
}
1284+
12341285
/**
12351286
* Updates the given {@link MessageDigest} from a String (converted to bytes using UTF-8).
12361287
* <p>

src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.File;
2525
import java.io.FileOutputStream;
2626
import java.io.IOException;
27+
import java.io.RandomAccessFile;
2728
import java.nio.ByteBuffer;
2829
import java.security.MessageDigest;
2930
import java.util.Random;
@@ -47,6 +48,10 @@ public class DigestUtilsTest {
4748

4849
private File testFile;
4950

51+
private File testRandomAccessFile;
52+
53+
private RandomAccessFile testRandomAccessFileWrapper;
54+
5055
private void assumeJava8() {
5156
Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
5257
}
@@ -63,20 +68,34 @@ File getTestFile() {
6368
return testFile;
6469
}
6570

71+
RandomAccessFile getTestRandomAccessFile() {
72+
return testRandomAccessFileWrapper;
73+
}
74+
6675
@Before
6776
public void setUp() throws Exception {
6877
new Random().nextBytes(testData);
6978
testFile = File.createTempFile(DigestUtilsTest.class.getName(), ".dat");
7079
try (final FileOutputStream fos = new FileOutputStream(testFile)) {
7180
fos.write(testData);
7281
}
82+
83+
testRandomAccessFile = File.createTempFile(DigestUtilsTest.class.getName(), ".dat");
84+
try (final FileOutputStream fos = new FileOutputStream(testRandomAccessFile)) {
85+
fos.write(testData);
86+
}
87+
testRandomAccessFileWrapper = new RandomAccessFile(testRandomAccessFile, "rw");
7388
}
7489

7590
@After
7691
public void tearDown() {
7792
if (!testFile.delete()) {
7893
testFile.deleteOnExit();
7994
}
95+
96+
if (!testRandomAccessFile.delete()) {
97+
testRandomAccessFile.deleteOnExit();
98+
}
8099
}
81100

82101
@Test(expected=IllegalArgumentException.class)

0 commit comments

Comments
 (0)