【发布时间】:2013-09-06 20:18:39
【问题描述】:
我正在尝试在 C# 中实现 Crc16。我已经尝试了许多不同的实现,但它们中的大多数给了我不同的值。这是我已经使用的一些代码。
private static int POLYNOMIAL = 0x8408;
private static int PRESET_VALUE = 0xFFFF;
public static int crc16(byte[] data)
{
int current_crc_value = PRESET_VALUE;
for (int i = 0; i < data.Length; i++)
{
current_crc_value ^= data[i] & 0xFF;
for (int j = 0; j < 8; j++)
{
if ((current_crc_value & 1) != 0)
{
current_crc_value = (current_crc_value >> 1) ^ POLYNOMIAL;
}
else
{
current_crc_value = current_crc_value >> 1;
}
}
}
current_crc_value = ~current_crc_value;
return current_crc_value & 0xFFFF;
}
这是我使用的另一个实现,但都给出了不同的值
const ushort polynomial = 0xA001;
ushort[] table = new ushort[256];
public ushort ComputeChecksum(byte[] bytes)
{
ushort crc = 0;
for (int i = 0; i < bytes.Length; ++i)
{
byte index = (byte)(crc ^ bytes[i]);
crc = (ushort)((crc >> 8) ^ table[index]);
}
return crc;
}
public byte[] ComputeChecksumBytes(byte[] bytes)
{
ushort crc = ComputeChecksum(bytes);
return BitConverter.GetBytes(crc);
}
public Crc16()
{
ushort value;
ushort temp;
for (ushort i = 0; i < table.Length; ++i)
{
value = 0;
temp = i;
for (byte j = 0; j < 8; ++j)
{
if (((value ^ temp) & 0x0001) != 0)
{
value = (ushort)((value >> 1) ^ polynomial);
}
else
{
value >>= 1;
}
temp >>= 1;
}
table[i] = value;
}
}
我使用的值是一个 Octet String "[jp3]TEST [fl]Flashing[/fl]" 及其期望值为十六进制的 95F9。这是NTCIP协议指南上的一个例子
谢谢
【问题讨论】:
-
CRC-16 有许多可能的输入参数。它不是像 MD5 这样的单一算法。出于这个原因,例如,您的两个片段有两个不同的
polynomial/POLYNOMIAL(以及其他不同的东西) -
例如在这个页面中lammertbies.nl/comm/info/crc-calculation.html显示了各种标准使用的各种crc-16。
-
我找到了您所说的文档:ite.org/standards/1203v03-04%20Part%201%20dms2011.pdf 遗憾的是,没有一个真实的 CRC 计算示例。
-
也许我找到了算法。它计算目前唯一的完整示例。
-
本文档中的唯一示例是我之前所说的定义,该算法基于 ISO 13239:2002 中定义的 CRC-16 算法,此处位于第 118 页 ntcip.org/library/文件/pdf/1203v0239b_rs.pdf。在此页面上还有一个文本示例及其使用 CRC16 的十六进制值。”95 F9 十六进制多字符串值“[jp3]TEST [fl]Flashing[/fl]”的 2 字节校验和值”。仍然不清楚我应该在哪里寻找,甚至我怎样才能做到这一点