All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.featherfly.common.algorithm.CRC Maven / Gradle / Ivy

package cn.featherfly.common.algorithm;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;

/**
 * CRC algorithm
 *
 * @author zhongj
 */
public abstract class CRC extends Algorithm {
    /**
     * generate crc32 long number
     *
     * @param data data bytes
     * @return crc32 long number
     */
    public static final long crc32(byte[] data) {
        CRC32 crc = new CRC32();
        crc.update(data);
        return crc.getValue();
    }

    /**
     * generate crc32 long number
     *
     * @param data data string
     * @return crc32 long number
     */
    public static final long crc32(String data) {
        return crc32(getBytes(data));
    }

    /**
     * generate crc32 long number
     *
     * @param inputStream inputStream
     * @return crc32 long number
     * @throws IOException
     */
    public static final long crc32(InputStream inputStream) throws IOException {
        CRC32 crc32 = new CRC32();
        CheckedInputStream checkedinputstream = new CheckedInputStream(inputStream, crc32);
        while (checkedinputstream.read() != -1) {
        }
        checkedinputstream.close();
        return crc32.getValue();
    }

    /**
     * generate crc32 long number
     *
     * @param file file
     * @return crc32 long number
     * @throws IOException
     */
    public static final long crc32(File file) throws IOException {
        return crc32(new FileInputStream(file));
    }

    /**
     * generate crc32 hex string
     *
     * @param data data bytes
     * @return crc32 hex string
     */
    public static final String crc32Hex(byte[] data) {
        return Long.toHexString(crc32(data));
    }

    /**
     * generate crc32 hex string
     *
     * @param data data string
     * @return crc32 hex string
     */
    public static final String crc32Hex(String data) {
        return Long.toHexString(crc32(data));
    }

    /**
     * generate crc32 hex string
     *
     * @param inputStream inputStream
     * @return crc32 hex string
     * @throws IOException
     */
    public static final String crc32Hex(InputStream inputStream) throws IOException {
        return Long.toHexString(crc32(inputStream));
    }

    /**
     * generate crc32 hex string
     *
     * @param file file
     * @return crc32 hex string
     * @throws IOException
     */
    public static String crc32Hex(File file) throws IOException {
        return Long.toHexString(crc32(file));
    }

    private static final long INITIALCRC = 0xFFFFFFFFFFFFFFFFL;
    private static long[] sCrcTable = new long[256];
    private static final long POLY64REV = 0x95AC9329AC4BC9B5L;

    static {
        // http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c
        long part;
        for (int i = 0; i < 256; i++) {
            part = i;
            for (int j = 0; j < 8; j++) {
                long x = ((int) part & 1) != 0 ? POLY64REV : 0;
                part = part >> 1 ^ x;
            }
            sCrcTable[i] = part;
        }
    }

    /**
     * generate crc64 long number
     *
     * @param data data byte[]
     * @return crc64 long number
     */
    public static final long crc64(byte[] data) {
        long crc = INITIALCRC;
        for (int k = 0, n = data.length; k < n; ++k) {
            crc = sCrcTable[((int) crc ^ data[k]) & 0xff] ^ crc >> 8;
        }
        return crc;
    }

    /**
     * generate crc64 long number
     *
     * @param data data string
     * @return crc64 long number
     */
    public static final long crc64(String data) {
        return crc64(getBytes(data));
    }

    /**
     * generate crc64 hex string
     *
     * @param data data byte[]
     * @return crc64 hex string
     */
    public static final String crc64Hex(byte[] data) {
        return Long.toHexString(crc64(data));
    }

    /**
     * generate crc64 hex string
     *
     * @param data data string
     * @return crc64 hex string
     */
    public static final String crc64Hex(String data) {
        return Long.toHexString(crc64(data));
    }

    /**
     * CRC-16 (CCITT):多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0x0000异或
     * 0x8408是0x1021按位颠倒后的结果。
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16Ccitt(byte[] data) {
        int wCRCin = 0x0000;
        int wCPoly = 0x8408;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0x0000;

    }

    /**
     * CRC-16 (CCITT
     * REVERSE):多项式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,结果与0x0000异或
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16CcittReverse(byte[] data) {
        int wCRCin = 0xffff;
        int wCPoly = 0x1021;
        for (byte b : data) {
            for (int i = 0; i < 8; i++) {
                boolean bit = (b >> 7 - i & 1) == 1;
                boolean c15 = (wCRCin >> 15 & 1) == 1;
                wCRCin <<= 1;
                if (c15 ^ bit) {
                    wCRCin ^= wCPoly;
                }
            }
        }
        wCRCin &= 0xffff;
        return wCRCin ^= 0x0000;
    }

    /**
     * CRC-16 (XModem):多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,结果与0x0000异或
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16Xmodem(byte[] data) {
        int wCRCin = 0x0000; // initial value 65535
        int wCPoly = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
        for (byte b : data) {
            for (int i = 0; i < 8; i++) {
                boolean bit = (b >> 7 - i & 1) == 1;
                boolean c15 = (wCRCin >> 15 & 1) == 1;
                wCRCin <<= 1;
                if (c15 ^ bit) {
                    wCRCin ^= wCPoly;
                }
            }
        }
        wCRCin &= 0xffff;
        return wCRCin ^= 0x0000;
    }

    /**
     * CRC-16 (X25):多项式x16+x12+x5+1(0x1021),初始值0xffff,低位在前,高位在后,结果与0xFFFF异或
     * 0x8408是0x1021按位颠倒后的结果。
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16X25(byte[] data) {
        int wCRCin = 0xffff;
        int wCPoly = 0x8408;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0xffff;
    }

    /**
     * CRC-16 (Modbus):多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或
     * 0xA001是0x8005按位颠倒后的结果
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16Modbus(byte[] data) {
        int wCRCin = 0xffff;
        int POLYNOMIAL = 0xa001;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= POLYNOMIAL;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0x0000;
    }

    /**
     * CRC-16 (IBM):多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或
     * 0xA001是0x8005按位颠倒后的结果
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16IBM(byte[] data) {
        int wCRCin = 0x0000;
        int wCPoly = 0xa001;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0x0000;
    }

    /**
     * CRC-16 (MAXIM):多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或
     * 0xA001是0x8005按位颠倒后的结果
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16Maxim(byte[] data) {
        int wCRCin = 0x0000;
        int wCPoly = 0xa001;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0xffff;
    }

    /**
     * CRC-16 (USB):多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或
     * 0xA001是0x8005按位颠倒后的结果
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16USB(byte[] data) {
        int wCRCin = 0xFFFF;
        int wCPoly = 0xa001;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0xffff;
    }

    /**
     * CRC-16
     * (DNP):多项式x16+x13+x12+x11+x10+x8+x6+x5+x2+1(0x3D65),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或
     * 0xA6BC是0x3D65按位颠倒后的结果
     *
     * @param data data byte[]
     * @return crc16 int number
     */
    public static int crc16DNP(byte[] data) {
        int wCRCin = 0x0000;
        int wCPoly = 0xA6BC;
        for (byte b : data) {
            wCRCin ^= b & 0x00ff;
            for (int j = 0; j < 8; j++) {
                if ((wCRCin & 0x0001) != 0) {
                    wCRCin >>= 1;
                    wCRCin ^= wCPoly;
                } else {
                    wCRCin >>= 1;
                }
            }
        }
        return wCRCin ^= 0xffff;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy