Untitled

 avatar
unknown
plain_text
13 days ago
2.3 kB
4
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