使用C语言位运算 计算CRC循环冗余校验码尾码的一种尝试:

使用C语言位运算 计算CRC循环冗余校验码尾码的一种尝试:
直接上程序:

#include <stdio.h>

/*
**  用于计算数码有效位 
*/
unsigned char length(unsigned char i)
{
	unsigned char len;
	while(i)
   {
  		i = i>>1;
  		len++;
   }
   return len;
}
int main()
{
/*
*	由于char类型的变量最大支持255,所以实际上可以参加本运算时,最大支持0x3F,即0011 1111,也就是说要为冗余码预留位置
*		当然如果超过了,其计算也是正确的,但是只显示完整数码的后八位,剩下的需要前后段拼接一下 
*
*/
 unsigned char P = 0x06; //被除数
 unsigned char A = 0x9C;  //目标码
 unsigned char n; 
 //
 printf("除数P = %x(%d)\t 数据A = %x (%d)\t\n\r",P,P,A,A); 
 //
 /*
 *  @用途:计算R的位数,也就是n,这个取决于P的位数,n = Length(P)-1 
 *  @利用左移位进行计算,对于一个2进制非数码数,其最高位必定是1 
 *  @变量:PTEMP =:临时存放P的值  lengthP P的长度 
 */
  unsigned char lengthP;
  unsigned char PTEMP = P;
 n=length(PTEMP)-1; 
 //
 printf("lengthP = %x(%d) 将添加 %x(%d) 位冗余码",length(PTEMP),length(PTEMP),n,n);
 //
 /*//第一步
 *  @用途:将A进行2^n*M的运算,位数相当于A原来的位数加了n位 0(也就是P的位数减一+n) 
 *  @变量:ATMP: A进行补位运算之后的值 
 */	
 unsigned char ATMP = A<<n;
 //
 printf("\r\n变更位数之后的数据:%x(%d)",ATMP,ATMP);
 printf("\n\r\n\r");
 // 
/*
* @ 计算其长度 和移动长度 ,将数据进行移位,并与除数进行异或,之后对原数据进行长度移位清除,先向右移动‘
*         8-length+(n+1)位,之后再向左移动8-length+(n+1)位,实现前位置零 
*       然后将临时余数向左移length-(n+1)位,在高位表示,从而与上面做好准备的数据进行或运算,得到模二第一次运算的值 
* @事实上这样的运算要进行length(A)-n次,所以放入while中执行即可。 
* @变量:LE:每次运算的剩余数据长度 ,MLE:LE-n,第一次计算需要移动的位数,实际上每进行一次运算,MLE就减一 
*    ATMP2:继承ATMP;  ATMPN为异或之后的临时余数 ;
*	运算的次数I = length(A)-n; 
*   SM: 每次异或完成之后,ATMP需要将有效位的高三位置0,才能接收临时的余数,作为下次运算的ATMP2
*		但是,只有当本次运算时的除数不为0时才能这样算,否则本次除数为0,就相当于啥都没做,所以此时SM为0
*		意思是继承上次的ATMP,不需要接收余数,只不过下次运算由于MLE减一的缘故少右移一位罢了 
*/
unsigned char ATMP2 = ATMP;
unsigned char LE =length(ATMP2);
unsigned char MLE = LE -(n+1);
unsigned char ATMPN;
unsigned char I;
unsigned char Px;
I=LE-n; 
int SM;
while(I>0)
{
	printf("\r\n\r\n\t数据需要移动长度为%d\r\n",MLE);
	ATMP2 = ATMP2>>MLE;
	printf("移动后的数值为%x(%d) \t\r\n",ATMP2,ATMP2);
	if((ATMP2>>n)>0){Px=P;SM=8-length(ATMP)+(n+1);}
	else {Px=0;SM = 0;}  //SM=0;
	printf("ATMP2置位参量%d\r\n",SM);
	printf("本次除数为%x(%d)",Px,Px);
	ATMPN = ATMP2^Px;
	printf("临时余数:%x(%d)\r\n",ATMPN,ATMPN);
	ATMP2 = ATMP;
	ATMP2 = ATMP2<<SM;
	ATMP2 = ATMP2>>SM; 
	ATMP2 |= (ATMPN<<MLE);
	ATMP = ATMP2;
	printf("%d次计算后的数值:%x(%d)  ",8-I-n+1,ATMP2,ATMP2); 
	I--;	 
	MLE--;	
}
printf("\r\n\r\nFCS码为%0x(%d)",ATMP,ATMP); 
A = (A<<n)|ATMP;
printf("\r\n\t\t\t\t 得到的真实数据为 %0x(%d)",A,A); 
} 
{

由于本人也不是计算机专业,所以只能写到这样了。
此程序可以实现对6位(即最大0x3F的数据)添加2位FSC,超过6位的情况下计算出的FSC是正确的,但是最后无法显示添加后的数码。至于实现CRC只需要将while中的步骤反过来就行了。
具体思路参照注释。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值