當數據幀長度在8bits-128bits范圍內時,推薦CRC-8(CRC-8能夠減少額外比特的開銷,且有更好的性能表現)
當數據幀長度在128bits-2048bits范圍內時,推薦CRC-12,CRC-16,CRC-CCITT(CRC-12額外比特的開銷更小,且用於6bit字符流的傳輸;對於16bits的標准,更推薦美國標准CRC-16,性能略優於CRC-CCITT);
當因數據幀長度更長、信道不穩定等情況而需要更高的性能時,CRC-32、CRC-32C將是更好的選擇;
Redis-基於字節查表法的CRC校驗碼生成算法
CRC16的校驗碼是兩個字節,所以Redis的源碼中使用了 uint16_t類型(unsigned short int)
CRC16要校驗的數據位是8位
在求解CRC校驗碼的過程中,會用到模二除,實際我們最后不關心它的商Q(x),只關心關心余數R(x),它也是兩個字節的大小
余數R(x)分為高字節RH(x)和低字節RL(x)兩個部分:R(x) = RH(x) * X^8 + RL(x) (這個+,可以理解成異或,也可以理解成+號)
任何數和0異或結果還是這個數
流程
- CRC-16碼由兩個字節構成,在開始時CRC寄存器的每一位都預置為1
- 然后把CRC寄存器與8-bit的數據進行異或
- 之后對CRC寄存器從高到低進行移位,在最高位(MSB)的位置補零,而最低位(LSB,移位后已經被移出CRC寄存器)如果為1,則把寄存器與預定義的多項式碼進行異或,否則如果LSB為零,則無需進行異或。
- 重復上述的由高至低的移位8次,第一個8-bit數據處理完畢
- 用此時CRC寄存器的值與下一個8-bit數據異或並進行如前一個數據似的8次移位。
- 所有的字符處理完成后CRC寄存器內的值即為最終的CRC值。
Redis使用的是CRC-16-CCITT標准,即G(x)為:x^16 + x^12 + x^5 + 1 。
G(x)的通常表征方式是將多項式轉換成二進制: 1 0001 0000 0010 0001。用十六進制表示為:0x11021。