【发布时间】:2017-04-14 22:32:24
【问题描述】:
我正在尝试在 c 中创建一个 CRC-15 检查,并且文件的每一行的输出都永远不正确。我正在尝试在每行旁边累积输出每行的 CRC。我使用:#define POLYNOMIAL 0xA053 作为除数,使用文本作为被除数。我需要将数字表示为 32 位无符号整数。我尝试打印出十六进制值以跟踪和翻转不同的班次。但是,我似乎无法弄清楚!我觉得这与我填充事物的方式有关。我的逻辑有问题吗?
CRC 将用四个十六进制数字表示,该序列将有四个前导 0。例如,它看起来像 0000xxxx,其中 x 是十六进制数字。我使用的多项式是 0xA053。
我考虑过使用一个临时变量,并在每次异或时每行执行 4 个 16 位的代码块,但是,我不太确定如何使用移位来完成此操作,所以我决定对上面的字母进行校验和行,然后对其进行异或以尝试计算 CRC 码。
我正在使用以下输入和填充测试我的代码。直到字符串的长度为 504,因为这是填充字符需要通过给定的要求: “这就是教训:决不屈服,决不屈服,决不,决不,决不,决不——无论大小,大或小——决不屈服,除非是对荣誉和理智的信念。决不屈服于武力;永远不要屈服于敌人看似压倒性的力量。”
前 64 个字符行的 CRC(“这是教训:永不放弃,永不放弃,永不,永不,)应该是 000015fa,我得到 bfe6ec00。
我的逻辑:
在 CRCCalculation 中,我将每个字符添加到一个 32 位无符号整数,然后在 64(一行的长度)之后将其发送到 XOR 函数中。
如果最高位不是1,我将数字左移一位 导致 0 填充右侧并再次循环。
如果最高位为 1,则将被除数与除数异或,然后将被除数左移。
所有计算完成后,我将左移四位的被除数(前面加四个零)返回给计算函数
将结果添加到结果的总和中
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#define POLYNOMIAL 0xA053
void crcCalculation(char *text, int length)
{
int i;
uint32_t dividend = atoi(text);
uint32_t result;
uint32_t sumText = 0;
// Calculate CRC
printf("\nCRC 15 calculation progress:\n");
i = length;
// padding
if(i < 504)
{
for(; i!=504; i++)
{
// printf("i is %d\n", i);
text[i] = '.';
}
}
// Try calculating by first line of crc by summing the values then calcuating, then add in the next line
for (i = 0; i < 504; i++)
{
if(i%64 == 0 && i != 0)
{
result = XOR(POLYNOMIAL, sumText);
printf(" - %x\n",result);
}
sumText +=(uint32_t)text[i];
printf("%c", text[i]);
}
printf("\n\nCRC15 result : %x\n", result);
}
uint32_t XOR(uint32_t divisor, uint32_t dividend)
{
uint32_t divRemainder = dividend;
uint32_t currentBit;
// Note: 4 16 bit chunks
for(currentBit = 32; currentBit > 0; --currentBit)
{
// if topbit is 1
if(divRemainder & 0x80)
{
//divRemainder = (divRemainder << 1) ^ divisor;
divRemainder ^= divisor;
printf("%x %x\n", divRemainder, divisor);
}
// else
// divisor = divisor >> 1;
divRemainder = (divRemainder << 1);
}
//return divRemainder; , have tried shifting to right and left, want to add 4 zeros to front so >>
//return divRemainder >> 4;
return divRemainder >> 4;
}
【问题讨论】:
-
你为什么要总结每64个字符的文本?这无论如何都不是 CRC。
-
我正在尝试累计获取每行的 CRC 总数,我假设这个求和和 XORing 会得到该行的位,然后我会去添加下一行,然后得到这些位...我正在考虑将文本数组发送到 XOR 函数并创建一个临时变量,该变量会一点一点地移动这些位,但是,我不太确定如何将这些位移动到临时数组中。例如,如果我将一行的 4 个 16 位块发送到 XOR 并根据需要移入另一位,直到数组为空并使用它来 XOR 事情,这是否比求和更 CRC?
-
为什么不计算 16 位 CRC?一次处理一个完整字节比处理部分字节要容易得多/
-
发布的代码有几个“神奇”数字:504 和 64。“神奇”数字是没有依据的数字。 “神奇”数字使代码更难理解、调试等。建议使用
enum语句或#define语句为这些“神奇”数字赋予有意义的名称,然后在整个代码中使用这些有意义的名称。跨度> -
@user3629249 讲师要求 32 位。我没有及时完成。但是,我走在正确的轨道上,并且仍在努力!我肯定会尝试用 16 位来解决它,因为我只是为了好玩:)。