博客搬家,博文原址:https://blog.csdn.net/yuse1194/article/details/78484340
版权声明:本文为博主原创文章,未经博主允许不得转载。
1、实验题目:CRC 校验
PPP 协议受到数据帧后要对数据部分连同 FCS 字段做 CRC 校验,结果若不为“0”,则 可以肯定数据在传输过程中出错;结果若为“0”,则只能说明很大概率上数据在传输的过程 中没有出错,而不是百分之百不出错。这个概率与 CRC 校验时采用的除数有关,我们把使 用某个除数做 CRC 校验,结果为“0”且数据实际不出错的概率称为该除数的有效性。 本次试验要求同学们以实验的方法验证 CRC-16 的有效性。
2、实验内容
(1) 随机取 1 个 128 位数 A。
(2) 将 A 与 CRC-16 做除法得余数 B,A*216+B 保存在 C 中。
(3) 随机修改 C 中的 1 个比特,重新与 CRC-16 做除法运算,记录余数为 0 的二进制组 合。
(4) 随机修改 C 中的 2 个比特,重新与 CRC-16 做除法运算,记录余数为 0 的二进制组 合。
(5) 随机修改 C 中的 3 个比特,重新与 CRC-16 做除法运算,记录余数为 0 的二进制组 合。
3、实验报告内容
(1) CRC 校验原理。
(2) 实验记录
(3) 随机产生的 128 位数(以 16 进制表示)。
(4) 除法运算的算法描述。
(5) 随机修改 C 中的 1 个比特,重新与 CRC-16 做除法运算,余数为 0 的二进制组合。
(6) 随机修改 C 中的 2 个比特,重新与 CRC-16 做除法运算,余数为 0 的二进制组合。
(7) 随机修改 C 中的 3 个比特,重新与 CRC-16 做除法运算,余数为 0 的二进制组合。
4、实验结果分析
理论上 CRC-16 的有效性(不一定 100%有效)。
实验代码
#
# writen by LoveReverse 17/11/08
#
#include<iostream>
#include<string>
#include<time.h>
#include<math.h>
using namespace std;
#define divisor "11000000000000101" //CRC-16的除数
int length(string str) //计算字符串长度
{
for (int i = 0;; i++)
{
if (str[i] == '\0') return i;
}
}
string randomNumber() //随机生成128位二进制数
{
srand((unsigned)time(NULL));
string number;
for (int loop = 0; loop < 128; loop++)
{
number += rand() % 2 + 48;
}
number += "\0";
return number;
}
string division(string remainder) //模二除法
{
int i = 0;
int tmp;
int quotient;
do {
quotient = remainder[0];
for (int j = 1, k = 0; j <= length(remainder); j++)
{
if (j == length(remainder)) {
remainder[k++] = '\0';
continue;
}
if (j < length(divisor)) {
tmp = (remainder[j] - 48) ^ ((divisor[j] - 48)*(quotient - 48));
remainder[k++] = tmp + 48;
}
else {
remainder[k++] = remainder[j];
}
}
i++;
} while (length(remainder) > 16);
return remainder;
}
string mistake(int i, string str) //随机修改比特
{
srand((unsigned)time(NULL));
do {
int tmp = rand() % length(str);
if (str[tmp] == 48) str[tmp]++;
else str[tmp]--;
} while (--i);
return str;
}
string BinToHex(string strBin) //2进制转16进制
{
string strHex;
for (int i = length(strBin); i > 0;)
{
int j = 0;
string tmp;
int hex = 0;
do {
if (i > 0) hex = hex + (strBin[i - 1] - 48) * pow(2, j);
i--;
j++;
} while (j < 4);
if (hex < 10) {
tmp = hex + 48;
strHex = tmp + strHex;
}
else {
tmp = hex + 55;
strHex = tmp + strHex;
}
}
return "0x" + strHex;
}
void main()
{
string number = randomNumber();
cout << "生成128位数A:" << BinToHex(number) << endl;
string remainder = division(number + "0000000000000000");
cout << "余数R:" << "(" << BinToHex(remainder) << ")" << remainder << endl;
string send = number + remainder;
cout << "假设发送数据C:" << BinToHex(send) << endl;
cout << "C的FCS为:" << division(send) << endl;
string wrong;
wrong = mistake(1, send);
cout << "随机修改1个比特,C的FCS:" << division(wrong) << endl;
wrong = mistake(2, send);
cout << "随机修改2个比特,C的FCS:" << division(wrong) << endl;
wrong = mistake(3, send);
cout << "随机修改3个比特,C的FCS:" << division(wrong) << endl;
system("pause");
}
实验结果和结论
理论上 CRC-16 不一定 100%有效,当且仅当出错后的C仍能够被CRC多项式整除的时候CRC算法无法检查到错误。