Untitled
unknown
plain_text
a year ago
3.0 kB
8
Indexable
public class CrcCalculator {
private final AlgorithmParams parameters;
private final byte hashSize;
private long mask = 0xFFFFFFFFFFFFFFFFL;
private final long[] table = new long[256];
public CrcCalculator(CrcAlgorithm algorithm) {
this(algorithm.getParams());
}
public CrcCalculator(AlgorithmParams parameters) {
this.parameters = parameters;
this.hashSize = (byte) parameters.getHashSize();
if (this.hashSize < 64) {
mask = (1L << this.hashSize) - 1;
}
createTable();
}
public long calc(byte[] data) {
return calc(data, 0, data.length);
}
public long calc(byte[] data, int offset, int length) {
long init = parameters.isRefOut() ?
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));
crc &= mask;
}
} else {
int toRight = (hashSize - 8);
toRight = Math.max(toRight, 0);
for (int i = offset; i < offset + length; i++) {
crc = (table[(int) (((crc >> toRight) ^ data[i]) & 0xFF)] ^ (crc << 8));
crc &= mask;
}
}
return crc;
}
private void createTable() {
for (int i = 0; i < table.length; i++)
table[i] = createTableEntry(i);
}
private long createTableEntry(int index) {
long r = index;
if (parameters.isRefIn())
r = reverseBits(r, hashSize);
else if (hashSize > 8)
r <<= (hashSize - 8);
long lastBit = (1L << (hashSize - 1));
for (int i = 0; i < 8; i++) {
if ((r & lastBit) != 0)
r = ((r << 1) ^ parameters.getPoly());
else
r <<= 1;
}
if (parameters.isRefOut())
r = reverseBits(r, hashSize);
return r & mask;
}
private long reverseBits(long ul, int valueLength) {
long newValue = 0;
for (int i = valueLength - 1; i >= 0; i--) {
newValue |= (ul & 1) << i;
ul >>= 1;
}
return newValue;
}
public static byte[] hexStringToByteArray(String hex) {
int length = hex.length();
byte[] data = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
return data;
}Editor is loading...
Leave a Comment