C# CCITT-8 CRC 算法
一篇关于 C# 循环冗余校验(
引言
很有可能,如果你来到这个页面,你正在与某种糟糕的、过时的制造/嵌入式设备通信,该设备要求你逐字节地构建消息到一个帧或其他类型的逻辑包中,并在末尾添加一个 CCITT-8 CRC 校验和。无论如何,我不会在这里赘述 CRC、校验和等等。如果你想了解它们,网上有很多关于这些主题的文章。
背景
我找不到任何 C# CCITT-8 CRC 算法。所以,当我最终完成这个任务时,我决定发布它,希望能帮助某人避免我经历过的徒劳搜索。我还收到了来自一些随机开发者的宝贵反馈,并将他们的一些有用的评论应用到这段代码的更新版本中。希望对你有所帮助。
Using the Code
这是示例类;它非常简单。你可能只想将其剪切并粘贴到你的项目中。要使用它,请传入包含需要校验和的字节数组。它会将 8 位校验和作为单个字节返回。你基本上创建一个新的类实例,传入用于计算校验和的多项式。我在这里只包含 8 位多项式,因为我认为其他所有内容在网上都有很好的表示。你可以通过调用 GenerateTable
函数并使用属性设置器来设置表,从而为单个类实例重新计算表。
///
/// This enum is used to indicate what kind of checksum you will be calculating.
///
public enum CRC8_POLY
{
CRC8 = 0xd5,
CRC8_CCITT = 0x07,
CRC8_DALLAS_MAXIM = 0x31,
CRC8_SAE_J1850 = 0x1D,
CRC_8_WCDMA = 0x9b,
};
///
/// Class for calculating CRC8 checksums...
///
public class CRC8Calc {
private byte[] table = new byte[256];
public byte Checksum(params byte[] val )
{
if(val == null)
throw new ArgumentNullException("val");
byte c = 0;
foreach ( byte b in val )
{
c = table[c ^ b];
}
return c;
}
public byte[] Table
{
get
{
return this.table;
}
set
{
this.table = value;
}
}
public byte[] GenerateTable(CRC8_POLY polynomial)
{
byte[] csTable = new byte[256];
for ( int i = 0; i < 256; ++i )
{
int curr = i;
for ( int j = 0; j < 8; ++j )
{
if ((curr & 0x80) != 0)
{
curr = (curr << 1) ^ (int)polynomial;
}
else
{
curr <<= 1;
}
}
csTable[i] = (byte)curr;
}
return csTable;
}
public CRC8Calc(CRC8_POLY polynomial)
{
this.table = this.GenerateTable(polynomial);
}
}
示例
using System;
public class CRC8Test
{
public static void RunSnippet()
{
byte checksum;
byte[] testVal = new byte[]
{0xee, 0x01, 0x13, 0x00, 0x06, 0x1c, 0x00, 0x20, 0x1d, 0x00, 0x00};
CRC8Calc crc_dallas = new CRC8Calc(CRC8_POLY.CRC8_DALLAS_MAXIM);
checksum = crc_dallas.Checksum(testVal);
WL(checksum);
CRC8Calc crc = new CRC8Calc(CRC8_POLY.CRC8_CCITT);
checksum = crc.Checksum(testVal);
WL(checksum);
}
#region Helper methods
public static void Main()
{
try
{
RunSnippet();
}
catch (Exception e)
{
string error = string.Format
("---\nThe following error occurred while executing
the snippet:\n{0}\n---", e.ToString());
Console.WriteLine(error);
}
finally
{
Console.Write("Press any key to continue...");
Console.ReadKey();
}
}
private static void WL(object text, params object[] args)
{
Console.WriteLine(text.ToString(), args);
}
#endregion
}
历史
- 2007 年 6 月 5 日 -- 发布原始版本
- 2010 年 2 月 5 日 -- 更新文章