Skip to content

Commit 0955639

Browse files
committed
added file size and mode indicator to compressed version
1 parent 78724fc commit 0955639

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

src/de/ntcomputer/crypto/hash/HashCondenser.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import java.io.ByteArrayInputStream;
44
import java.io.IOException;
55
import java.io.InputStream;
6+
import java.nio.ByteBuffer;
7+
import java.nio.ByteOrder;
68
import java.security.MessageDigest;
79
import java.security.NoSuchAlgorithmException;
810
import java.util.Arrays;
911

1012
public class HashCondenser {
1113
public static final int DEFAULT_OUTPUT_SIZE = 512*1024;
14+
private static final int LONG_SIZE = Long.SIZE/8;
1215
private final MessageDigest digest;
1316
private final int outputSize;
1417
private final int digestLength;
@@ -36,7 +39,7 @@ private HashCondenser(MessageDigest md, int outputSize) {
3639
digestLength = md.getDigestLength();
3740
if(digestLength==0) throw new IllegalArgumentException("could not determine message digest length (returned 0)");
3841
if(this.outputSize < this.digestLength) throw new IllegalArgumentException("output size is less than message digest length");
39-
this.hashCount = this.outputSize / digestLength;
42+
this.hashCount = (this.outputSize - LONG_SIZE) / digestLength;
4043
}
4144

4245
/**
@@ -66,26 +69,34 @@ public byte[] compute(byte[] data) {
6669
* @throws IOException when source throws an IOException
6770
* @throws IllegalArgumentException if sourceSize happens not to be the same as source's size
6871
*/
69-
public byte[] compute(InputStream source, long sourceSize) throws IOException, IllegalArgumentException {
72+
public byte[] compute(InputStream source, long sourceSize) throws IOException, IllegalArgumentException {
7073
// create result buffer
7174
byte[] result = new byte[this.outputSize];
7275
Arrays.fill(result, (byte) 0x00);
7376

74-
if(sourceSize <= this.outputSize) {
77+
if(sourceSize <= this.outputSize-LONG_SIZE) {
7578
// copy source directly if short enough
79+
80+
// add file size + negative sign as direct mode indicator
81+
ByteBuffer.wrap(result).order(ByteOrder.BIG_ENDIAN).putLong(-sourceSize);
82+
7683
int readSourceSize = 0;
7784
int readLength;
78-
while((readLength = source.read(result, readSourceSize, (int) (sourceSize-readSourceSize))) != -1) {
85+
while((readLength = source.read(result, LONG_SIZE+readSourceSize, (int) (sourceSize-readSourceSize))) != -1) {
7986
readSourceSize+= readLength;
8087
if(readLength==0) {
8188
if(source.read() != -1) readSourceSize++;
8289
break;
8390
}
8491
}
85-
if(readSourceSize != sourceSize) throw new IllegalArgumentException("read not as many bytes as sourceSize originally provided. Maybe the resource changed?");
92+
if(readSourceSize != sourceSize) throw new IllegalArgumentException("read not as many bytes as sourceSize originally provided. Maybe the resource changed?");
93+
8694
} else {
8795
// otherwise, hash segments
8896

97+
// add file size + positive sign as compressed mode indicator
98+
ByteBuffer.wrap(result).order(ByteOrder.BIG_ENDIAN).putLong(sourceSize);
99+
89100
// calculate segment size (input size for each hash)
90101
// if necessary, start hashing 1 byte more which will later be dropped so we hash exactly sourceSize bytes
91102
long segmentSize = sourceSize / hashCount;
@@ -101,7 +112,7 @@ public byte[] compute(InputStream source, long sourceSize) throws IOException, I
101112
long previouslyReadSegmentSize = 0;
102113
int readLength = 0;
103114
int segmentIndex = 0;
104-
int resultIndex = 0;
115+
int resultIndex = LONG_SIZE;
105116

106117
// read all input
107118
while((readLength = source.read(buf)) != -1) {

0 commit comments

Comments
 (0)