从字符串计算 Modbus RTU 的 CRC
calculate CRC for Modbus RTU from strings
我有字符串:02 03 04 50 00 01
。我需要计算这个字符串的 CRC。
我有一个计算 CRC 的函数:
public static UInt16 ModRTU_CRC(ushort[] buf, int len)
{
UInt16 crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (UInt16)buf[pos];
for (int i = 8; i != 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else
crc >>= 1;
}
}
return crc;
}
我想将字符串转换为 ushort 数组:
ushort[] result = cmd.Split(' ').Select(item => Convert.ToUInt16(item, 16)).ToArray();
但是这样一个数组返回给我:2 3 4 80 0 1
。
请告诉我应该怎么做才能正确计算 CRC。
看来,你想合并两个byte
到ushort
,即对于给定的
string cmd = "02 03 04 50 00 01";
你想得到
{0x0203, 0x0405, 0x0001}
如果是你的话,
using System.Linq;
...
string cmd = "02 03 04 50 00 01";
ushort[] result = cmd
.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select((value, index) => new { index, value = Convert.ToInt32(value, 16) })
.GroupBy(item => item.index / 2, item => item.value)
.Select(group => (UInt16)(group.Aggregate((s, a) => s * 256 + a)))
.ToArray();
一起来看看:
Console.WriteLine(string.Join(" ", data.Select(item => item.ToString("x4"))));
结果:
0203 0450 0001
编辑:如果你想不合并第skip
项(见下面的评论),你可以尝试修改GroupBy
:
int skip = 2;
ushort[] data = source
.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select((value, index) => new { index, value = Convert.ToInt32(value, 16) })
.GroupBy(item => item.index >= skip ? item.index / 2 : -item.index - 1,
item => item.value)
.Select(group => (UInt16)(group.Aggregate((s, a) => s * 256 + a)))
.ToArray();
Console.WriteLine(string.Join(" ", data.Select(item => item.ToString("x4"))));
结果:(02
和 03
保持不变,04
结合 50
,00
01
)
0002 0003 0450 0001
我有字符串:02 03 04 50 00 01
。我需要计算这个字符串的 CRC。
我有一个计算 CRC 的函数:
public static UInt16 ModRTU_CRC(ushort[] buf, int len)
{
UInt16 crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (UInt16)buf[pos];
for (int i = 8; i != 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else
crc >>= 1;
}
}
return crc;
}
我想将字符串转换为 ushort 数组:
ushort[] result = cmd.Split(' ').Select(item => Convert.ToUInt16(item, 16)).ToArray();
但是这样一个数组返回给我:2 3 4 80 0 1
。
请告诉我应该怎么做才能正确计算 CRC。
看来,你想合并两个byte
到ushort
,即对于给定的
string cmd = "02 03 04 50 00 01";
你想得到
{0x0203, 0x0405, 0x0001}
如果是你的话,
using System.Linq;
...
string cmd = "02 03 04 50 00 01";
ushort[] result = cmd
.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select((value, index) => new { index, value = Convert.ToInt32(value, 16) })
.GroupBy(item => item.index / 2, item => item.value)
.Select(group => (UInt16)(group.Aggregate((s, a) => s * 256 + a)))
.ToArray();
一起来看看:
Console.WriteLine(string.Join(" ", data.Select(item => item.ToString("x4"))));
结果:
0203 0450 0001
编辑:如果你想不合并第skip
项(见下面的评论),你可以尝试修改GroupBy
:
int skip = 2;
ushort[] data = source
.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select((value, index) => new { index, value = Convert.ToInt32(value, 16) })
.GroupBy(item => item.index >= skip ? item.index / 2 : -item.index - 1,
item => item.value)
.Select(group => (UInt16)(group.Aggregate((s, a) => s * 256 + a)))
.ToArray();
Console.WriteLine(string.Join(" ", data.Select(item => item.ToString("x4"))));
结果:(02
和 03
保持不变,04
结合 50
,00
01
)
0002 0003 0450 0001