IT/DEV Study

[통신/네트워크] CRC 정리. CRC-16 C#/VB 코드. 온라인 CRC 변환기 링크.

Ella.J 2023. 2. 7. 14:16
728x90
반응형

https://ko.wikipedia.org/wiki/%EC%88%9C%ED%99%98_%EC%A4%91%EB%B3%B5_%EA%B2%80%EC%82%AC

 

순환 중복 검사 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 순환 중복 검사(巡環重復檢査), CRC(cyclic redundancy check)는 네트워크 등을 통하여 데이터를 전송할 때 전송된 데이터에 오류가 있는지를 확인하기 위한 체크값을

ko.wikipedia.org

위키 백과 참고하여 정리한 글입니다.

 


CRC (Cyclic Redundancy Check) 순환 중복 검사.

: 네트워크 등을 통하여 데이터 전송 시 데이터에 오류가 있는지를 확인하기 위한 체크값을 결정하는 방식. 데이터를 전송하기 전에 주어진 데이터 값에 따라 CRC 값을 계산하여 데이터에 붙여 전송하고, 받은 데이터의 CRC 값을 계산하여 Error Check가 가능하다.

데이터 전송 시 CRC Check Query 예시


개요.

CRC는 Commutative ring(가환환)의 나눗셈(mod-2의 덧셈-XOR-)에 기반한다.

(참고) Mod-2 연산 : 기본적으로 나눗셈 연산(mod)에 기초. 2로 나눈 나머지를 염두에 두고 계산하면 됨.

쉽게 말하면, 이는 한 비트의 계수를 갖는 다항식(Polynomial)의 집합이고, 이 다항식들 간의 사칙연산은 다시 계수들을 가장 아래 비트만 따도록 정의하여 한 비트 계수의 다항식으로 표현하도록 정의된다.

(예시)

덧셈 예시

위 식에서 2는 이진수로 10이고, 따라서 정의에 의해서 가장 아래비트인 0을 취하고 그 이상의 자리수는 버려 위와 같은 결과가 나온다.

곱셈 예시
나눗셈 예시

위 식에서는 나눗셈의 몫은 X^2 + 1이고 나머지는 -1이고, -1은 홀수이기 때문에 1이 된다.

 

모든 데이터 비트 스트림은 이러한 다항식의 계수로 상상할 수 있다.

즉, 101은 0번자리가 1, 1번 자리가 0, 2번 자리가 1이므로, 다항식 x^2 + 1에 해당한다고 볼 수 있다.

 

CRC 값은 정해진 특정 다항식으로 데이터 스트링으로 주어진 다항식을 나누어 그 나머지를 나타내는 특정 길이의 비트 스트링이 된다. 특정한 CRC는 사용되는 다항식으로 정의하며, n비트 CRC를 만드는 데는 x^n+...+1 꼴의 1차 다항식이 필요한다. 이를 기본적으로 (n+1) 비트 문자열로 나타낼 수 있지만, 차수가 가장 높은 x^n 항의 계수는 항상 1이기 때문에 이 항을 빼고 n비트 문자열로 나타낼 수 있다.

(예시)

CRC-16 표준에 사용되는 다항식인 x^15 + x^2 + 1은 비트 순서에 따라 0x8005나 0xa001로 나타낼 수 있다.


CRC 다항식들과 종류들.

CRC에는 비트수에 따라 CRC-8, CRC-16, CRC-32 등이 존재한다.

CRC 값을 계산하려면 비트수와 다항식을 결정해야 하며, 정해진 값을 토대로 계산하면 입력된 메시지는 오류가 없는 경우 항상 같은 CRC 값이 나온다.

이름 사용 다항식
정상 역방향 역방향의 역수
CRC-8-CCITT I.432.1; ATM HEC, ISDN HEC and cell delineation 0x07 0xE0 0x83
CRC-8-Dallas/Maxim 1-Wire bus 0x31 0x8C 0x98
CRC-8   0xD5 0xAB 0xEA
CRC-8-SAE J1850 AES3 0x1D 0xB8 0x8E
CRC-8-WCDMA   0x9B 0xD9 0xCD
CRC-16-IBM Bisync(Binary Synchronous Communications), Modbus, USB, ANSI X3.28, SIA DC-07, 기타. CRC-16 또는 CRC-16-ANSI로 알려짐. 0x8005 0xA001 0xC002
CRC-16-CCITT X.25, V.41, HDLC FCS, XMODEM, Bluetooth, PACTOR, SD 카드,기타. CRC-CCITT라고도 함. 0x1021 0x8408 0x8810
CRC-16-T10-DIF SCSI DIF 0x8BB7 0xEDD1 0xC5DB
CRC-16-DNP DNP, IEC 870, M-Bus 0x3D65 0xA6BC 0x9EB2
CRC-16-DECT 무선전화 0x0589 0x91A0 0x82C4
CRC-16-ARINC ACARS 응용 0xA02B 0xD405 0xD015
CRC-32 HDLC, ANSI X3.66, ITU-T V.42, 이더넷, Serial ATA, MPEG-2, PKZIP, Gzip, Bzip2, PNG, many others 0x04C11DB7 0xEDB88320 0x82608EDB
CRC-32C (Castagnoli) iSCSI, SCTP, G.hn payload, SSE4.2, Btrfs, ext4 0x1EDC6F41 0x82F63B78 0x8F6E37A0
CRC-32K (Koopman)   0x741B8CD7 0xEB31D82E 0xBA0DC66B
CRC-32Q aviation; AIXM 0x814141AB 0xD5828281 0xC0A0A0D5

소프트웨어 구현.

소프트웨어에서 보통 CRC를 적용할 때 바이트 단위로 구현하지만, 비트단위로 계산해야 하는 경우에는 속도등의 문제로 오히려 CRC 테이블 기법을 많이 사용한다.

실제 소프트웨어 코드 방식으로 사용되는 방법.

1. CRC 테이블을 만들어 변수화 하고,

2. 데이터를 바이트단위로 테이블 탐색을 통해 CRC 값을 결정한다.

 

(CRC-16/ARC  C# 코드 예시)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private static ushort[] CRCtable = {
    0X00000XC0C10XC1810X01400XC3010X03C00X02800XC241,
    0XC6010X06C00X07800XC7410X05000XC5C10XC4810X0440,
    0XCC010X0CC00X0D800XCD410X0F000XCFC10XCE810X0E40,
    0X0A000XCAC10XCB810X0B400XC9010X09C00X08800XC841,
    0XD8010X18C00X19800XD9410X1B000XDBC10XDA810X1A40,
    0X1E000XDEC10XDF810X1F400XDD010X1DC00X1C800XDC41,
    0X14000XD4C10XD5810X15400XD7010X17C00X16800XD641,
    0XD2010X12C00X13800XD3410X11000XD1C10XD0810X1040,
    0XF0010X30C00X31800XF1410X33000XF3C10XF2810X3240,
    0X36000XF6C10XF7810X37400XF5010X35C00X34800XF441,
    0X3C000XFCC10XFD810X3D400XFF010X3FC00X3E800XFE41,
    0XFA010X3AC00X3B800XFB410X39000XF9C10XF8810X3840,
    0X28000XE8C10XE9810X29400XEB010X2BC00X2A800XEA41,
    0XEE010X2EC00X2F800XEF410X2D000XEDC10XEC810X2C40,
    0XE4010X24C00X25800XE5410X27000XE7C10XE6810X2640,
    0X22000XE2C10XE3810X23400XE1010X21C00X20800XE041,
    0XA0010X60C00X61800XA1410X63000XA3C10XA2810X6240,
    0X66000XA6C10XA7810X67400XA5010X65C00X64800XA441,
    0X6C000XACC10XAD810X6D400XAF010X6FC00X6E800XAE41,
    0XAA010X6AC00X6B800XAB410X69000XA9C10XA8810X6840,
    0X78000XB8C10XB9810X79400XBB010X7BC00X7A800XBA41,
    0XBE010X7EC00X7F800XBF410X7D000XBDC10XBC810X7C40,
    0XB4010X74C00X75800XB5410X77000XB7C10XB6810X7640,
    0X72000XB2C10XB3810X73400XB1010X71C00X70800XB041,
    0X50000X90C10X91810X51400X93010X53C00X52800X9241,
    0X96010X56C00X57800X97410X55000X95C10X94810X5440,
    0X9C010X5CC00X5D800X9D410X5F000X9FC10X9E810X5E40,
    0X5A000X9AC10X9B810X5B400X99010X59C00X58800X9841,
    0X88010X48C00X49800X89410X4B000X8BC10X8A810X4A40,
    0X4E000X8EC10X8F810X4F400X8D010X4DC00X4C800X8C41,
    0X44000X84C10X85810X45400X87010X47C00X46800X8641,
    0X82010X42C00X43800X83410X41000X81C10X80810X4040
};
 
public static UInt16 CalculateCRC(byte[] data)
{
    ushort crc = 0xFFFF;
 
    foreach (byte datum in data)
    {
        crc = (ushort)((crc >> 8) ^ CRCtable[(crc ^ datum) & 0xFF]);
    }
 
    return crc;
}
cs

 

(CRC-16/ARC  VisualBasic 코드 예시)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Private CRCtable As UShort() = {
    &H0, &HC0C1, &HC181, &H140, &HC301, &H3C0, &H280, &HC241,
    &HC601, &H6C0, &H780, &HC741, &H500, &HC5C1, &HC481, &H440,
    &HCC01, &HCC0, &HD80, &HCD41, &HF00, &HCFC1, &HCE81, &HE40,
    &HA00, &HCAC1, &HCB81, &HB40, &HC901, &H9C0, &H880, &HC841,
    &HD801, &H18C0, &H1980, &HD941, &H1B00, &HDBC1, &HDA81, &H1A40,
    &H1E00, &HDEC1, &HDF81, &H1F40, &HDD01, &H1DC0, &H1C80, &HDC41,
    &H1400, &HD4C1, &HD581, &H1540, &HD701, &H17C0, &H1680, &HD641,
    &HD201, &H12C0, &H1380, &HD341, &H1100, &HD1C1, &HD081, &H1040,
    &HF001, &H30C0, &H3180, &HF141, &H3300, &HF3C1, &HF281, &H3240,
    &H3600, &HF6C1, &HF781, &H3740, &HF501, &H35C0, &H3480, &HF441,
    &H3C00, &HFCC1, &HFD81, &H3D40, &HFF01, &H3FC0, &H3E80, &HFE41,
    &HFA01, &H3AC0, &H3B80, &HFB41, &H3900, &HF9C1, &HF881, &H3840,
    &H2800, &HE8C1, &HE981, &H2940, &HEB01, &H2BC0, &H2A80, &HEA41,
    &HEE01, &H2EC0, &H2F80, &HEF41, &H2D00, &HEDC1, &HEC81, &H2C40,
    &HE401, &H24C0, &H2580, &HE541, &H2700, &HE7C1, &HE681, &H2640,
    &H2200, &HE2C1, &HE381, &H2340, &HE101, &H21C0, &H2080, &HE041,
    &HA001, &H60C0, &H6180, &HA141, &H6300, &HA3C1, &HA281, &H6240,
    &H6600, &HA6C1, &HA781, &H6740, &HA501, &H65C0, &H6480, &HA441,
    &H6C00, &HACC1, &HAD81, &H6D40, &HAF01, &H6FC0, &H6E80, &HAE41,
    &HAA01, &H6AC0, &H6B80, &HAB41, &H6900, &HA9C1, &HA881, &H6840,
    &H7800, &HB8C1, &HB981, &H7940, &HBB01, &H7BC0, &H7A80, &HBA41,
    &HBE01, &H7EC0, &H7F80, &HBF41, &H7D00, &HBDC1, &HBC81, &H7C40,
    &HB401, &H74C0, &H7580, &HB541, &H7700, &HB7C1, &HB681, &H7640,
    &H7200, &HB2C1, &HB381, &H7340, &HB101, &H71C0, &H7080, &HB041,
    &H5000, &H90C1, &H9181, &H5140, &H9301, &H53C0, &H5280, &H9241,
    &H9601, &H56C0, &H5780, &H9741, &H5500, &H95C1, &H9481, &H5440,
    &H9C01, &H5CC0, &H5D80, &H9D41, &H5F00, &H9FC1, &H9E81, &H5E40,
    &H5A00, &H9AC1, &H9B81, &H5B40, &H9901, &H59C0, &H5880, &H9841,
    &H8801, &H48C0, &H4980, &H8941, &H4B00, &H8BC1, &H8A81, &H4A40,
    &H4E00, &H8EC1, &H8F81, &H4F40, &H8D01, &H4DC0, &H4C80, &H8C41,
    &H4400, &H84C1, &H8581, &H4540, &H8701, &H47C0, &H4680, &H8641,
    &H8201, &H42C0, &H4380, &H8341, &H4100, &H81C1, &H8081, &H4040
}
 
Public Function CalculateCRC(ByVal data As Byte()) As UInt16
    Dim crc As UShort = &HFFFF
    For i = 0 To data.Length - 1
        crc = CUShort((crc >> 8) Xor CRCtable((crc Xor data(i)) And &HFF))
    Next
    Return crc
End Function
cs

온라인 CRC 변환기.

https://crccalc.com/

 

Online CRC-8 CRC-16 CRC-32 Calculator

Input: ASCII HEX

crccalc.com

위 링크에서 데이터를 입력하면 CRC로 변환할 수 있으며, 각 CRC 알고리즘의 테이블 값도 확인할 수 있다.


 

728x90
반응형