Untitled
unknown
plain_text
9 months ago
2.3 kB
6
Indexable
public class CrcCalculator {
private final AlgoParams parameters;
private final byte hashSize;
private final long mask;
private final long[] table;
public CrcCalculator(CrcAlgorithm algorithm) {
this(algorithm.getParams());
}
public CrcCalculator(AlgoParams parameters) {
this.parameters = parameters;
this.hashSize = (byte) parameters.getHashSize();
this.mask = (hashSize < 64) ? (1L << hashSize) - 1 : 0xFFFFFFFFFFFFFFFFL;
this.table = new long[256];
createTable();
}
public long calculate(byte[] data) {
return calculate(data, 0, data.length);
}
public long calculate(byte[] data, int offset, int length) {
long init = parameters.isRefOut() ?
CrcHelper.reverseBits(parameters.getInit(), hashSize) :
parameters.getInit();
long hash = computeCrc(init, data, offset, length);
return (hash ^ parameters.getXorOut()) & mask;
}
private long computeCrc(long init, byte[] data, int offset, int length) {
long crc = init;
if (parameters.isRefOut()) {
for (int i = offset; i < offset + length; i++) {
crc = (table[(int) ((crc ^ data[i]) & 0xFF)] ^ (crc >>> 8)) & mask;
}
} else {
int shiftRight = Math.max(hashSize - 8, 0);
for (int i = offset; i < offset + length; i++) {
crc = (table[(int) (((crc >> shiftRight) ^ data[i]) & 0xFF)] ^ (crc << 8)) & mask;
}
}
return crc;
}
private void createTable() {
Arrays.setAll(table, this::createTableEntry);
}
private long createTableEntry(int index) {
long r = parameters.isRefIn() ? CrcHelper.reverseBits(index, hashSize) : (long) index;
if (!parameters.isRefIn() && hashSize > 8) {
r <<= (hashSize - 8);
}
long lastBit = 1L << (hashSize - 1);
for (int i = 0; i < 8; i++) {
r = ((r & lastBit) != 0) ? (r << 1) ^ parameters.getPoly() : r << 1;
}
return parameters.isRefOut() ? CrcHelper.reverseBits(r, hashSize) & mask : r & mask;
}
public AlgoParams getParameters() {
return parameters;
}
}
Editor is loading...
Leave a Comment