hashing
parent
8d1936a368
commit
75f03f181b
|
@ -4,7 +4,9 @@ import client.Client;
|
||||||
import net.jpountz.lz4.LZ4Compressor;
|
import net.jpountz.lz4.LZ4Compressor;
|
||||||
import net.jpountz.lz4.LZ4Factory;
|
import net.jpountz.lz4.LZ4Factory;
|
||||||
import net.jpountz.lz4.LZ4FastDecompressor;
|
import net.jpountz.lz4.LZ4FastDecompressor;
|
||||||
import net.jpountz.lz4.LZ4SafeDecompressor;
|
import net.jpountz.xxhash.StreamingXXHash64;
|
||||||
|
import net.jpountz.xxhash.XXHash64;
|
||||||
|
import net.jpountz.xxhash.XXHashFactory;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -12,11 +14,16 @@ import java.nio.file.Paths;
|
||||||
|
|
||||||
public class FileHeader {
|
public class FileHeader {
|
||||||
|
|
||||||
public static final int READER_SIZE = 8192;
|
private static final int READER_SIZE = 8192;
|
||||||
|
|
||||||
private static final LZ4Factory factory = LZ4Factory.fastestInstance();
|
private static final LZ4Factory LZ_FACTORY = LZ4Factory.fastestInstance();
|
||||||
private static final LZ4Compressor compressor = factory.highCompressor();
|
private static final LZ4Compressor COMPRESSOR = LZ_FACTORY.highCompressor();
|
||||||
private static final LZ4FastDecompressor decompressor = factory.fastDecompressor();
|
private static final LZ4FastDecompressor DECOMPRESSOR = LZ_FACTORY.fastDecompressor();
|
||||||
|
|
||||||
|
private static final XXHashFactory XX_HASH_FACTORY = XXHashFactory.fastestInstance();
|
||||||
|
private static final XXHash64 HASH_64 = XX_HASH_FACTORY.hash64();
|
||||||
|
|
||||||
|
private static final long SEED = 691;
|
||||||
|
|
||||||
public enum COMMAND {
|
public enum COMMAND {
|
||||||
WRITE((byte) 1);
|
WRITE((byte) 1);
|
||||||
|
@ -49,6 +56,7 @@ public class FileHeader {
|
||||||
writer.writeByte(COMMAND.WRITE.type);
|
writer.writeByte(COMMAND.WRITE.type);
|
||||||
writer.writeUTF(relative_path);
|
writer.writeUTF(relative_path);
|
||||||
|
|
||||||
|
StreamingXXHash64 streamHash = XX_HASH_FACTORY.newStreamingHash64(SEED);
|
||||||
while (reader.available() > 0) {
|
while (reader.available() > 0) {
|
||||||
// read / write files in chunks
|
// read / write files in chunks
|
||||||
int read = Integer.min(reader.available(), READER_SIZE);
|
int read = Integer.min(reader.available(), READER_SIZE);
|
||||||
|
@ -58,19 +66,25 @@ public class FileHeader {
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// create a checksum for this chunk + update the overall checksum
|
||||||
|
streamHash.update(bytes, 0, amount);
|
||||||
|
long hash = HASH_64.hash(bytes, 0, amount, SEED);
|
||||||
|
|
||||||
// apply compression
|
// apply compression
|
||||||
int maxCompressedLength = compressor.maxCompressedLength(bytes.length);
|
int maxCompressedLength = COMPRESSOR.maxCompressedLength(bytes.length);
|
||||||
byte[] compressed = new byte[maxCompressedLength];
|
byte[] compressed = new byte[maxCompressedLength];
|
||||||
int compressedLength = compressor.compress(bytes, 0, bytes.length, compressed, 0, maxCompressedLength);
|
int compressedLength = COMPRESSOR.compress(bytes, 0, bytes.length, compressed, 0, maxCompressedLength);
|
||||||
|
|
||||||
System.out.println("Writing " + compressedLength + " bytes");
|
System.out.println("Writing " + compressedLength + " bytes");
|
||||||
writer.writeInt(amount);
|
writer.writeInt(amount);
|
||||||
writer.writeInt(compressedLength);
|
writer.writeInt(compressedLength);
|
||||||
|
writer.writeLong(hash);
|
||||||
writer.write(compressed, 0, compressedLength);
|
writer.write(compressed, 0, compressedLength);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
writer.writeInt(0);
|
writer.writeInt(0);
|
||||||
|
writer.writeLong(streamHash.getValue());
|
||||||
writer.flush();
|
writer.flush();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ExceptionLogger.log(e);
|
ExceptionLogger.log(e);
|
||||||
|
@ -93,17 +107,27 @@ public class FileHeader {
|
||||||
|
|
||||||
DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(Files.newOutputStream(Paths.get(path))));
|
DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(Files.newOutputStream(Paths.get(path))));
|
||||||
int uncompressed_size = 0;
|
int uncompressed_size = 0;
|
||||||
|
StreamingXXHash64 computedStreamHash = XX_HASH_FACTORY.newStreamingHash64(SEED);
|
||||||
while ((uncompressed_size = reader.readInt()) > 0) {
|
while ((uncompressed_size = reader.readInt()) > 0) {
|
||||||
int compressed_size = reader.readInt();
|
int compressed_size = reader.readInt();
|
||||||
|
long hash = reader.readLong();
|
||||||
byte[] data = new byte[compressed_size];
|
byte[] data = new byte[compressed_size];
|
||||||
int amount = reader.read(data, 0, compressed_size);
|
int amount = reader.read(data, 0, compressed_size);
|
||||||
|
|
||||||
byte[] restored = new byte[uncompressed_size];
|
byte[] restored = new byte[uncompressed_size];
|
||||||
|
int len = DECOMPRESSOR.decompress(data, 0, restored, 0, uncompressed_size);
|
||||||
|
|
||||||
int len = decompressor.decompress(data, 0, restored, 0, uncompressed_size);
|
long computedHash = HASH_64.hash(restored, 0, uncompressed_size, SEED);
|
||||||
|
computedStreamHash.update(restored, 0, uncompressed_size);
|
||||||
|
|
||||||
|
if (hash != computedHash)
|
||||||
|
throw new RuntimeException(hash + " HELP! " + computedHash);
|
||||||
|
|
||||||
writer.write(restored, 0, uncompressed_size);
|
writer.write(restored, 0, uncompressed_size);
|
||||||
}
|
}
|
||||||
|
long streamHash = reader.readLong();
|
||||||
|
if (computedStreamHash.getValue() != streamHash)
|
||||||
|
throw new RuntimeException("HELP 22");
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
|
|
Loading…
Reference in New Issue