In the IoT platform design process, my middleware needs to process the package from the hardware side, on the other hand, it needs to process the package from the client side, including the Web side and the mobile terminal, etc. So it is very necessary to write a unified CRC authentication.
So, at the beginning of the design, what exactly is CRC certification? The so-called CRC authentication, refers to the hardware side or the user before data transmission, through a set of algorithms, the data to be transmitted, through the addition of inspection, calculate its check code, attached to the final package, and then the middleware received this package, the package to parse, take out the data content part, And then to the package to re-check the CRC, if the addition of the test results and the package is accompanied by the CRC checksum data consistent, then that the packet is complete, available. Conversely, it proves that the package is problematic.
So from the above process, we can see that the CRC contains so several important content: CRC generation algorithm, CRC parsing algorithm.
CRC Search Table algorithm
First, the CRC generation algorithm is as follows, from the Internet can be found in a bunch of random, we use here is CRC16 bit:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Namespace dsmiddlewire.lib{public class CRC16 {Private Const int crc_len = 0; Table of CRC values for High-order byte private readonly byte[] _auchcrchi = new byte[] {0x00 , 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x 0xC1, 0x00, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 , 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0X81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0X81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0 X81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x0 1, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0 XC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x4 1, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0 X00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0X81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40}; Table of CRC values for Low-order byte private readonly byte[] _auchcrclo = new byte[] {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xc4, 0x04, 0xCC, 0x0C, 0x0D, 0 XCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xc9, 0x09, 0x08, 0xC8, 0xd8, 0x18, 0x19, 0xD 9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xd4, 0xd5, 0x15, 0xD7, 0x17, 0x16, 0xd6, 0xd2, 0x12, 0x13, 0xd3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xf3, 0xF2, 0x32, 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4, 0x3C, 0xFC, 0xFD, 0x3d, 0xFF, 0x3F, 0x3 E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xf9, 0xF8, 0x38, 0x28, 0xe8, 0xe9,0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2e, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0x E5, 0x27, 0xE7, 0xe6, 0x26, 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xa1 , 0x63, 0xa3, 0xa2, 0x62, 0x66, 0xa6, 0xa7, 0x67, 0xa5, 0x65, 0x64, 0xa4, 0x6c, 0xAC, 0xAD, 0x6d, 0xAF, 0x6F, 0x6e, 0xAE, 0xAA, 0x6A, 0x6b, 0xAB, 0x69, 0xa9, 0xa8, 0x68, 0x78, 0xb8, 0xb9, 0x79, 0xBB, 0x7B, 0x 7 A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7d, 0xBD, 0xBC, 0x7C, 0xb4, 0x74, 0x75, 0xb5, 0x77, 0xb7, 0xb6 , 0x76, 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71, 0x70, 0xb0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9c, 0x5C, 0x5d, 0x9d, 0x5f, 0x9F, 0x9E, 0x5E, 0x5A, 0x 9A, 0x9b, 0x5b, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8b, 0x8A, 0x4A, 0x4E, 0x8E , 0x8F, 0x4f, 0x8d, 0x4d, 0x4C, 0x8c, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40}; <summary>///CRC16 validation code///</summary>//<param name= "buffer" ></param> <returns></returns> internal ushort CALCULATECRC16 (byte[] buffer) {byte Crchi = 0xFF; High CRC byte initialized byte Crclo = 0xFF; Low CRC, Byte initialized for (int i = 0; i < buffer. Length-crc_len; i++) {int crcindex = Crchi ^ buffer[i];//Calculate the CRC lookup index Crchi = (byte) (crclo ^ _auchcrchi[crcindex]); Crclo = _auchcrclo[crcindex]; } return (ushort) (Crchi << 8 | crclo); }///<summary>//CRC16 validation code///</summary>//<param name= "Strpar" ></ param>//<returns></returns> public static string CalculateCrc16 (String strpar) {string retstr = new CRC16 (). CALCULATECRC16 (System.Text.Encoding.Default.GetBytes (Strpar)). ToString (); while (Retstr.length < 5) {retstr = "0" + retstr; } return RETSTR; } }}
Above is the use of table method to generate CRC16 check code function, the mechanism is: I will get a CRC through the operation of the code, and then divided by 256 will get a high value, the remaining 256 will get the low value, and finally the high and low values of the operation, is our check code.
CRC plus Recipe method
Although the above function is available, but produces a string type of value, in the data transfer process, is to be converted to byte transmission, so here we need to convert the resulting value to a byte type, and then into the data content of a byte array, sent to the middleware:
/* * CRC encapsulation method sent to the underlying hardware * 1.var crcgenerate = GETCRC (result); Get the CRC code: 14321 * 2. Get high, low value: 14321/256 = 55, 14321%256=241 * 3. To byte, appended to the last two-bit byte array, passed to the hardware * */public static byte[] CONSTRUCTMESSAGEWITHCRC (String message) {//Information body, plus a delimiter V AR messagetoconstruct = message + "|"; Calculate the CRC code var Crccode = CRC16. CALCULATECRC16 (messagetoconstruct); var crccodeshort = ushort. Parse (Crccode); CRC code High var Crchigh = byte. Parse ((crccodeshort/256). ToString ()); CRC code low var crclow = byte. Parse ((crccodeshort% 256). ToString ()); var messagebytes = Encoding.Default.GetBytes (messagetoconstruct); var messagelength = messagebytes.length; var MESSAGEBYTESWITHCRC = new Byte[messagelength + 2]; Array.copy (messagebytes, 0, MESSAGEBYTESWITHCRC, 0, messagelength); Put the CRC code to the last two bits of the array Messagebyteswithcrc[messagelength] = Crchigh; Messagebyteswithcrc[messagelength + 1] = Crclow; return MESSAGEBYTESWITHCRC; }
I explained the above code: MESSAGETOCONSTRUCT is our data Content section, we first calculate the data content through the CRC16.CALCULATECRC16 function of its checksum, and then put its highest and lowest bits in a byte array, and then sent out.
CRC Calibration Method
So since there is CRC check code generation, also need the CRC check code parsing process, so-called attack must have anti-:
public static bool CHECKMESSAGECRC (byte[] message, out string messagereceived) {//Received data length var messagelength = message. Length; Received data information var messagereceivedstrbytes = new Byte[messagelength-2]; Array.copy (message, 0, messagereceivedstrbytes, 0, messageLength-2); CRC check code fixed 2 bytes var messagereceivedcrcbytes = new Byte[2]; Array.copy (Message, messageLength-2, Messagereceivedcrcbytes, 0, 2); Get Transfer data var messagecalculatedstring = Encoding.Default.GetString (messagereceivedstrbytes); messagereceived = messagecalculatedstring; Get CRC check code var CURRENTCRC = byte. Parse (Messagereceivedcrcbytes[0]. ToString ()) * + + byte. Parse (Messagereceivedcrcbytes[1]. ToString ()); CRC Check for data section var result = ushort. Parse (CRC16. CALCULATECRC16 (messagecalculatedstring)); if (CURRENTCRC = = result) return true; return false; }
The above process is the docking received packets, the data part and the CRC check code part is separated (the verification code part is clearly accounted for the last two bytes, from the CRC plus part we can see). The data section is then recalculated to the CRC check code, and the accompanying comparison.
Something
Okay, so that's all the CRC checksum content, including the addition and verification process, you understand?
To say the truth, turned a lot of articles, none of my this article to speak thoroughly. Because I was at the beginning of the design, but also to find online articles, but are not successful, and then do the hardware of the people to communicate, and then successfully formed.
IoT platform design experience: CRC checks You don't know