358 lines
9.3 KiB
C#
358 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace XMX
|
|
{
|
|
|
|
public enum CRCType : int
|
|
{
|
|
CRC16_IBM = 0,
|
|
CRC16_MAXIM,
|
|
CRC16_USB,
|
|
CRC16_MODBUS,
|
|
CRC16_CCITT,
|
|
CRC16_CCITT_FALSE,
|
|
CRC16_X25,
|
|
CRC16_XMODEM,
|
|
CRC16_DNP,
|
|
CRC32,
|
|
CRC32_MPEG2,
|
|
}
|
|
|
|
public class DataCheck
|
|
{
|
|
static public CRCInfo GetCRCInfo(CRCType type)
|
|
{
|
|
CRCInfo param = null;
|
|
switch (type)
|
|
{
|
|
case CRCType.CRC16_IBM:
|
|
param = new CRCInfo(0x8005, 0x0000, true, true, 0x0000);
|
|
break;
|
|
case CRCType.CRC16_MAXIM:
|
|
param = new CRCInfo(0x8005, 0x0000, true, true, 0xFFFF);
|
|
break;
|
|
|
|
case CRCType.CRC16_USB:
|
|
param = new CRCInfo(0x8005, 0xFFFF, true, true, 0xFFFF);
|
|
break;
|
|
|
|
case CRCType.CRC16_MODBUS:
|
|
param = new CRCInfo(0x8005, 0xFFFF, true, true, 0x0000);
|
|
break;
|
|
|
|
case CRCType.CRC16_CCITT:
|
|
param = new CRCInfo(0x1021, 0x0000, true, true, 0x0000);
|
|
break;
|
|
|
|
case CRCType.CRC16_CCITT_FALSE:
|
|
param = new CRCInfo(0x1021, 0xFFFF, false, false, 0x0000);
|
|
break;
|
|
|
|
case CRCType.CRC16_X25:
|
|
param = new CRCInfo(0x1021, 0xFFFF, true, true, 0xFFFF);
|
|
break;
|
|
|
|
case CRCType.CRC16_XMODEM:
|
|
param = new CRCInfo(0x1021, 0x0000, false, false, 0x0000);
|
|
break;
|
|
|
|
case CRCType.CRC16_DNP:
|
|
param = new CRCInfo(0x3D65, 0x0000, true, true, 0xFFFF);
|
|
break;
|
|
|
|
case CRCType.CRC32:
|
|
param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, true, true, 0xFFFFFFFF);
|
|
break;
|
|
case CRCType.CRC32_MPEG2:
|
|
param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, false, false, 0x00000000);
|
|
break;
|
|
}
|
|
|
|
return param;
|
|
}
|
|
|
|
static public UInt32 GetCRC(CRCType type, byte[] data)
|
|
{
|
|
CRCInfo param;
|
|
|
|
param = GetCRCInfo(type);
|
|
if (type >= CRCType.CRC16_IBM && type <= CRCType.CRC16_DNP)
|
|
{
|
|
return GetCRC16(param, data);
|
|
}
|
|
else if (type>=CRCType.CRC32 && type<=CRCType.CRC32_MPEG2)
|
|
{
|
|
return GetCRC32(param, data);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static public UInt16 GetCRC16(CRCInfo param, byte[] data)
|
|
{
|
|
UInt16 crc = (UInt16)param.Init;
|
|
UInt16 Poly = 0;
|
|
UInt16 XorOut = (UInt16)param.XorOut;
|
|
|
|
if (param.RefIn)
|
|
{
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
Poly <<= 1;
|
|
if ((param.Poly & (1u << i)) != 0)
|
|
{
|
|
Poly |= 0x01;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Poly = (UInt16)param.Poly;
|
|
}
|
|
|
|
foreach (byte b in data)
|
|
{
|
|
UInt16 bValue;
|
|
if (param.RefOut)
|
|
{
|
|
bValue = Convert.ToUInt16(b);
|
|
}
|
|
else
|
|
{
|
|
bValue = Convert.ToUInt16((UInt16)b << 8);
|
|
}
|
|
|
|
crc = Convert.ToUInt16(crc ^ bValue);
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (param.RefOut)
|
|
{
|
|
if ((crc & 0x01) != 0)
|
|
{
|
|
crc >>= 1;
|
|
crc ^= Poly;
|
|
}
|
|
else
|
|
{
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((crc & 0x8000) != 0)
|
|
{
|
|
crc <<= 1;
|
|
crc ^= Poly;
|
|
}
|
|
else
|
|
{
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Convert.ToUInt16(crc ^ XorOut);
|
|
}
|
|
|
|
static public UInt32 GetCRC32(CRCInfo param, byte[] data)
|
|
{
|
|
UInt32 crc = (UInt32)param.Init;
|
|
UInt32 Poly = 0;
|
|
UInt32 XorOut = (UInt32)param.XorOut;
|
|
|
|
if (param.RefIn)
|
|
{
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
Poly <<= 1;
|
|
if ((param.Poly & (1u << i)) != 0)
|
|
{
|
|
Poly |= 0x01;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Poly = (UInt32)param.Poly;
|
|
}
|
|
|
|
foreach (byte b in data)
|
|
{
|
|
UInt32 bValue;
|
|
if (param.RefOut)
|
|
{
|
|
bValue = Convert.ToUInt32(b);
|
|
}
|
|
else
|
|
{
|
|
bValue = Convert.ToUInt32((UInt32)b << 24);
|
|
}
|
|
|
|
crc = Convert.ToUInt32(crc ^ bValue);
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (param.RefOut)
|
|
{
|
|
if ((crc & 0x01) != 0)
|
|
{
|
|
crc >>= 1;
|
|
crc ^= Poly;
|
|
}
|
|
else
|
|
{
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((crc & 0x80000000) != 0)
|
|
{
|
|
crc <<= 1;
|
|
crc ^= Poly;
|
|
}
|
|
else
|
|
{
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Convert.ToUInt32(crc ^ XorOut);
|
|
}
|
|
|
|
|
|
static public UInt32 GetCheckSum(byte[] data)
|
|
{
|
|
UInt32 sum = 0;
|
|
|
|
foreach (byte b in data)
|
|
{
|
|
sum += b;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
static public byte GetXor(byte[] data)
|
|
{
|
|
byte xor = 0;
|
|
|
|
foreach (byte b in data)
|
|
{
|
|
xor ^= b;
|
|
}
|
|
|
|
return xor;
|
|
}
|
|
|
|
}
|
|
|
|
public class CRCInfo
|
|
{
|
|
private UInt32 _Poly;
|
|
private UInt32 _Init;
|
|
private UInt32 _XorOut;
|
|
private bool _RefIn;
|
|
private bool _RefOut;
|
|
|
|
public CRCInfo()
|
|
: this(0, 0, false, false, 0)
|
|
{
|
|
|
|
}
|
|
public CRCInfo(UInt32 poly, UInt32 init, bool refIn, bool refOut, UInt32 xorOut)
|
|
{
|
|
_Poly = poly;
|
|
_Init = init;
|
|
_RefIn = refIn;
|
|
_RefOut = refOut;
|
|
_XorOut = xorOut;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 多项式
|
|
/// </summary>
|
|
public UInt32 Poly
|
|
{
|
|
get
|
|
{
|
|
return _Poly;
|
|
}
|
|
set
|
|
{
|
|
_Poly = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始值
|
|
/// </summary>
|
|
public UInt32 Init
|
|
{
|
|
get
|
|
{
|
|
return _Init;
|
|
}
|
|
set
|
|
{
|
|
_Init = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输出CRC异或值
|
|
/// </summary>
|
|
public UInt32 XorOut
|
|
{
|
|
get { return _XorOut; }
|
|
set { _XorOut = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输入多项式反序
|
|
/// </summary>
|
|
public bool RefIn
|
|
{
|
|
get { return _RefIn; }
|
|
set { _RefIn = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输出数据反序
|
|
/// </summary>
|
|
public bool RefOut
|
|
{
|
|
get { return _RefOut; }
|
|
set { _RefOut = value; }
|
|
}
|
|
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
if ((Poly & 0xFFFF0000) != 0)
|
|
{
|
|
sb.AppendFormat("Poly: {0:X8}\r\n", Poly);
|
|
sb.AppendFormat("Init: {0:X8}\r\n", Init);
|
|
sb.AppendFormat("RefIn: {0}\r\n", RefIn ? "True" : "False");
|
|
sb.AppendFormat("RefOut:{0}\r\n", RefOut ? "True" : "False");
|
|
sb.AppendFormat("XorOut:{0:X8}", XorOut);
|
|
}
|
|
else
|
|
{
|
|
sb.AppendFormat("Poly: {0:X4}\r\n", Poly);
|
|
sb.AppendFormat("Init: {0:X4}\r\n", Init);
|
|
sb.AppendFormat("RefIn: {0}\r\n", RefIn ? "True" : "False");
|
|
sb.AppendFormat("RefOut:{0}\r\n", RefOut ? "True" : "False");
|
|
sb.AppendFormat("XorOut:{0:X4}", XorOut);
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
}
|
|
}
|