為建立中文知識(shí)庫(kù)加塊磚 ——中科大胡不歸
0. 前言
如果必須加入一種方法來(lái)校驗(yàn)協(xié)議數(shù)據(jù),累加校驗(yàn)不失為一種好的方案。MD5計(jì)算出的Hash太長(zhǎng)了,校驗(yàn)和不過(guò)1或2個(gè)字節(jié)惧财,當(dāng)然MD5的安全性也不是校驗(yàn)和能比的。
1. 校驗(yàn)和原理
1.1 發(fā)送方生成檢驗(yàn)和
1.將發(fā)送的進(jìn)行檢驗(yàn)和運(yùn)算的數(shù)據(jù)分成若干個(gè)16位的位串扭仁,每個(gè)位串看成一個(gè)二進(jìn)制數(shù)垮衷,這里并不管字符串代表什么,是整數(shù)乖坠、浮點(diǎn)數(shù)還是位圖都無(wú)所謂搀突。
2.將IP、UDP或TCP的PDU首部中的檢驗(yàn)和字段置為0熊泵,該字段也參與檢驗(yàn)和運(yùn)算仰迁。
3.對(duì)這些16位的二進(jìn)制數(shù)進(jìn)行1的補(bǔ)碼和(one's complement sum)運(yùn)算甸昏,累加的結(jié)果再取反碼即生成了檢驗(yàn)碼。將檢驗(yàn)碼放入檢驗(yàn)和字段中徐许。
其中1的補(bǔ)碼和運(yùn)算施蜜,即帶循環(huán)進(jìn)位(end round carry)的加法,最高位有進(jìn)位應(yīng)循環(huán)進(jìn)到最低位雌隅。反碼即二進(jìn)制各位取反翻默,如0111的反碼為1000。
1.2 接收方校驗(yàn)檢驗(yàn)和
1.接收方將接收的數(shù)據(jù)(包括檢驗(yàn)和字段)按發(fā)送方的同樣的方法進(jìn)行1的補(bǔ)碼 和運(yùn)算恰起,累加的結(jié)果再取反碼修械。
2.校驗(yàn),如果上步的結(jié)果為0检盼,表示傳輸正確肯污;否則,說(shuō)明傳輸有差錯(cuò)吨枉。
1.3 算法圖示
2. 代碼實(shí)現(xiàn)
2.1 生成檢驗(yàn)和
public static byte[] GetCheckSum(byte[] data)
{
List<byte> m = new List<byte>();
int sum = 0;
for (int i = 0; i < data.Length; i++)
{
m.Add(data[i]);
sum += data[i];
}
sum = sum % 256;
sum = ~sum + 1;
m.Add((byte) sum);
return m.ToArray();
}
返回值是追加了校驗(yàn)和的原始字節(jié)數(shù)組蹦渣。
2.2 接收方校驗(yàn)
public static byte DoSumCheck(byte[] data)
{
byte cs = 0;
for (int i = 0; i < data.Length; i++)
{
cs = (byte)((cs + data[i]) % 256);
}
return cs;
}
DoSumCheck的參數(shù)就是原字節(jié)數(shù)組在尾部加上了校驗(yàn)和,如果數(shù)據(jù)正確運(yùn)算結(jié)果就為00貌亭。
3. 效果展示
調(diào)用演示:
運(yùn)行結(jié)果: