为什么我在 C# 和 VB.NET 之间得到不同的 CRC16 结果?
Why do I get different CRC16 result between C# and VB.NET?
我将 C# 代码转换为 VB.NET 以进行 CRC16 计算。但是,我在 C# 和 VB.NET 上得到了不同的结果。我很迷惑!有人可以给我指出正确的方向吗?
//C# Codes
UInt16 CalculateCRC(Byte dchar, UInt16 crc16)
{
UInt16 mask = (UInt16) (dchar & 0x00FF);
crc16 = (UInt16)(crc16 ^ mask);
for (int i = 0; i < 8; i++)
{
UInt16 compare = (UInt16)(crc16 & 0x0001);
if ( compare == 1)
{
mask = (UInt16)(crc16 / 2);
crc16 = (UInt16)(mask ^ 0xA001);
}
else
{
mask = (UInt16)(crc16 / 2);
crc16 = mask;
}
}
return crc16;
}
'VB.NET Codes
Private Function CalculateCRC(ByVal dchar As Byte, ByVal crc16 As UInt16) As UInt16
Dim mask As UInt16 = Convert.ToUInt16((dchar And &HFF))
crc16 = Convert.ToUInt16((crc16 Xor mask))
Dim compare As UInt16
For i As Integer = 0 To 7
compare = Convert.ToUInt16((crc16 And &H1))
If compare = 1 Then
mask = Convert.ToUInt16((crc16 / 2))
crc16 = Convert.ToUInt16((mask Xor &HA001))
Else
mask = Convert.ToUInt16((crc16 / 2))
crc16 = mask
End If
Next
Return crc16
End Function
OUTPUT
dchar = 1
Variable values for each iteration (0 to 7)
C#
COMPARE : 0, 1, 0, 1, 0, 1, 0, 1
MASK : 32767, 16383, 20479, 10239, 17407, 8703, 16639, 8319,
CRC16 : 32767, 40958, 20479, 38414, 17407, 33278, 16639, 32894
VB.NET
COMPARE : 0, 1, 1, 1, 1, 1, 1, 1
MASK : 32767, 16384, 28672, 26624, 25600, 25088, 24832, 24704
CRC16 : 32767, 57345, 53249, 51201, 50177, 49665, 49409, 49281
有人可以指出我在 VB 代码中哪里做错了吗?显然 C# 代码产生了正确的结果。
正如 Jimi 在评论中指出的那样,您需要使用整数除法 - 另外,'CUShort' 应该就足够了:
Private Function CalculateCRC(ByVal dchar As Byte, ByVal crc16 As UInt16) As UInt16
Dim mask As UInt16 = CUShort(dchar And &HFF)
crc16 = CUShort(crc16 Xor mask)
For i As Integer = 0 To 7
Dim compare As UInt16 = CUShort(crc16 And &H1)
If compare = 1 Then
mask = CUShort(crc16 \ 2)
crc16 = CUShort(mask Xor &HA001)
Else
mask = CUShort(crc16 \ 2)
crc16 = mask
End If
Next i
Return crc16
End Function
我将 C# 代码转换为 VB.NET 以进行 CRC16 计算。但是,我在 C# 和 VB.NET 上得到了不同的结果。我很迷惑!有人可以给我指出正确的方向吗?
//C# Codes
UInt16 CalculateCRC(Byte dchar, UInt16 crc16)
{
UInt16 mask = (UInt16) (dchar & 0x00FF);
crc16 = (UInt16)(crc16 ^ mask);
for (int i = 0; i < 8; i++)
{
UInt16 compare = (UInt16)(crc16 & 0x0001);
if ( compare == 1)
{
mask = (UInt16)(crc16 / 2);
crc16 = (UInt16)(mask ^ 0xA001);
}
else
{
mask = (UInt16)(crc16 / 2);
crc16 = mask;
}
}
return crc16;
}
'VB.NET Codes
Private Function CalculateCRC(ByVal dchar As Byte, ByVal crc16 As UInt16) As UInt16
Dim mask As UInt16 = Convert.ToUInt16((dchar And &HFF))
crc16 = Convert.ToUInt16((crc16 Xor mask))
Dim compare As UInt16
For i As Integer = 0 To 7
compare = Convert.ToUInt16((crc16 And &H1))
If compare = 1 Then
mask = Convert.ToUInt16((crc16 / 2))
crc16 = Convert.ToUInt16((mask Xor &HA001))
Else
mask = Convert.ToUInt16((crc16 / 2))
crc16 = mask
End If
Next
Return crc16
End Function
OUTPUT
dchar = 1
Variable values for each iteration (0 to 7)
C#
COMPARE : 0, 1, 0, 1, 0, 1, 0, 1
MASK : 32767, 16383, 20479, 10239, 17407, 8703, 16639, 8319,
CRC16 : 32767, 40958, 20479, 38414, 17407, 33278, 16639, 32894
VB.NET
COMPARE : 0, 1, 1, 1, 1, 1, 1, 1
MASK : 32767, 16384, 28672, 26624, 25600, 25088, 24832, 24704
CRC16 : 32767, 57345, 53249, 51201, 50177, 49665, 49409, 49281
有人可以指出我在 VB 代码中哪里做错了吗?显然 C# 代码产生了正确的结果。
正如 Jimi 在评论中指出的那样,您需要使用整数除法 - 另外,'CUShort' 应该就足够了:
Private Function CalculateCRC(ByVal dchar As Byte, ByVal crc16 As UInt16) As UInt16
Dim mask As UInt16 = CUShort(dchar And &HFF)
crc16 = CUShort(crc16 Xor mask)
For i As Integer = 0 To 7
Dim compare As UInt16 = CUShort(crc16 And &H1)
If compare = 1 Then
mask = CUShort(crc16 \ 2)
crc16 = CUShort(mask Xor &HA001)
Else
mask = CUShort(crc16 \ 2)
crc16 = mask
End If
Next i
Return crc16
End Function