package com.dedupeer.checksum; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.apache.log4j.Logger; import org.springframework.util.Assert; /** * @deprecated */ public class RollingChecksumOlder { private static final Logger log = Logger.getLogger(RollingChecksumOlder.class); private byte[] data; private InputStream stream; private File f; private boolean eofReached = false; private int readOffset = 0; private int blockSize; private int index = -1; private long a = 0; private long b = 0; private static long M = (long) Math.pow(2, 16); public RollingChecksumOlder(File f, int blockSize) { this.f = f; this.blockSize = Math.min((int) f.length(), blockSize); this.data = new byte[(int) f.length()]; //Maximum filesize: 2,147,483,647 try { this.stream = new FileInputStream(f); } catch (FileNotFoundException e) { log.info(String.format("Failed to access file [%s]", f.getAbsolutePath())); } } public RollingChecksumOlder(String string, int blockSize) { Assert.notNull(string); this.data = string.getBytes(); this.blockSize = Math.min(data.length, blockSize); } public RollingChecksumOlder(byte[] data, int blockSize) { this.data = data; this.blockSize = Math.min(data.length, blockSize); } public final void reset() { index = -1; a = 0; b = 0; } public boolean next() { if (index < data.length - blockSize) { //If pulling data off a stream, get another chunk of data here if (stream != null && !eofReached) { if (log.isDebugEnabled()) log.debug("Buffering more data..."); try { int bytesRead = stream.read(data, readOffset, blockSize); if (bytesRead >= 0) readOffset += bytesRead; else { eofReached = true; stream.close(); } } catch (IOException e) { System.out.println(String.format("Failed to read or close file [%s]", f.getAbsolutePath())); } } index++; return true; } else { return false; } } public static final Long sum(byte[] chunk) { long a = 0, b = 0; for (int i=0; i<chunk.length; i++) { a += (long) chunk[i]; b += (chunk.length-i) * (long) chunk[i]; } a = a % M; b = b % M; long checksum = a + M * b; return checksum; } public static final Long sum(String str, int start, int end) { String sub = str.substring(start, Math.min(str.length(), end)); long checksum = sum(sub.getBytes()); if (log.isDebugEnabled()) log.debug("sum("+sub+"): " + Long.toHexString(checksum)); return checksum; } public long weak() { long checksum; if (index == 0) { // s(l, k) = a(l, k) + M * b(l, k) byte[] firstBlock = new byte[Math.min(blockSize, data.length)]; System.arraycopy(data, 0, firstBlock, 0, Math.min(blockSize, data.length)); //Initialize alpha and beta summations for (int i=0; i<firstBlock.length; i++) { a += (long) firstBlock[i]; b += (blockSize-i) * (long) firstBlock[i]; } a = a % M; b = b % M; checksum = a + M * b; if (log.isTraceEnabled()) { StringBuilder hex = new StringBuilder(); for (int i=0; i<firstBlock.length; i++) hex.append(Long.toHexString((long) firstBlock[i])); log.trace("weak(block:"+hex.toString()+"): " + Long.toHexString(checksum)); } } else { int lastByteAt = index - 1; int nextByteAt = index + blockSize - 1; byte lastByte = data[lastByteAt]; byte nextByte = data[nextByteAt]; a = (a - (long) lastByte + (long) nextByte) % M; b = (b - blockSize * (long) lastByte + a) % M; checksum = a + M * b; if (log.isTraceEnabled()) { log.trace("weak(lastByte:"+Long.toHexString((long) lastByte)+", nextByte:"+Long.toHexString((long) nextByte) + "): " + Long.toHexString(checksum)); } } return checksum; } }