在 C 中生成的 CRC 查找 table 总是给出不同的结果
CRC lookup table generated in C always gives different results
我正在尝试创建一个生成 CRC 查找的函数 table。我正在使用 8051 微控制器,我宁愿使用 table 查找方法,但与此同时,我宁愿让我的计算机生成值,然后我可以直接将其加载到微控制器中-控制器。此源代码大部分借自:http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html
我只在"main"函数中添加
#include <stdio.h>
#define GP 0x107
#define DI 0x07
static unsigned char crc8_table[256];
static int made_table=0;
static void init_crc8()
{
int i,j;
unsigned char crc;
if (!made_table) {
for (i=0; i<256; i++) {
crc = i;
for (j=0; j<8; j++)
crc = (crc << 1) ^ ((crc & 0x80) ? DI : 0);
crc8_table[i] = crc & 0xFF;
}
made_table=1;
}
}
void crc8(unsigned char *crc, unsigned char m)
{
if (!made_table)
init_crc8();
*crc = crc8_table[(*crc) ^ m];
*crc &= 0xFF;
}
int main()
{
unsigned char crc[1];
crc8(crc,'S');
printf("S=%x\n",crc[0]); //different hex code almost every time
crc8(crc,'T');
printf("T=%x\n",crc[0]); //different hex code almost every time
return 0;
}
当我执行该程序时,我希望屏幕上显示相同的值,但打印的等号后的十六进制代码几乎在每次程序执行时都会改变。
我该怎么做才能解决这个问题?我不想收集不正确的 CRC 值。
主要是crc[0]没有初始化。结果,在 crc8 中,表达式 (*crc) ^ m 中的 *crc 未初始化,因此您的随机值。
修复:初始化 crc[0]。像
unsigned char crc[1] = { 0 };
crc[0]
未初始化。在使用 crc
调用 crc8()
之前,您需要 crc[0] = 0;
或 *crc = 0;
。那么你不会从 crc[0]
. 的随机初始内容中得到随机答案
- 您不需要
crc8()
中的 *crc &= 0xff;
。如果 char
是八位,那么它什么都不做。如果你有一个奇怪的架构,其中 char
超过八位,那么你需要做 *crc = crc8_table[((*crc) ^ m) & 0xff];
以确保你不会超出 table 的范围。 (只有m
的低八位会被用于CRC计算。)table的内容已经被限制为八位,所以无论如何你不需要最后的& 0xff
.
- 您可能需要一个不同于零的初始值,并且您可能需要将最终 CRC 值与某些内容进行异或,具体取决于您想要的 CRC-8 定义。在 RevEng catalog of CRC's 中,有两个具有未反映的多项式的 8 位 CRC。两者都恰好以初始值零开始,但其中一个在末尾与
0x55
进行异或运算。此外,可能会反映您需要的 CRC 定义,在这种情况下,移位方向会发生变化,多项式也会翻转。如果您的 CRC-8 需要与其他软件互操作,那么您需要找出正在使用的 CRC 的完整定义。
- 在这里传递指针似乎是一个奇怪的选择。直接传递和 return CRC 值会更有效。例如。
unsigned crc8(unsigned crc, unsigned ch) {
,这会将 ch
中的八位应用于 CRC crc
,并且 return 是新值。请注意,您不需要将 CRC 值设置为 char
。 unsigned
通常是 C 例程最有效的参数,return。事实上,通常第一个参数是在一个寄存器中传递的,并且 return 在同一个寄存器中编辑。
- 通常对由一系列字节组成的消息计算 CRC。如果有一个循环执行整个消息的例程会更有效,这样您就不需要检查 table 是否已经为消息的每个字节构建。
我正在尝试创建一个生成 CRC 查找的函数 table。我正在使用 8051 微控制器,我宁愿使用 table 查找方法,但与此同时,我宁愿让我的计算机生成值,然后我可以直接将其加载到微控制器中-控制器。此源代码大部分借自:http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html
我只在"main"函数中添加
#include <stdio.h>
#define GP 0x107
#define DI 0x07
static unsigned char crc8_table[256];
static int made_table=0;
static void init_crc8()
{
int i,j;
unsigned char crc;
if (!made_table) {
for (i=0; i<256; i++) {
crc = i;
for (j=0; j<8; j++)
crc = (crc << 1) ^ ((crc & 0x80) ? DI : 0);
crc8_table[i] = crc & 0xFF;
}
made_table=1;
}
}
void crc8(unsigned char *crc, unsigned char m)
{
if (!made_table)
init_crc8();
*crc = crc8_table[(*crc) ^ m];
*crc &= 0xFF;
}
int main()
{
unsigned char crc[1];
crc8(crc,'S');
printf("S=%x\n",crc[0]); //different hex code almost every time
crc8(crc,'T');
printf("T=%x\n",crc[0]); //different hex code almost every time
return 0;
}
当我执行该程序时,我希望屏幕上显示相同的值,但打印的等号后的十六进制代码几乎在每次程序执行时都会改变。
我该怎么做才能解决这个问题?我不想收集不正确的 CRC 值。
主要是crc[0]没有初始化。结果,在 crc8 中,表达式 (*crc) ^ m 中的 *crc 未初始化,因此您的随机值。
修复:初始化 crc[0]。像
unsigned char crc[1] = { 0 };
crc[0]
未初始化。在使用crc
调用crc8()
之前,您需要crc[0] = 0;
或*crc = 0;
。那么你不会从crc[0]
. 的随机初始内容中得到随机答案
- 您不需要
crc8()
中的*crc &= 0xff;
。如果char
是八位,那么它什么都不做。如果你有一个奇怪的架构,其中char
超过八位,那么你需要做*crc = crc8_table[((*crc) ^ m) & 0xff];
以确保你不会超出 table 的范围。 (只有m
的低八位会被用于CRC计算。)table的内容已经被限制为八位,所以无论如何你不需要最后的& 0xff
. - 您可能需要一个不同于零的初始值,并且您可能需要将最终 CRC 值与某些内容进行异或,具体取决于您想要的 CRC-8 定义。在 RevEng catalog of CRC's 中,有两个具有未反映的多项式的 8 位 CRC。两者都恰好以初始值零开始,但其中一个在末尾与
0x55
进行异或运算。此外,可能会反映您需要的 CRC 定义,在这种情况下,移位方向会发生变化,多项式也会翻转。如果您的 CRC-8 需要与其他软件互操作,那么您需要找出正在使用的 CRC 的完整定义。 - 在这里传递指针似乎是一个奇怪的选择。直接传递和 return CRC 值会更有效。例如。
unsigned crc8(unsigned crc, unsigned ch) {
,这会将ch
中的八位应用于 CRCcrc
,并且 return 是新值。请注意,您不需要将 CRC 值设置为char
。unsigned
通常是 C 例程最有效的参数,return。事实上,通常第一个参数是在一个寄存器中传递的,并且 return 在同一个寄存器中编辑。 - 通常对由一系列字节组成的消息计算 CRC。如果有一个循环执行整个消息的例程会更有效,这样您就不需要检查 table 是否已经为消息的每个字节构建。