CRC编码






4.32/5 (22投票s)
2003年12月7日
2分钟阅读

268399

6600
一篇关于在 C# 中使用 CRCxxx 校验和计算的文章,结合了本网站上的 serialstreamreader 示例。
引言
许多医疗设备使用 RS232 端口进行通信,并且它们都使用一种 CRC 算法。几个月前,我尝试迁移到 .NET 和 C#。然而,许多旧的东西在 C# 中并不存在。所以你必须自己编写或移植它们。
此代码可以生成任何 CRCXX 计算,只要 XX 是 8、16、32。CCITT 只是 16,但使用不同的多项式。该项目还使用了本网站上的 serialstream 示例。我使用演示项目与现有设备进行通信。
背景
在本节中,我不会解释 CRC 校验和计算。很多东西都可以在网上找到。特别是在 Rocksoft 网站上,这是原始设计者的网站。
只是为了介绍它
循环冗余校验 (CRC) 被添加到通信协议中,以确保数据不会丢失或被更改。它是基本 RS232 通信协议中奇偶校验的更高级版本。它使用一个多项式来创建一个唯一的校验和,因此如果某个地方的位被更改,总校验和也会被更改。
使用代码
要使用该代码,只需将 CRCTool.cs 类添加到你的 C# 项目中,并将命名空间添加到你的类中
using Communication.IO.Tools
将 CRCTool
添加到你将要使用它的类中。
class Class1 { /// <SUMMARY> /// The main entry point for the application. /// </SUMMARY> /// ....... // Crc Computation Class private static CRCTool compCRC = new CRCTool(); }
告诉该类你将使用哪种 CRC。大多数函数都适用于所有类型的 CRC 编码。Init
函数用于指定每种编码的起始值:CRC16, CRC_ITT, CRC32
。它还创建了最快编码算法所需的编码表!
当你想要更改 CRC 类型时,再次调用 Init
。
// use of these values,
// enum CRCCode{CRC_CCITT, CRC16, CRC32};
// if the protocol you need is not here
// you can add it to this enum and change the relevant parameters
// in the Init function.
compCRC.Init(CRCTool.CRCCode.CRC_CCITT);
有四种方法可以计算 CRC 校验和值,第五种方法可以向你展示另一种方法。区别在于计算速度,其中 crctablefast
最快,crcbitbybit
最慢。
但是,在某些情况下,一种方法可能比另一种方法更可取。例如,请记住,查找表的计算也需要时间。因此,对于一次性计算,这将更慢。
//Four function with a little different algoritm but the same endresult.
public ulong crcbitbybit(byte[] p);
public ulong crcbitbybitfast(byte[] p);
public ulong crctable(byte[] p);
public ulong crctablefast (byte[] p);
// Not a generic but an example of how to do everything in one function
public ushort CalcCRCITT(byte[] p);
我已将其添加到 serialstream 示例中,现在命令编写代码已更改为这样。我使用 CRCITT 16 位编码。我与之通信的设备需要在消息前面加上 !,在消息结尾加上 |XXXX\r,其中 XXXX 是 CRCITT 值。
// Write command to port
byte[] rawBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(command);
compCRC.Init(CRCTool.CRCCode.CRC_CCITT);
ushort usCrc16 = (ushort)compCRC.crctablefast(rawBytes);
// The following is equal to
// sprintf( message,"!%s|%04X\r", buf, crc );
string sMessageString =
String.Format("!{0}|{1:X4}\r",command,usCrc16);
sw.WriteLine(sMessageString );
sw.Flush();
我已使用 CRC16、CRCITT、CRC32 进行了测试,所有算法都运行良好。
关注点
目前没有什么值得关注的。这取决于你如何理解这篇文章!请让我了解你的经验!