CRC is Cyclic Redundancy Check (Cyclic Redundancy Check): It is the most commonly used error check check code in the field of data communication. Its characteristic is that the length of the information field and the verification field can be selected arbitrarily. Cyclic redundancy checking (CRC) is a data transmission error detection function that performs polynomial calculations on the data and attaches the result to the frame. The receiving device also executes a similar algorithm to ensure the correctness and integrity of the data transmission.
CRC algorithm parameter model explanation:
- NAME: Parameter model name.
- WIDTH: Width, that is, the number of CRC bits.
- POLY: The abbreviation of the generated item, expressed in hexadecimal. For example: CRC-32 is 0x04C11DB7, ignoring the highest bit "1", that is, the complete generation term is 0x104C11DB7.
- INIT: This is the initial preset value of the register (crc) at the beginning of the algorithm, and is represented in hexadecimal.
- REFIN: Whether each byte of the data to be tested is inverted bitwise, True or False.
- REFOUT: Whether the entire data is bit-inverted after calculation, before XOR output, True or False.
- XOROUT: The final CRC value is obtained after the calculation result is XORed with this parameter.
/// ********************************************************************** /// Name: CRC-4/ITU x4+x+1 /// Poly: 0x03 /// Init: 0x00 /// Refin: true /// Refout: true /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc1(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0x0C);//0x0C = (reverse 0x03)>>(8-4) else crc = (byte)(crc >> 1); } } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-5/EPC x5+x3+1 /// Poly: 0x09 /// Init: 0x09 /// Refin: false /// Refout: false /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc2(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0x48;// Initial value: 0x48 = 0x09<<(8-5) for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 0x80) > 0) crc = (byte)((crc << 1) ^ 0x48);// 0x48 = 0x09<<(8-5) else crc = (byte)(crc << 1); } } return new byte[] { (byte)(crc >> 3) }; } /// ********************************************************************** /// Name: CRC-5/ITU x5+x4+x2+1 /// Poly: 0x15 /// Init: 0x00 /// Refin: true /// Refout: true /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc3(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0x15);// 0x15 = (reverse 0x15)>>(8-5) else crc = (byte)(crc >> 1); } } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-5/USB x5+x2+1 /// Poly: 0x05 /// Init: 0x1F /// Refin: true /// Refout: true /// Xorout: 0x1F ///************************************************************************* public static byte[] Crc4(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0x1F;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0x14);// 0x14 = (reverse 0x05)>>(8-5) else crc = (byte)(crc >> 1); } } return new byte[] {(byte)( crc ^ 0x1F) }; } /// ********************************************************************** /// Name: CRC-6/ITU x6+x+1 /// Poly: 0x03 /// Init: 0x00 /// Refin: true /// Refout: true /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc5(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0x30);// 0x30 = (reverse 0x03)>>(8-6) else crc = (byte)(crc >> 1); } } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-7/MMC x7+x3+1 /// Poly: 0x09 /// Init: 0x00 /// Refin: false /// Refout: false /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc6(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 0x80) > 0) crc = (byte)((crc << 1) ^ 0x12);// 0x12 = 0x09<<(8-7) else crc = (byte)(crc << 1); } } return new byte[] { (byte)(crc >> 1) }; } /// ********************************************************************** /// Name: CRC8 x8+x2+x+1 /// Poly: 0x07 /// Init: 0x00 /// Refin: false /// Refout: false /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc7(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 0x80) > 0) crc = (byte)((crc << 1) ^ 0x07); else crc = (byte)(crc << 1); } } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-8/ITU x8+x2+x+1 /// Poly: 0x07 /// Init: 0x00 /// Refin: false /// Refout: false /// Xorout: 0x55 ///************************************************************************* public static byte[] Crc8(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 0x80) > 0) crc = (byte)((crc << 1) ^ 0x07); else crc = (byte)(crc << 1); } } return new byte[] { (byte)(crc ^ 0x55) }; } /// ********************************************************************** /// Name: CRC-8/MAXIM x8+x5+x4+1 /// Poly: 0x31 /// Init: 0x00 /// Refin: true /// Refout: true /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc9(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0x8C);// 0x8C = reverse 0x31 else crc = (byte)(crc >> 1); } } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-8/ROHC x8+x2+x+1 /// Poly: 0x07 /// Init: 0xFF /// Refin: true /// Refout: true /// Xorout: 0x00 ///************************************************************************* public static byte[] Crc10(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte crc = 0xFF;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (byte)((crc >> 1) ^ 0xE0);// 0xE0 = reverse 0x07 else crc = (byte)(crc >> 1); } } return new byte[] { crc }; } /// Calculate Z1 protocol verification code static byte[] table = { 0x00, 0x1C, 0x38, 0x24, 0x70, 0x6C, 0x48, 0x54, 0xE0, 0xFC, 0xD8, 0xC4, 0x90, 0x8C, 0xA8, 0xB4, 0xDC, 0xC0, 0xE4, 0xF8, 0xAC, 0xB0, 0x94, 0x88, 0x3C, 0x20, 0x04, 0x18, 0x4C, 0x50, 0x74, 0x68, 0xA4, 0xB8, 0x9C, 0x80, 0xD4, 0xC8, 0xEC, 0xF0, 0x44, 0x58, 0x7C, 0x60, 0x34, 0x28, 0x0C, 0x10, 0x78, 0x64, 0x40, 0x5C, 0x08, 0x14, 0x30, 0x2C, 0x98, 0x84, 0xA0, 0xBC, 0xE8, 0xF4, 0xD0, 0xCC, 0x54, 0x48, 0x6C, 0x70, 0x24, 0x38, 0x1C, 0x00, 0xB4, 0xA8, 0x8C, 0x90, 0xC4, 0xD8, 0xFC, 0xE0, 0x88, 0x94, 0xB0, 0xAC, 0xF8, 0xE4, 0xC0, 0xDC, 0x68, 0x74, 0x50, 0x4C, 0x18, 0x04, 0x20, 0x3C, 0xF0, 0xEC, 0xC8, 0xD4, 0x80, 0x9C, 0xB8, 0xA4, 0x10, 0x0C, 0x28, 0x34, 0x60, 0x7C, 0x58, 0x44, 0x2C, 0x30, 0x14, 0x08, 0x5C, 0x40, 0x64, 0x78, 0xCC, 0xD0, 0xF4, 0xE8, 0xBC, 0xA0, 0x84, 0x98, 0xA8, 0xB4, 0x90, 0x8C, 0xD8, 0xC4, 0xE0, 0xFC, 0x48, 0x54, 0x70, 0x6C, 0x38, 0x24, 0x00, 0x1C, 0x74, 0x68, 0x4C, 0x50, 0x04, 0x18, 0x3C, 0x20, 0x94, 0x88, 0xAC, 0xB0, 0xE4, 0xF8, 0xDC, 0xC0, 0x0C, 0x10, 0x34, 0x28, 0x7C, 0x60, 0x44, 0x58, 0xEC, 0xF0, 0xD4, 0xC8, 0x9C, 0x80, 0xA4, 0xB8, 0xD0, 0xCC, 0xE8, 0xF4, 0xA0, 0xBC, 0x98, 0x84, 0x30, 0x2C, 0x08, 0x14, 0x40, 0x5C, 0x78, 0x64, 0xFC, 0xE0, 0xC4, 0xD8, 0x8C, 0x90, 0xB4, 0xA8, 0x1C, 0x00, 0x24, 0x38, 0x6C, 0x70, 0x54, 0x48, 0x20, 0x3C, 0x18, 0x04, 0x50, 0x4C, 0x68, 0x74, 0xC0, 0xDC, 0xF8, 0xE4, 0xB0, 0xAC, 0x88, 0x94, 0x58, 0x44, 0x60, 0x7C, 0x28, 0x34, 0x10, 0x0C, 0xB8, 0xA4, 0x80, 0x9C, 0xC8, 0xD4, 0xF0, 0xEC, 0x84, 0x98, 0xBC, 0xA0, 0xF4, 0xE8, 0xCC, 0xD0, 0x64, 0x78, 0x5C, 0x40, 0x14, 0x08, 0x2C, 0x30 }; public static byte[] Crc11(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; int i; byte crc = 0x00; int tableIndex; for (i = start; i < length; i++) { tableIndex = crc ^ (buffer[i] & 0xFF); crc = table[tableIndex]; } return new byte[] { crc }; } /// ********************************************************************** /// Name: CRC-12 x16+x12+x5+1 /// Poly: 0x80 /// Init: 0x0000 /// Refin: true /// Refout: true /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc12(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value short iQ = 0, iR = 0; for (int i = start; i < length; i++) { // Polynomial division // If the bit is 1 if ((buffer[i] & (0x80 >> iR)) > 0) { // Add 1 to the end of the remainder, otherwise add 0 crc |= 0x01; } // If the highest bit of the 12-bit divisor is 1, then the division is sufficient if (crc >= 0x1000) { crc ^= 0x180D; } crc <<= 1; iR++; if (8 == iR) { iR = 0; iQ++; } } // Process the 12 0s added later for (int i = 0; i < 12; i++) { if (crc >= 0x1000) { crc ^= 0x180D; } crc <<= 1; } crc >>= 1; byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/CCITT x16+x12+x5+1 /// Poly: 0x1021 /// Init: 0x0000 /// Refin: true /// Refout: true /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc13(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021 else crc = (ushort)(crc >> 1); } } byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/CCITT FALSE x16+x12+x5+1 /// Poly: 0x1021 /// Init: 0xFFFF /// Refin: false /// Refout: false /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc14(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0xFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= (ushort)(buffer[i] << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ 0x1021); else crc = (ushort)(crc << 1); } } byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/DNP x16+x13+x12+x11+x10+x8+x6+x5+x2+1 /// Poly: 0x3D65 /// Init: 0x0000 /// Refin: true /// Refout: true /// Xorout: 0xFFFF ///************************************************************************* public static byte[] Crc15(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0xA6BC);// 0xA6BC = reverse 0x3D65 else crc = (ushort)(crc >> 1); } } byte[] ret = ((ushort)~crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/IBM x16+x15+x2+1 /// Poly: 0x8005 /// Init: 0x0000 /// Refin: true /// Refout: true /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc16(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 else crc = (ushort)(crc >> 1); } } byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/MAXIM x16+x15+x2+1 /// Poly: 0x8005 /// Init: 0x0000 /// Refin: true /// Refout: true /// Xorout: 0xFFFF ///************************************************************************* public static byte[] Crc17(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 else crc = (ushort)(crc >> 1); } } byte[] ret = ((ushort)~crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/MODBUS x16+x15+x2+1 /// Poly: 0x8005 /// Init: 0xFFFF /// Refin: true /// Refout: true /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc18(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0xFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 else crc = (ushort)(crc >> 1); } } byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/USB x16+x15+x2+1 /// Poly: 0x8005 /// Init: 0xFFFF /// Refin: true /// Refout: true /// Xorout: 0xFFFF ///************************************************************************* public static byte[] Crc19(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0xFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 else crc = (ushort)(crc >> 1); } } byte[] ret = ((ushort)~crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/X25 x16+x12+x5+1 /// Poly: 0x1021 /// Init: 0xFFFF /// Refin: true /// Refout: true /// Xorout: 0xFFFF ///************************************************************************* public static byte[] Crc20(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0xFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021 else crc = (ushort)(crc >> 1); } } byte[] ret = ((ushort)~crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC-16/XMODEM x16+x12+x5+1 /// Poly: 0x1021 /// Init: 0x0000 /// Refin: false /// Refout: false /// Xorout: 0x0000 ///************************************************************************* public static byte[] Crc21(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; ushort crc = 0;// Initial value for (int i = start; i < length; i++) { crc ^= (ushort)(buffer[i] << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ 0x1021); else crc = (ushort)(crc << 1); } } byte[] ret = (crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 /// Poly: 0x04C11DB7 /// Init: 0xFFFFFFFF /// Refin: true /// Refout: true /// Xorout: 0xFFFFFFFF ///************************************************************************* public static byte[] Crc22(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; uint crc = 0xFFFFFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= buffer[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) > 0) crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7 else crc = crc >> 1; } } byte[] ret = (~crc); (ret); return ret; } /// ********************************************************************** /// Name: CRC32/MPEG-2 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 /// Poly: 0x04C11DB7 /// Init: 0xFFFFFFFF /// Refin: false /// Refout: false /// Xorout: 0x00000000 ///************************************************************************* public static byte[] Crc23(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; uint crc = 0xFFFFFFFF;// Initial value for (int i = start; i < length; i++) { crc ^= (uint)(buffer[i] << 24); for (int j = 0; j < 8; j++) { if ((crc & 0x80000000) > 0) crc = (crc << 1) ^ 0x04C11DB7; else crc = crc << 1; } } byte[] ret = (crc); (ret); return ret; }
Checksum, in the fields of data processing and data communication, is used to verify the sum of a set of data items at a destination. It is usually expressed in hexadecimal. If the value of the checksum exceeds the FF in hexadecimal, that is, 255, its complement is required as the checksum. It is usually used to ensure the integrity and accuracy of data in communication, especially in long-distance communication.
public static byte[] allAdd(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || == 0) return null; if (start < 0) return null; if (len == 0) len = - start; int length = start + len; if (length > ) return null; byte bcc = 0;// Initial value for (int i = start; i < len; i++) { bcc ^= buffer[i]; } return new byte[] { bcc }; }
This is the article about the four common data verification methods (CRC verification, LRC verification, BCC verification, accumulation and verification) implemented in C#. For more related C# data verification content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!