如何验证两个 CRC 实现将生成相同的校验和?
我正在寻找一种针对 CRC 的详尽的实施评估方法。
您可以将问题分为边缘情况和随机样本。
边缘案例。CRC 输入有两个变量,字节数和每个字节的值。因此,创建 0、1 和 MAX_BYTES 的数组,其值范围从 0 到 MAX_BYTE_VALUE。边缘案例套件将是您最可能希望保留在 JUnit 套件中的东西。
随机样本。使用上述范围,在循环中对随机生成的字节数组运行 CRC。你让循环运行的时间越长,你消耗的输入就越多。如果您的计算能力不足,请考虑将测试部署到 EC2。
创建几个具有相同输入的单元测试,将两个实现的输出相互比较。
CRC 的一个很好的特性是,对于给定的一组参数(多项式、反射、初始状态等),当您在原始数据集 + 原始 CRC 上重新计算 CRC 时,您将获得一个恒定值。这些常量记录在常见的 CRC 中,但您可以使用两个不同的随机数据集盲目地生成它们并检查它们是否相同:
implementation 1: crc(rand_data_1 + crc(rand_data_1)) -> constant_1
implementation 2: crc(rand_data_2 + crc(rand_data_2)) -> constant_2
assert constant_1 == constant_2
您可以在实现中使用相同的方法来获得关于其正确性的温暖模糊感觉。如果您的实现适用于任意多项式,您可以让 unittest 使用此方法彻底检查每个可能的多项式,而无需知道常量是什么。
这种技术很强大,但添加一个独立的测试也是明智的,该测试基于已知输入来验证病理情况的结果,在这种情况下,您的 CRC 实现都会产生错误的结果,而这些结果恰好通过恒定等价检查得到。
首先,如果它是标准的 CRC 实现,您应该能够在网络上的某处找到已知值。
其次,您可以生成一些有效负载并在有效负载上运行每个 CRC 并检查 CRC 值是否匹配。
通过为每个采用相同输入的单元测试编写一个单元测试,并根据预期输出进行验证。