我已经尝试在c中实现crc。我的逻辑不是很好。我试过的是将消息(msg)复制到临时变量中,最后我附加的数字为0,小于数字crc的除数div中的位数。
代表:
msg=11010011101100
div=1011
然后临时变为:
temp=11010011101100000
div= 10110000000000000
找到temp和div的xor并将其存储在temp
中在第一个' 1'之前显示temp=01100011101100000
个零点数。将temp的字符右移到该数字,然后重复相同的过程,直到temp的十进制值小于div的十进制值。其余部分给出了。
我的问题是,当我在临时结束时附加零,它会存储0以及一些特殊字符,如下所示:
temp=11010011101100000$#UFI#->Jp#|
当我调试时出现错误
浮点:堆栈下溢
这是我的代码:
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
void main() {
char msg[100],div[100],temp[100];
int i,j=0,k=0,l=0,msglen,divlen,newdivlen,ct=0,divdec=0,tempdec=0;
printf("Enter the message\n");
gets(msg);
printf("\nEnter the divisor\n");
gets(div);
msglen=strlen(msg);
divlen=strlen(div);
newdivlen=msglen+divlen-1;
strcpy(temp,msg);
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
printf("\nModified Temp:");
printf("%s",temp);
for(i=divlen;i<newdivlen;i++)
div[i]='0';
printf("\nModified div:");
printf("%s",div);
for(i=newdivlen;i>0;i--)
divdec=divdec+div[i]*pow(2,j++);
for(i=newdivlen;i>0;i--)
tempdec=tempdec+temp[i]*pow(2,k++);
while(tempdec>divdec)
{
for(i=0;i<newdivlen;i++)
{
temp[i]=(temp[i]==div[i])?'0':'1';
while(temp[i]!='1')
ct++;
}
for(i=newdivlen+ct;i>ct;i--)
div[i]=div[i-ct];
for(i=0;i<ct;i++)
div[i]='0';
tempdec=0;
for(i=newdivlen;i>0;i--)
tempdec=tempdec+temp[i]*pow(2,l++);
}
printf("%s",temp);
getch();
}
这部分代码:
for(i=newdivlen;i>0;i--)
divdec=divdec+div[i]*pow(2,i);
给出错误浮点:堆栈下溢
答案 0 :(得分:0)
问题是你在NUL终结符上写了一个0
,并没有在字符串上放置另一个NUL终止符。所以printf
会混淆并打印垃圾。这就是说这段代码
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
printf("\nModified Temp:");
printf("%s",temp);
应该是
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
temp[i] = '\0'; // <--- NUL terminate the string
printf("\nModified Temp:");
printf("%s",temp);
答案 1 :(得分:0)
您必须使用整数执行此操作
int CRC(unsigned int n);
int CRC_fast(unsigned int n);
void printbinary(unsigned int n);
unsigned int msb(register unsigned int n);
int main()
{
char buf[5];
strcpy(buf, "ABCD");
//convert string to number,
//this is like 1234 = 1*1000 + 2*100 + 3*10 + 4, but with hexadecimal
unsigned int n = buf[3] * 0x1000000 + buf[2] * 0x10000 + buf[1] * 0x100 + buf[3];
/*
- "ABCD" becomes just a number
- Any string of text can become a sequence of numbers
- you can work directly with numbers and bits
- shift the bits left and right using '<<' and '>>' operator
- use bitwise operators & | ^
- use basic math with numbers
*/
//finding CRC, from Wikipedia example:
n = 13548; // 11010011101100 in binary (14 bits long), 13548 in decimal
//padding by 3 bits: left shift by 3 bits:
n <<= 3; //11010011101100000 (now it's 17 bits long)
//17 is "sort of" the length of integer, can be obtained from 1 + most significant bit of n
int m = msb(n) + 1;
printf("len(%d) = %d\n", n, m);
int divisor = 11; //1011 in binary (4 bits)
divisor <<= (17 - 4);
//lets see the bits:
printbinary(n);
printbinary(divisor);
unsigned int result = n ^ divisor;// XOR operator
printbinary(result);
//put this in function:
n = CRC(13548);
n = CRC_fast(13548);
return 0;
}
void printbinary(unsigned int n)
{
char buf[33];
memset(buf, 0, 33);
unsigned int mask = 1 << 31;
//result in binary: 1 followed by 31 zero
for (int i = 0; i < 32; i++)
{
buf[i] = (n & mask) ? '1' : '0';
//shift the mask by 1 bit to the right
mask >>= 1;
/*
mask will be shifted like this:
100000... first
010000... second
001000... third
*/
}
printf("%s\n", buf);
}
//find most significant bit
unsigned int msb(register unsigned int n)
{
unsigned i = 0;
while (n >>= 1)
i++;
return i;
}
int CRC(unsigned int n)
{
printf("\nCRC(%d)\n", n);
unsigned int polynomial = 11;
unsigned int plen = msb(polynomial);
unsigned int divisor;
n <<= 3;
for (;;)
{
int shift = msb(n) - plen;
if (shift < 0) break;
divisor = polynomial << shift;
printbinary(n);
printbinary(divisor);
printf("-------------------------------\n");
n ^= divisor;
printbinary(n);
printf("\n");
}
printf("result: %d\n\n", n);
return n;
}
int CRC_fast(unsigned int n)
{
printf("\nCRC_fast(%d)\n", n);
unsigned int polynomial = 11;
unsigned int plen = msb(polynomial);
unsigned int divisor;
n <<= 3;
for (;;)
{
int shift = msb(n) - plen;
if (shift < 0) break;
n ^= (polynomial << shift);
}
printf("result: %d\n\n", n);
return n;
}
以前的字符串方法问题: 这是无限循环:
while (temp[i] != '1')
{
ct++;
}
以前的字符串方法问题: 这个太混乱了:
for (i = newdivlen + ct; i > ct; i--)
div[i] = div[i - ct];
我不知道ct
是什么。 for
循环都向后移动,这使得代码有时更快(可能快1纳秒),但这使得它非常混乱。
还有另一个while循环,
while (tempdec > divdec)
{
//...
}
如果你没有得到预期的结果,这可能会永远持续下去。这使得调试代码非常困难。