CRC 16,C至C#
我有这个CRC-16计算的代码示例,我想把它转换成C。它必须保持相同的逻辑,因为它与其他机器一起工作CRC 16,C至C#,c#,c,crc,crc16,C#,C,Crc,Crc16,我有这个CRC-16计算的代码示例,我想把它转换成C。它必须保持相同的逻辑,因为它与其他机器一起工作 我看到了这一点,但它不起作用(不同的结果),可能是因为变量类型 原始代码是:Input char='A',余数=0,Output=390 #define CRC_POLYNOMIAL 0x8005 /* CRC polynomial */ short Calculate_CRC ( char ch, short remainder ){ char *ch_ptr; int i;
我看到了这一点,但它不起作用(不同的结果),可能是因为变量类型 原始代码是:Input char='A',余数=0,Output=390
#define CRC_POLYNOMIAL 0x8005 /* CRC polynomial */
short Calculate_CRC ( char ch, short remainder ){
char *ch_ptr;
int i;
// the different part
ch_ptr = (char*)&remainder;
*(ch_ptr+1) = *(ch_ptr+1) ^ ch; /* exclusive or ch with msb of remainder */
for (i=0; i<=7; i++)
if (remainder < 0)
{ /* msb of remainder = 1 */
remainder = remainder << 1;
remainder = remainder ^ CRC_POLYNOMIAL;
}
else
remainder = remainder << 1;
return (remainder);
}
#定义CRC_多项式0x8005/*CRC多项式*/
短计算CRC(字符通道,短余数){
char*CHU ptr;
int i;
//不同的部分
ch_ptr=(字符*)&余数;
*(ch_ptr+1)=*(ch_ptr+1)^ch;/*互斥或带有余数msb的ch*/
对于(i=0;i而言,您的C#代码并不等同于您的C代码。具体而言:
…异或ch
,其最低有效字节为余数
,而C代码中的相应操作是具有最高有效字节的异或
此外,这条C#线:
…似乎与C代码中的任何内容都不对应,而且从表面上看它是错误的。我想您的意思是将两个字节重新组合为余数
,但这不起作用。我建议完全不使用rawCrc
,而是执行类似的操作
remainder = remainder ^ ((ch & 0xff) << 8);
…与C代码中的相应测试相反,并且与尾随注释所声明的含义不一致。试试这个…它应该(应该)与C版本等效。请注意,我删除了字节[]
数组
const short CRC_POLYNOMIAL = unchecked((short)0x8005);
static short Calculate_CRC(byte ch, short remainder)
{
short ch_ptr = (short)(remainder & 0xFF);
ch_ptr |= (short)((remainder & 0xFF00) ^ (ch << 8));
// You could directly use ch_ptr from now on!
remainder = ch_ptr;
for (int i = 0; i <= 7; i++)
{
if (remainder < 0)
{ /* msb of remainder = 1 */
remainder = (short)(remainder << 1);
remainder = (short)(remainder ^ CRC_POLYNOMIAL);
}
else
{
remainder = (short)(remainder << 1);
}
}
return remainder;
}
C代码中的这一行:*(ch_ptr+1)=*(ch_ptr+1)^ch;
在ch
余数的高位字节上是独占的。这是一种可怕的方法,因为在大端机器上会失败。在C语言中,他们应该做的是rements^=(短)有什么问题吗?你能把你的错误例外也放在你的帖子里吗?不同的结果两个实现的哪个步骤开始不同?嗯?在哪一行?哪些值不同?不同的值是什么?你没有提供导致问题的输入。它仍然返回相同的结果。我不知道既然我没有给你一个完整的重新编写的解决方案,但是如果你说你解决了我指出的所有问题,但是你的C代码产生了相同的结果,那么你要么(I)你错了,要么(ii)原因在其他地方。正如您在另一个答案中所看到的,代码有点不同,因此可能问题在其他地方,第二个代码返回0,但第一个代码正在工作(至少在我的示例中)。谢谢!@RoyAncri更正了第二个版本…当您直接在so编辑框中编程时会发生这种情况:-)
remainder &= (byte)(rawCrc[0]);
remainder = remainder ^ ((ch & 0xff) << 8);
if ((remainder & (0x8000)) == 0) { /* msb of remainder = 1 */
const short CRC_POLYNOMIAL = unchecked((short)0x8005);
static short Calculate_CRC(byte ch, short remainder)
{
short ch_ptr = (short)(remainder & 0xFF);
ch_ptr |= (short)((remainder & 0xFF00) ^ (ch << 8));
// You could directly use ch_ptr from now on!
remainder = ch_ptr;
for (int i = 0; i <= 7; i++)
{
if (remainder < 0)
{ /* msb of remainder = 1 */
remainder = (short)(remainder << 1);
remainder = (short)(remainder ^ CRC_POLYNOMIAL);
}
else
{
remainder = (short)(remainder << 1);
}
}
return remainder;
}
const ushort CRC_POLYNOMIAL = (ushort)0x8005;
static ushort Calculate_CRC(byte ch, ushort remainder)
{
ushort remainder2 = (ushort)(remainder & 0xFF);
remainder2 |= (ushort)((remainder & 0xFF00) ^ (ch << 8));
for (int i = 0; i <= 7; i++)
{
if (remainder2 > short.MaxValue)
{ /* msb of remainder = 1 */
remainder2 = (ushort)(remainder2 << 1);
remainder2 = (ushort)(remainder2 ^ CRC_POLYNOMIAL);
}
else
{
remainder2 = (ushort)(remainder2 << 1);
}
}
return remainder2;
}
static ushort Calculate_CRC(byte ch, ushort crc) {
crc ^= (ushort)(ch << 8);
for (int i = 0; i < 8; i++)
crc = (ushort)((crc & 0x8000) == 0 ? crc << 1 : (crc << 1) ^ 0x8005);
return crc;
}