- 數據完整性校驗
在 數據錄入、通信協議(CAN、LIN、Ethernet) 和 存儲(Flash、EEPROM) 領域,數據校驗(Error Checking) 是確保 數據完整性和正確性的關鍵技術
示例:當我們從互聯網上下載的軟件或者文件是否能打開,是否在傳輸過程中丟包決定了是否能使用和查看,很多資源站下載文件時會提供一個md5校驗碼,驗證文件是否完整可以通過md5 文件獲取到校驗碼,與下載站提供的校驗碼一致就能確定文件是完整的。
以下部分將提供幾種常用的完整性校驗的技術:
· 奇偶校驗(Parity Check) - 用于簡單錯誤檢測
奇偶校驗是一種簡單的錯誤檢測機制,它通過計算數據中 1 的個數來檢查數據是否發 生錯誤。
適用于低速數據傳輸(如 LIN 總線、UART 通信)
常用于加密技術,如:des加密技術
奇偶校驗的基本原理:
奇偶校驗通過統計數據中1的個數,然后添加一位校驗碼,使得數據中1的總數為奇數(奇校驗)或偶數(偶校驗)。當接收方接 收到數據后,再次計算1的個數,并根據校驗位的設置驗證數據的完整性。如果檢測到錯誤,接收方會要求重新發送數據
代碼實現:
計算奇偶校驗
uint8_t Compute_Parity(uint8_t data)
{
????uint8_t parity = 0;
????while (data)
????{
????????parity ^= (data & 1); ?// 計算 1 的個數
????????data >>= 1;
????}
????return parity;
}
發送數據:
uint8_t data = 0x53; // 01010011
uint8_t parity = Compute_Parity(data);
uint8_t frame = (data << 1) | parity; ?// 生成帶校驗位的數據
接收數據:
uint8_t received_data = frame >> 1;
uint8_t received_parity = frame & 1;
if (Compute_Parity(received_data) != received_parity)
{
????printf("數據錯誤!\n");
}
以DES技術實現原理為例:
DES特點
對稱算法:加密和解密使用同一秘鑰
分組加密算法:以64位為分組。64位明文輸入,64位密文輸出。
有效秘鑰長度為56位秘鑰通常表示為64位數,但每個第8位用作奇偶校驗,可以忽略。
代替和置換DES算法是兩種加密技術的組合:混亂和擴散。先替代后置換。
易于實現:DES算法只是使用了標準的算術和邏輯運算,其作用的數最多也只有64 位,因此用70年代末期的硬件技術很容易實現算法的重復特性使得它可以非常理想地用在一個專用芯片中。
可通過多重加密,提高安全等級
入口參數
Key為7個字節共56位,是DES算法的工作密鑰
Data為8個字節64位,是要被加密或被解密的數據
Mode為DES的工作方式,有兩種:加密或解密
基本原則
DES設計中使用了分組密碼設計的兩個原則:混淆(confusion)和擴散(diffusion),其目的是抗擊敵手對密碼系統的統計分析。
混淆是使密文的統計特性與密鑰的取值之間的關系盡可能復雜化,以使密鑰和明文以及密文之間的依賴性對密碼分析者來說是無法利用的。
擴散的作用就是將每一位明文的影響盡可能迅速地作用到較多的輸出密文位中,以便在大量的密文中消除明文的統計結構,并且使每一位密鑰的影響盡可能迅速地擴展到較多的密文位中,以防對密鑰進行逐段破譯。
算法描述
輸入64位明文數據,并進行初始置換IP
在初始置換IP后,明文數據再被分為L0和R0左右兩部分,每部分32位
在秘鑰的控制下,經過16輪運算(f)
16輪后,左、右兩部分交換,并連接再一起,再進行逆置換
輸出64位密文
DES算法過程
子密鑰生成流程
DES算法由64位密鑰產生16輪的48位子密鑰。主要過程如下:
把密鑰的奇偶校驗位忽略不參與計算,即每個字節的第8位,將64位密鑰降至56位,然后根據選擇置換表PC-1將這56位分成兩塊C0(28位)和D0(28位)
將C0和D0進行循環左移變化(注:每輪循環左移的位數由輪數決定),變換后生成C1和D1,然后C1和D1合并,并通過選擇置換表PC-2生成子密鑰K1(48位)
C1和D1再次經過循環左移變換,生成C2和D2,然后C2和D2合并,通過選擇置換PC-2生成密鑰K2(48位)
以此類推,得到K16(48位)
?
· CRC 校驗(Cyclic Redundancy Check) - 用于強校驗
CRC(Cyclic Redundancy Check,循環冗余校驗)是一種強大的錯誤檢測機制,用于檢測 數據傳輸 / 存儲中的錯誤。
廣泛應用于 CAN 總線、LIN、FlexRay、Ethernet、Flash 存儲。
?CRC 校驗步驟
發送端計算 CRC 值,并將其附加到數據幀。
接收端重新計算 CRC,如果計算出的 CRC 與收到的 CRC 不一致,則數據錯誤
Crc-8計算:
uint8_t CRC8_Table[256] = { /* 預計算的 CRC-8 查找表 */ };
uint8_t Compute_CRC8(uint8_t* data, uint8_t len)
{
????uint8_t crc = 0xFF;
????for (int i = 0; i < len; i++)
????{
????????crc = CRC8_Table[crc ^ data[i]];
????}
????return crc;
}
發送crc:
uint8_t message[] = {0x12, 0x34, 0x56};
uint8_t crc = Compute_CRC8(message, sizeof(message));
message[3] = crc; ?// 附加 CRC
接收crc:
uint8_t received_crc = message[3];
if (Compute_CRC8(message, 3) != received_crc)
{
????printf("數據錯誤!\n");
}
· Checksum(校驗和) - 用于簡單完整性校驗
Checksum(校驗和) 是一種簡單的錯誤檢測方法,它將 所有數據的二進制數值相加,并將 結果的低字節作為校驗和。
三種完整性校驗對比:
校驗方法 | 適用場景 | 優點 | 缺點 |
奇偶校驗 | UART、LIN | 計算簡單 | 只能檢測?1-bit?錯誤 |
Checksum | EEPROM、Flash | 計算快,適合小數據 | 不能檢測位翻轉 |
CRC | CAN、Ethernet、UDS | 高精度錯誤檢測 | 計算復雜 |
根據業務具體場景選擇使用哪種校驗算法
- 數據可靠性傳輸
Tcp可靠性傳輸協議
通道的建立——三次握手:
(1)在建立通道時,客戶端首先要向服務端發送一個SYN同步信號。
(2)服務端在接收到這個信號之后會向客戶端發出SYN同步信號和ACK確認信號。
(3)當服務端的ACK和SYN到達客戶端后,客戶端與服務端之間的這個“通道”就會被建立起來。
通道的關閉——四次揮手:
(1)在數據傳輸完畢之后,客戶端會向服務端發出一個FIN終止信號。
(2)服務端在收到這個信號之后會向客戶端發出一個ACK確認信號。
(3)如果服務端此后也沒有數據發給客戶端時服務端會向客戶端發送一個FIN終止信號。
(4)客戶端在收到這個信號之后會回復一個確認信號,在服務端接收到這個信號之后,服務端與客戶端的通道也就關閉了。
Tcp保證可靠性策略
·?確認應答機制(核心)
確認應答機制就是由Tcp報頭字段中的32位序號和32位確認序號來保證的
注意:確認應答機制不是保證雙方的通信的可靠性,而是通過收到對方應答,來保證一方通信的可靠性,但是如果雙方都這樣搞,就是間接保證了雙方通信的可靠性
?確認應答機制前面已經大量涉及了,這里不再贅述了,只要記住,確認應答機制是Tcp保證可靠性的核心,或者說是基礎,其余絕大部分的保證可靠性機制都是建立在確認應答機制基礎上的
· 超時重傳機制
定義:雙方在進行網絡通信時,發送方發出數據,如果在一個特定時間間隔內收不到應答,那么發送方就認為“我發的數據對方沒有收到”,就會進行數據重發
附:Tcp保證可靠性一部分是通過Tcp協議報頭體現出來的,還有一部分是通過實現Tcp的代碼邏輯實現出來的,比如超時重傳機制就是在發送方發出數據后開啟了一個定時器,這就是通過Tcp的代碼邏輯體現出來的,這在Tcp報頭中是體現不出來的