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

实现CRC算法

如何解决实现CRC算法

我正在尝试实现某些视频接口标准中定义的 CRC 算法:

原始数据是 10 位字,被压缩成 8 位字节,我在 numpy 中提取和使用没有问题。

CRC 具有多项式:

CRC(X) = X^18 + X^5 + X^4 + 1

我相信这给了我不变的:

poly = 0x40031

我尝试了几种不同的实现,但我生成的任何内容都无法与我的示例数据相匹配。 此实现的灵感来自 this

MASK = 0x3FFFF
class MYCRC:
    crc_table = []
    def __init__(self):
        if not self.crc_table:
            for i in range(1024):
                k = i
                for j in range(10):
                    if k & 1:
                        k ^= poly
                    k >>= 1
                self.crc_table.append(k)

    def calc(self,crc,data):
        crc ^= MASK
        for d in data:
            crc = (crc >> 10) ^ self.crc_table[(crc & 0x3FF) ^ d]
        return crc ^ MASK

然后是我从某个地方(不确定在哪里)提取的这个实现

def crc_calc(crc,p):
    crc = MASK & ~crc
    for i in range(len(p)):
        crc = (crc ^ p[i]) # & BIG_MASK
        for j in range(10):
            crc = ((crc >> 1) ^ (poly & -(crc & 1))) # & BIG_MASK
    return MASK & ~crc

我还考虑使用 this library,它支持使用自定义多项式,但它似乎是为处理 8 位数据而构建的,而不是我拥有的 10 位数据。

我不确定如何最好地共享测试数据,因为我只有整个帧,如果导出为 numpy 文件,则大约为 5MB。 我也不清楚我应该提供给 CRC 计算的数据范围。我认为通过阅读它,它应该从一行上的第一个活动样本开始,直到后面的行的行数,然后在该范围内计算校验和。从硬件的角度来看,这是最有意义的,但标准对我来说并没有那么清楚。

编辑: pastebin 的 10 行测试数据,其中包括嵌入的校验和。 在一行数据中,样本0-7是EAV标记,8-11是行号,12-16是两个校验和。数据是两个交错的视频数据流(亮度通道和 CbCr 通道)。 标准规定校验和是从第一个活动样本到行数据的末尾运行的,我认为这意味着它从一行的样本 740 运行到下一行的样本 11。

根据 SMPTE292M 的第 5 节,数据是 10 位数据,不能低于 0x3 或高于 0x3FC。根据表 4,CRC 的结果应该是 18 位,它们被拆分并作为两个字嵌入到流中(一个位填充了另一个位的非)请注意,每个数据通道都有一个校验和,这些每行 12-16 处有两个校验和

编辑2 some longer test data 跨越从消隐数据到活动帧数据的跳跃

解决方法

CRC 计算必须完成反映。 (表 9 注释中的提示:“注意 – CRC0 是错误检测代码的 MSB。”)

此 C 例程正确检查示例中的 CRC:

// Update the CRC-18 crc with the low ten bits of word.
// Polynomial = 1000000000000110001
// Reflected (dropping x^18) = 10 0011 0000 0000 0000 = 0x23000
unsigned crc18(unsigned crc,unsigned word) {
    crc ^= word & 0x3ff;
    for (int k = 0; k < 10; k++)
        crc = crc & 1 ? (crc >> 1) ^ 0x23000 : crc >> 1;
    return crc;
}

确实,检查的范围是从活动行的开头到行号,直到流中的两个 CRC 之前。该计算与这两个 CRC 匹配。每个 CRC 都是根据流中的交替字计算的。 CRC 初始化为零。

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