现在用C#写一个串口程序,请问一下下面的C语言的CRC校验码怎么写成C#的,因为有指针,C#好像是没有指针的
uint crc_data(unsigned char volatile *ptr,unsigned char len)
{
unsigned int crc ;
unsigned char da;
unsigned int crc_ta[16]=
{
//十六进制数组
};
crc = 0;
//ptr++;
while(len--!=0)
{
da=((uchar)(crc/256))/16 ;
crc <<= 4;
crc ^= crc_ta[da^(*ptr/16)] ;
da=((uchar)(crc/256))/16 ;
crc <<= 4;
crc ^= crc_ta[da^(*ptr&0x0f)] ;
ptr++ ;
}
return crc;
百度搜“C# CRC校验”
你这个不是算法计算,你这个代码是crc查表法
ps:crc算法取决于特征二项式,纯算法计算需要实时和二项式运算,所以对字节,性能上比较计较的C++的人都采用查表法---预先把数据计算出来,然后用查表法查值异或,当然你目前这个代码,在特征二项式上是空的 crc_ta[16],实际使用你得根据双方约定的二项式预先填入数据才可以
在多说一句把,方便你有统一认识。前几年曾经火的AI的基础卷积特征,本质上其实跟Crc就是一个东西。不过人家玩图像的用的是N*N的多维特征卷积,crc用的一维特征卷积
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CRC16
{
class Program
{
static void Main(string[] args)
{
/*short s = 3333;
byte b1 = (byte)s;
byte b2;
unchecked
{
b2 = Convert.ToByte(s);
}
Console.WriteLine("{0}, {1}, {2}", b1, b2, unchecked((byte)s));
*/
byte[] d = { 0x01, 0x00, 0x03, 0x01, 0x00, 0x01 };
d = new byte[] { 0xFF, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00 };
int i = 0;
//1.置16位寄存器为全1,作为CRC寄存器。
UInt16 crc = 0x0000;// 0xffff;
UInt16 mask = 0x1021;
mask = 0xa001;
do
{
for (int j = 0; j < 8; j++)
{
//2.把一个8位数据与16位CRC寄存器的低字节相异或,把结果放于CRC寄存器中。
crc ^= d[i];
//3.把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位(移出位)。
crc >>= 1;
//4.如果最低位为0,重复2.3(再移位);如果最低位为1,CRC寄存器与多项式A001H(1010 0000 0000 0001)进行异或。
if ((crc & 0x0001) == 1) crc ^= mask;// 0xa001;
//5.重复2.3、2.4,直到右移8次,这样整个8位数据全部进行了处理。
}
//6.重复2.2-2.5,进行下一个8位数据的处理。
}
while (++i < d.Length);
//7.将一帧的所有数据字节处理完后得到CRC-16寄存器。
//8.将CRC-16寄存器的低字节和高字节交换,得到的值即为CRC-16码。
var ccrc = crc ^ 0x0000;
Console.WriteLine(ccrc.ToString("X4"));
Console.WriteLine(CRC16_MODBUS(d, (UInt16)d.Length).ToString("X4"));
Console.WriteLine(CRC16_MODBUS(d).ToString("X4"));
}
static int CRC16_MODBUS(byte[] puchMsg)
{
int wCRCin = 0x0000;
int wCPoly = 0x1021;
int wChar = 0;
int k = 0;
int usDataLen = puchMsg.Length;
while (usDataLen-- > 0)
{
wChar = puchMsg[k++];
wCRCin ^= wChar << 8;
for (int i = 0; i < 8; i++)
{
if ((wCRCin & 0x8000) > 0)
wCRCin = (UInt16)((wCRCin << 1) ^ wCPoly);
else
wCRCin = (UInt16)(wCRCin << 1);
}
}
return (wCRCin);
}
static UInt16 CRC16_MODBUS(byte[] puchMsg, UInt16 usDataLen)
{
UInt16 wCRCin = 0x0000;
UInt16 wCPoly = 0x1021;
UInt16 wChar = 0;
int k = 0;
while (usDataLen-- > 0)
{
wChar = puchMsg[k++];
//InvertUint8(&wChar,&wChar);
wCRCin ^= (UInt16)(wChar << 8);
for (int i = 0; i < 8; i++)
{
if ((wCRCin & 0x8000) > 0)
wCRCin = (UInt16)((wCRCin << 1) ^ wCPoly);
else
wCRCin = (UInt16)(wCRCin << 1);
}
}
//InvertUint16(&wCRCin,&wCRCin);
return (wCRCin);
}
//static void InvertUint8(ref
}
}