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

C# CCITT-8 CRC 算法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (19投票s)

2007 年 6 月 5 日

GPL3

1分钟阅读

viewsIcon

157205

一篇关于 C# 循环冗余校验(CRC)算法的文章

引言

很有可能,如果你来到这个页面,你正在与某种糟糕的、过时的制造/嵌入式设备通信,该设备要求你逐字节地构建消息到一个帧或其他类型的逻辑包中,并在末尾添加一个 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 日 -- 更新文章
C# CCITT-8 CRC 算法 - CodeProject - 代码之家
© . All rights reserved.