做的软件需要个单片机打交道,通讯走的TCP里面校验数据CRC了。
因为用到了不同语言,所以整理下这块的使用。
1. go 语言 CRC 计算 CRC-16/XMODEM
var crc16tab = []uint16{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
}
/**
* CRC-16/XMODEM (Go语言)
*/
func Crc16_xmodem(buf []byte) uint16 {
var crc uint16 = 0
var ch byte = 0
size := len(buf)
for i := 0; i < size; i++ {
ch = byte(crc >> 12)
crc <<= 4
crc ^= crc16tab[ch^(buf[i]/16)]
ch = byte(crc >> 12)
crc <<= 4
crc ^= crc16tab[ch^(buf[i]&0x0f)]
}
return crc
}
使用:
//beforeCheck1 = ",50,DAT,070137180952,6B90BDE6,OK,00,230220164148,00,00,00,00,00,00,00,00," test---------
crc1Info := utils.Crc16_xmodem([]byte(beforeCheck1)) //HelpMethods.crcCheck(beforeCheck1.getBytes());
//fmt.Printf("check sum:%X \n", crc1Info)
crc1 := fmt.Sprintf("%X", crc1Info)
if len(crc1) == 3 {
crc1 = "0" + crc1
}
2. java 语言 CRC 计算 CRC-16/XMODEM
public static String crcCheck(byte[] bytes) {
int crc = 0x00;
int polynomial = 0x1021;
for (int index = 0; index < bytes.length; index++) {
byte b = bytes[index];
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
crc ^= polynomial;
}
}
crc &= 0xffff;
return Integer.toHexString(crc).toUpperCase();
}
调用:
String beforeCheck1 = "," + Integer.toHexString(length + 10).toUpperCase() + notLength;
String crc1 = HelpMethods.crcCheck(beforeCheck1.getBytes());
3.C# 语言 CRC 计算 CRC-16/XMODEM
// crc 校验
public static int CRC_XModem(byte[] bytes)
{
int crc = 0x00; // initial value
int polynomial = 0x1021;
for (int index = 0; index < bytes.Length; index++)
{
byte b = bytes[index];
for (int i = 0; i < 8; i++)
{
bool bit = ((b >> (7 - i) & 1) == 1);
bool c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
return crc;
}
调用:
string sdata = ",25,RPM," + dateStr + "," + deviceId + ",";
byte[] bytesend = System.Text.Encoding.ASCII.GetBytes(sdata);
int icrc16 = CRC_XModem(bytesend);
string scrc = icrc16.ToString("x4").ToUpper();
Console.WriteLine(scrc);