微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

该程序是否正确计算 CRC?

如何解决该程序是否正确计算 CRC?

我正在尝试创建一个函数,该函数采用单个字节并为给定的任何生成的多项式返回 CRC 值。

#include <stdio.h>
#include <stdint.h>

#define MSG_SIZE    7                             // number of message bits
#define poly_SIZE   9                             // number of gen. poly. bits
#define SHIFT_INPUT poly_SIZE-1                   // zeros to be added to input
#define SHIFT_poly  MSG_SIZE-1                    // zeros to be added to polynomial
#define poly        0x11D                          // generated polynomial
#define poly_MSK    (poly << SHIFT_poly)          // add zeros to polynomial to be aligned with input
#define ALIGN_MSK   (1 << (MSG_SIZE+poly_SIZE-2)) // for MSB_poly and MSB_input alignment check

uint64_t PartCRC(uint64_t input);

uint64_t PartCRC(uint64_t input){

    input = ( input << SHIFT_INPUT );

    for(int n = 0; n < MSG_SIZE; n++){
        // if current (MSB) bit of input is "1"; if MSB_poly and MSB_input are aligned
        if( input & ALIGN_MSK ){
            input ^= poly_MSK;      // input XOR poly
        }
        // if crc is calculated,don't shift
        if( n == (MSG_SIZE-1) ) break;
        input = ( input << 1 );       // shift input left each step
    }
    return (input >> SHIFT_poly);   // return crc - trim zeros
}

void main(void) {

    printf( "CRC for input: %llX\n",PartCRC(0x41) );

    return;
}

除了从 PartCRC() 提供给 main() 函数的消息之外,我必须仅将生成的多项式定义为十六进制数加上其大小和消息大小(从 LSB 到 MSB 的位数)。 这个函数的作用是在每次迭代时将输入左移,在那里检查多项式的 MSB 和输入的 MSB 是否对齐;如果是这样,则在当前移位的输入和多项式之间执行按位 XOR(即 poly_MSK - poly 被移位以使其与当前移位的输入对齐)。最后,计算出的余数右移(因为它在 CRC 计算期间用零填充)。

我了解这个过程是如何工作的,我非常有信心它应该对每个 CRC 标准化生成的多项式正确运行,但是它只对少数非标准化多项式起作用。例如,它适用于 2.Introduction 段落(以及少数其他多项式)。

然而,对于其他(标准化的)多项式,它不起作用;在 this 站点检查代码的(非)有效性。在这里,我想指出,我了解关于生成的多项式计算 CRC 的方法很少 - 正态、逆向、倒数、逆倒数。为简单起见,我保持正常表示,并且在前面提到的站点要求已经计算的 CRC 时我也考虑了这一事实(我的意思是“初始值”和“最终 XOR 值”都是 0x00,虽然我不确定,那两个是什么意思)

解决方法

至少有一个潜在问题:整数大小

#define MSG_SIZE    7
#define POLY_SIZE   9   
#define ALIGN_MSK   (1 << (MSG_SIZE+POLY_SIZE-2))

MSG_SIZE+POLY_SIZE-2 超过 15 并且 1 是 16 位 int 时,这是一个问题。同样,对于 MSG_SIZE+POLY_SIZE-2 超过 31 并且 1 是 32 位 int

更好

#define ALIGN_MSK   ((uint64_t)1 << (MSG_SIZE+POLY_SIZE-2))

以下类似问题。

#define POLY        0x11D 
#define POLY_MSK    (POLY << SHIFT_POLY) 
input ^= POLY_MSK;

推荐

#define POLY_MSK    ((uint64_t)POLY << SHIFT_POLY) 

代码对 SHIFT_INPUT 的使用看起来不错,但推荐使用 ()

// #define SHIFT_INPUT POLY_SIZE-1
#define SHIFT_INPUT (POLY_SIZE-1)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。