试图反向工程一个串口协议。我无法重新创建crc-16字节。
根据文档,这是包的格式
48 45 4c 4f // HELO
01 00 00 01 // ARG 1
00 00 00 00 // ARG 2
00 00 00 00 // ARG 3
00 00 00 00 // ARG 4
00 00 00 00 // REQUEST BODY
5c b1 00 00 // CRC-16
b7 ba b3 b0 // Bit-wise inversion of HELO command这是从串行监视中嗅探出来的写命令
48 45 4c 4f 01 00 00 01 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 5c b1 00 00 b7 ba b3 b0 除了两个字节"5c b1“外,我还可以重新创建数据包。根据文档,5c b1字节是数据包上的crc-ccit16 16,crc-16插槽中为零。CRC16函数确实返回5C字节,但不返回b1。
我正在使用下面的代码计算crc:
public class Crc16
{
static ushort[] table = new ushort[256];
public ushort ComputeChecksum(params 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(params byte[] bytes)
{
ushort crc = ComputeChecksum(bytes);
return BitConverter.GetBytes(crc);
}
public Crc16(Crc16Mode mode)
{
ushort polynomial = (ushort)mode;
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;
}
}
}
public byte[] getPreCRC16Bytes()
{
byte[] x = new byte[28];
byte[] cmdBytes = Encoding.ASCII.GetBytes(this.cmd.ToString());
byte[] arg1Bytes = (byte[])this.arg1;
byte[] arg2Bytes = (byte[])this.arg2;
byte[] arg3Bytes = (byte[])this.arg3;
byte[] arg4Bytes = (byte[])this.arg4;
byte[] bodyLen = { 0x00, 0x00, 0x00, 0x00 };
byte[] emptyCRC = { 0x00, 0x00, 0x00, 0x00 };
byte[] checksum = Encoding.ASCII.GetBytes(this.checksum);
var list = new List<byte>();
list.AddRange(cmdBytes);
list.AddRange(arg1Bytes);
list.AddRange(arg2Bytes);
list.AddRange(arg3Bytes);
list.AddRange(arg4Bytes);
list.AddRange(bodyLen);
list.AddRange(emptyCRC);
list.AddRange(checksum);
var xx = list.ToArray();
string hex = BitConverter.ToString(cmdBytes).Replace("-", "");
return list.ToArray();
}发布于 2017-01-10 18:13:40
从这个例子来看,它似乎是X-25 16位CRC,而不是CCITT (Kermit) 16位CRC.有1/65536的可能性,这是一个巧合,因为只有一个例子,所以您需要尝试与更多嗅探包。
下面是一个简单的逐时位C例程,它计算CRC (用mem == NULL调用它返回CRC的初始值):
unsigned crc16x_25_bit(unsigned crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
crc = ~crc;
crc &= 0xffff;
while (len--) {
crc ^= *data++;
for (unsigned k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8408 : crc >> 1;
}
crc ^= 0xffff;
return crc;
}该代码是由克拉卡尼生成的,它还为表驱动的版本生成代码,无论是字节驱动版本还是字驱动版本。
https://stackoverflow.com/questions/41560322
复制相似问题