我无法在C#中使用CRC功能。下面是给出的示例C代码,下面是我使用的C#代码。我怀疑罪魁祸首是大端,但是当我切换校验和的字节顺序时,它仍然给出了不同的值。
我出错的任何想法?
非常感谢
马特
使用CRC-CCITT(Kermit)算法(http://www.lammertbies.nl/comm/info/crccalculation.html)计算CRC。
参数长度 - 2个字节。格式是大端。这就是字节0和1被“切换”的原因。
CRC计算算法如下所示(C编程语言)。
/*----------------------------------------------------------------------------
* FUNCTION: CRC16
*---------------------------------------------------------------------------
*/
unsigned short crc_16_rec (unsigned char *pucData, unsigned short ucLen) {
//--------------------------------------------------------------------
unsigned int i;
unsigned char ucBit, ucCarry;
//--------------------------------------------------------------------
unsigned short usPoly = 0x8408;//reversed 0x1021
unsigned short usCRC = 0;
//--------------------------------------------------------------------
for (i = 0; i < ucLen; i++) {
usCRC ^= pucData[i];
for (ucBit = 0; ucBit < 8; ucBit++) {
ucCarry = usCRC & 1;
usCRC >>= 1;
if (ucCarry) {
usCRC ^= usPoly;
}
}
}
//--------------------------------------------------------------------
return usCRC;
//--------------------------------------------------------------------
}
我使用的代码
public enum Crc16Mode : ushort { Standard = 0xA001, CcittKermit = 0x8408 }
Crc16 CRC = new Crc16(Crc16Mode.CcittKermit);
public class Crc16
{
readonly ushort[] table = new ushort[256];
public ushort ComputeChecksum(params byte[] bytes)
{
ushort crc = 0;
for (int i = 0; i < bytes.Length - 2; ++i)
{
byte index = (byte)(crc ^ bytes[i]);
crc = (ushort)((crc >> 8) ^ table[index]);
}
return crc;
}
public bool ChecksumValid(ref byte[] bytes)
{
ushort checksum = (ushort)((bytes[bytes.Length - 2] << 8) | bytes[bytes.Length - 1]);
ushort checksum_received = CRC16(bytes);
if (checksum == checksum_received)
{
return true;
}
else
{
return false;
}
}
public ushort CRC16(byte[] bytes)
{
ushort crc = 0; //(ushort.maxvalue, 65535)
for (int j = 0; j < bytes.Length; j++)
{
crc = (ushort)(crc ^ bytes[j]);
for (int i = 0; i < 8; i++)
{
if ((crc & 0x0001) == 1)
crc = (ushort)((crc >> 1) ^ 0x8408);
else
crc >>= 1;
}
}
return (ushort)~(uint)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;
}
}
}