#include <stdio.h>
#include <string.h>
// 转化后的二进制最多的位数
#define MAX_BIN_LENGHT 100
// 输入的表达式最多的字符数
#define MAX_EXP_LENGHT 100
// 根据表达式得到二进制数
void getBinary(char *express,int binary[MAX_BIN_LENGHT]);
// 根据两个二进制数,得到CRC校验结果
void getQuoRem(int *binaryY,int binaryG[MAX_BIN_LENGHT], int result[MAX_BIN_LENGHT]);
// 打印二进制数
void printBinary(int binary[MAX_BIN_LENGHT]);
// 得到正序的二进制数
void getOrderedBinary(int originalBinary[MAX_BIN_LENGHT],int orderedBinary[MAX_BIN_LENGHT]);
// 得到二进制位数
int getBinaryLength(int originalBinary[MAX_BIN_LENGHT]);
int main(int argc,char *argv[])
{
int binaryY[MAX_BIN_LENGHT]={0}; // 存放Y(x)转化后的二进制数
int binaryG[MAX_BIN_LENGHT]={0}; // 存放G(x)转化后的二进制数
int binaryTemp[MAX_BIN_LENGHT]={0}; // 存放表达式转化后的倒序二进制数
int binaryResult[MAX_BIN_LENGHT]={0}; // 存放最后要发送的加上校验码的数据
char express[MAX_EXP_LENGHT]; //存放输入的表达式
printf("请输入Y(x)表达式:\n");
scanf("%s",express);
getBinary(express,binaryTemp);
getOrderedBinary(binaryTemp,binaryY);
printf("请输入G(x)表达式:\n");
scanf("%s",express);
getBinary(express,binaryTemp);
getOrderedBinary(binaryTemp,binaryG);
// 得到有校验码的数据
getQuoRem(binaryY,binaryG,binaryResult);
printf("\nY(x)的二进制为:");
printBinary(binaryY);
printf("G(x)的二进制为:");
printBinary(binaryG);
printf("最终的CRC校验数据为:");
printBinary(binaryResult);
return 0;
}
/**********************
* 根据表达式得到二进制数
***********************/
void getBinary(char *express,int binary[MAX_BIN_LENGHT])
{
int i;
int num=0;
char tempc;
// 让binary清零
for(i=0;i<MAX_BIN_LENGHT;i++)
{
binary[i]=0;
}
// 求倒序的二进制
for(i=0;i<strlen(express);)
{
if(*(express+i)=='^')
{
// 如果是^号,表示接下来的就是指数了
for(i=i+1;i<strlen(express);i++)
{
tempc=*(express+i);
if(tempc>='0' && tempc<='9')
{
num=num*10+(tempc-'0');
if((i+1)>=strlen(express))
{
binary[num]=1;
}
}
else
{
/*
得到相应的指数,将对应的二进制位数设置为1。
此时二进制的最低位对应的是binary[0],二进制的最高位对应的是binary[MAX_BIN_LENGHT-1]
*/
binary[num]=1;
num=0;
break;
}
}
}
else
{
if(*(express+i)=='1'&& (i+1)>=strlen(express))
{
// 如果最后一个数字是1,那么二进制最低位binary[0]设置为1
binary[0]=1;
}
i++;
}
}
}
/**************************
* 根据两个二进制数,得到CRC校验结果
* 参数: binaryY 二进制被除数
* binaryG 二进制除数
* quotient 商
* remainder 余数
* result 带校验码的最终结果
**************************/
void getQuoRem(int binaryY[MAX_BIN_LENGHT],int binaryG[MAX_BIN_LENGHT],int result[MAX_BIN_LENGHT])
{
int i,j,index=0,k;
int lengthY,lengthG,lengthB;
int quotient[MAX_BIN_LENGHT]={0}; // 存放商的二进制数
int remainder[MAX_BIN_LENGHT]={0}; // 存放余数的二进制数
lengthY=getBinaryLength(binaryY);
lengthG=getBinaryLength(binaryG);
if(lengthG>lengthY)
{
printf("除数比余数大!无法得到正确商和余数!");
quotient[1]=-1;
remainder[1]=-1;
return ;
}
/*
* 将被除数的后边加上除数对应的0,结果存入到result中。
* 添加的0的个数与除数中x^n的最大指数值n相同
*/
for(i=0;i<(lengthY+lengthG-1);i++)
{
// 最终的结果前面与被除数相同
if(i<lengthY)
{
result[i]=binaryY[i];
}
// 最终结果的后面填充相应个数的0
else
{
result[i]=0;
}
}
// result尾部加上结束符
result[i]=-1;
// 得到被除数总的位数长度
lengthB=getBinaryLength(result);
// 先得到最开始的余数
for(i=0;i<lengthG;i++)
{
remainder[i]=result[i];
}
// 循环得到商和余数
for(i=lengthG-1;i<lengthB;i++)
{
if(remainder[0]==1)
{
// 商1
quotient[index]=1;
// remainder余数与除数按位异或,结果存remainder余数中
for(j=0;j<lengthG;j++)
{
if(remainder[j]==binaryG[j])
{
remainder[j]=0;
}
else
{
remainder[j]=1;
}
}
}
else
{
// 商0
quotient[index]=0;
// 商0的话,remainder余数与全0按位异或,余数结果是不变的
}
index++;
// 舍弃余数最高位,后边的依次前移1位
for(j=1;j<lengthG;j++)
{
remainder[j-1]=remainder[j];
}
// 将被除数的下一位数字加到余数的最低位处,这样就可以进行下一次的除法
if((i+1)<lengthB)
{
remainder[lengthG-1]=result[i+1];
}
}
// 循环结束,将商和余数的数组末尾加上结束符号
remainder[lengthG-1]=-1;
quotient[index]=-1;
/*
printf("商为:");
printBinary(quotient);
printf("余数为:");
printBinary(remainder);
*/
// 将被除数后面的0换成相应的余数,这样被除数就变成要发送的带校验码的数据
for(i=lengthY;i<(lengthY+lengthG-1);i++)
{
result[i]=remainder[i-lengthY];
}
}
/**************************
* 打印二进制数
**************************/
void printBinary(int binary[MAX_BIN_LENGHT])
{
int i;
for(i=0;i<getBinaryLength(binary);i++)
{
printf("%d",binary[i]);
}
printf("\n");
}
/**************************
* 得到正序的二进制数
**************************/
void getOrderedBinary(int originalBinary[MAX_BIN_LENGHT],int orderedBinary[MAX_BIN_LENGHT])
{
/*
*因为originalBinary数组中originalBinary[0]存放的是二进制的最低位,originalBinary[MAX_BIN_LENGHT-1]存放的是二进制的最高位,
*将数组倒序后存放到orderedBinary中
*/
int i;
int j=0;
for(i=MAX_BIN_LENGHT-1;i>=0;i--)
{
if(originalBinary[i]==1)
{
for(j=0;i>=0;i--)
{
orderedBinary[j]=originalBinary[i];
j++;
}
}
else if(i==0)
{
orderedBinary[j]=originalBinary[i];
j++;
}
}
// 设置结束标志
orderedBinary[j]=-1;
}
/**************************
* 得到二进制位数
**************************/
int getBinaryLength(int binary[MAX_BIN_LENGHT])
{
int i;
for(i=0;i<MAX_BIN_LENGHT;i++)
{
if(binary[i]==-1)
{
break;
}
}
return i;
}
/*-----------------------------测试结果------------------------------*/
请输入Y(x)表达式:
x^5+x^3+1
请输入G(x)表达式:
x^3+x^2+1
Y(x)的二进制为:101001
G(x)的二进制为:1101
最终的CRC校验数据为:101001001