65.9K
CodeProject 正在变化。 阅读更多。
Home

CRC编码

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.32/5 (22投票s)

2003年12月7日

2分钟阅读

viewsIcon

268399

downloadIcon

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 进行了测试,所有算法都运行良好。

关注点

目前没有什么值得关注的。这取决于你如何理解这篇文章!请让我了解你的经验!

© . All rights reserved.