[Java] CRC16 체크 로직

Programming/Java 2021. 12. 4. 18:19 Posted by 생각하는로뎅
반응형

CRC 체크할때 잘 써먹자.

 

 

package kr.co.kiosk.util;

/**
 * crc 16 체크 유틸
 * 
 * @author 임성진
 */
public class CRCCheckUtil {

    private static boolean isCreatedCrcTable = false;
    private static short[] crcTable = new short[256];
    public static short cnCrc16 = (short)0x8005;

    /**
     * checkSum
     * @param data 검증 데이터
     * @param checkCrc crc
     * @return true : 성공, false 실패
     */
    public static boolean checkSum(byte[] data,  byte[] checkCrc) {
        short crc = CRCCheckUtil.crcUpdate(data, data.length);
        byte[] bCrc = fnShortToBytes(crc,1);

        if (bCrc[0] == checkCrc[0] && bCrc[1] == checkCrc[1]) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * crc 테이블 생성
     * @param poly
     */
    private static void crcGenerateTable(short poly) {
        short data;
        short accum;
        for(short i = 0; Short.toUnsignedInt(i) < 256; i++) {
            data = (short)(Short.toUnsignedInt(i) << 8);
            accum = 0;
            for(short j = 0; Short.toUnsignedInt(j) < 8; j++) {
                if(((Short.toUnsignedInt(data) ^ Short.toUnsignedInt(accum)) & 0x8000) != 0) {
                    accum = (short)(Short.toUnsignedInt(accum) << 1 ^ Short.toUnsignedInt(poly));
                } else {
                    accum = (short)(Short.toUnsignedInt(accum) << 1);
                }
                data = (short)(Short.toUnsignedInt(data) << 1);
            }

            crcTable[Short.toUnsignedInt(i)] = accum;
        }
        isCreatedCrcTable = true;
    }

    private static short crcUpdate(byte[] data, int size) {
        int dataIndex = 0;
        short accum = 0;
        if (!isCreatedCrcTable) {
            crcGenerateTable(cnCrc16);
        }
        for(short i = 0; Short.toUnsignedInt(i) < size; i++) {
            accum = (short)(Short.toUnsignedInt(accum) << 8 ^ Short.toUnsignedInt(crcTable[Short.toUnsignedInt(accum) >> 8 ^ Byte.toUnsignedInt(data[dataIndex++])]));
        }
        return accum;
    }



    private static byte[] fnShortToBytes(short value, int order){
        byte[] temp;
        temp = new byte[]{ (byte)((value & 0xFF00) >> 8), (byte)(value & 0x00FF) };
        temp = fnChangeByteOrder(temp,order);
        return temp;
    }

    private static byte[] fnChangeByteOrder(byte[] value,int Order){
        int idx = value.length;
        byte[] Temp = new byte[idx];

        if(Order == 1){
            Temp = value;
        }else if(Order == 0){
            for(int i=0;i<idx;i++) {
                Temp[i] = value[idx-(i+1)];
            }
        }
        return Temp;
    }
}
반응형