expose some direct byte formatting methods

allow SHA256 to be run against a partial array
append to the stats.log instead of overwriting it
This commit is contained in:
jrandom
2004-10-07 16:48:46 +00:00
committed by zzz
parent 37479d8c0d
commit 32188b1cc0
3 changed files with 75 additions and 21 deletions

View File

@ -62,40 +62,43 @@ public class SHA256Generator {
* @return hash of the source
*/
public Hash calculateHash(byte[] source) {
long length = source.length * 8;
return calculateHash(source, 0, source.length);
}
public Hash calculateHash(byte[] source, int start, int len) {
long length = len * 8;
int k = 448 - (int) ((length + 1) % 512);
if (k < 0) {
k += 512;
}
int padbytes = k / 8;
int wordlength = source.length / 4 + padbytes / 4 + 3;
int wordlength = len / 4 + padbytes / 4 + 3;
int[] M0 = new int[wordlength];
int wordcount = 0;
int x = 0;
for (x = 0; x < (source.length / 4) * 4; x += 4) {
M0[wordcount] = source[x] << 24 >>> 24 << 24;
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0;
for (x = 0; x < (len / 4) * 4; x += 4) {
M0[wordcount] = source[x+start] << 24 >>> 24 << 24;
M0[wordcount] |= source[x+start + 1] << 24 >>> 24 << 16;
M0[wordcount] |= source[x+start + 2] << 24 >>> 24 << 8;
M0[wordcount] |= source[x+start + 3] << 24 >>> 24 << 0;
wordcount++;
}
switch (source.length - (wordcount + 1) * 4 + 4) {
switch (len - (wordcount + 1) * 4 + 4) {
case 0:
M0[wordcount] |= 0x80000000;
break;
case 1:
M0[wordcount] = source[x] << 24 >>> 24 << 24;
M0[wordcount] = source[x+start] << 24 >>> 24 << 24;
M0[wordcount] |= 0x00800000;
break;
case 2:
M0[wordcount] = source[x] << 24 >>> 24 << 24;
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
M0[wordcount] = source[x+start] << 24 >>> 24 << 24;
M0[wordcount] |= source[x+start + 1] << 24 >>> 24 << 16;
M0[wordcount] |= 0x00008000;
break;
case 3:
M0[wordcount] = source[x] << 24 >>> 24 << 24;
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
M0[wordcount] = source[x+start] << 24 >>> 24 << 24;
M0[wordcount] |= source[x+start + 1] << 24 >>> 24 << 16;
M0[wordcount] |= source[x+start + 2] << 24 >>> 24 << 8;
M0[wordcount] |= 0x00000080;
break;
}

View File

@ -262,6 +262,45 @@ public class DataHelper {
}
}
public static byte[] toLong(int numBytes, long value) throws IllegalArgumentException {
if (numBytes <= 0) throw new IllegalArgumentException("Invalid number of bytes");
if (value < 0) throw new IllegalArgumentException("Negative value not allowed");
byte val[] = new byte[numBytes];
for (int i = 0; i < numBytes; i++)
val[numBytes-i-1] = (byte)(value >>> (i*8));
return val;
}
public static void main(String args[]) {
for (int i = 0; i <= 0xFF; i++)
testLong(1, i);
System.out.println("Test 1byte passed");
for (long i = 0; i <= 0xFFFF; i++)
testLong(2, i);
System.out.println("Test 2byte passed");
for (long i = 0; i <= 0xFFFFFF; i++)
testLong(3, i);
System.out.println("Test 3byte passed");
for (long i = 0; i <= 0xFFFFFFFF; i++)
testLong(4, i);
System.out.println("Test 4byte passed");
for (long i = 0; i <= 0xFFFFFFFF; i++)
testLong(8, i);
System.out.println("Test 8byte passed");
}
private static void testLong(int numBytes, long value) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(numBytes);
writeLong(baos, numBytes, value);
byte written[] = baos.toByteArray();
byte extract[] = toLong(numBytes, value);
if (!eq(written, extract))
throw new RuntimeException("testLong("+numBytes+","+value+") FAILED");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
/** Read in a date from the stream as specified by the I2P data structure spec.
* A date is an 8 byte unsigned integer in network byte order specifying the number of
* milliseconds since midnight on January 1, 1970 in the GMT timezone. If the number is
@ -272,7 +311,7 @@ public class DataHelper {
* @return date read, or null
*/
public static Date readDate(InputStream in) throws DataFormatException, IOException {
long date = readLong(in, 8);
long date = readLong(in, DATE_LENGTH);
if (date == 0L) return null;
return new Date(date);
@ -287,10 +326,18 @@ public class DataHelper {
public static void writeDate(OutputStream out, Date date)
throws DataFormatException, IOException {
if (date == null)
writeLong(out, 8, 0L);
writeLong(out, DATE_LENGTH, 0L);
else
writeLong(out, 8, date.getTime());
writeLong(out, DATE_LENGTH, date.getTime());
}
public static byte[] toDate(Date date) throws IllegalArgumentException {
if (date == null)
return toLong(DATE_LENGTH, 0L);
else
return toLong(DATE_LENGTH, date.getTime());
}
public static final int DATE_LENGTH = 8;
/** Read in a string from the stream as specified by the I2P data structure spec.
* A string is 1 or more bytes where the first byte is the number of bytes (not characters!)
@ -364,13 +411,17 @@ public class DataHelper {
public static void writeBoolean(OutputStream out, Boolean bool)
throws DataFormatException, IOException {
if (bool == null)
writeLong(out, 1, 2);
writeLong(out, 1, BOOLEAN_UNKNOWN);
else if (Boolean.TRUE.equals(bool))
writeLong(out, 1, 1);
writeLong(out, 1, BOOLEAN_TRUE);
else
writeLong(out, 1, 0);
writeLong(out, 1, BOOLEAN_FALSE);
}
public static final byte BOOLEAN_TRUE = 0x1;
public static final byte BOOLEAN_FALSE = 0x0;
public static final byte BOOLEAN_UNKNOWN = 0x2;
//
// The following comparator helpers make it simpler to write consistently comparing
// functions for objects based on their value, not JVM memory address

View File

@ -99,7 +99,7 @@ public class BufferedStatLog implements StatLog {
if (_out != null) try { _out.close(); } catch (IOException ioe) {}
_outFile = filename;
try {
_out = new BufferedWriter(new FileWriter(_outFile));
_out = new BufferedWriter(new FileWriter(_outFile, true));
} catch (IOException ioe) { ioe.printStackTrace(); }
}
}