如何解决实现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 举报,一经查实,本站将立刻删除。