[英]What the lack of CRC-CCITT (0xFFFF)?
Based Online CRC calculation , when I entered hex string data = 基于在线CRC计算 ,当我输入十六进制字符串数据=
503002080000024400003886030400000000010100 503002080000024400003886030400000000010100
I get result CRC-CCITT (0xFFFF) = 我得到结果CRC-CCITT(0xFFFF) =
0x354E (Expected Result) 0x354E(预期结果)
. 。
I use the code below, but the results of CalcCRC16() are 0xACEE . 我使用下面的代码,但CalcCRC16()的结果为0xACEE 。 What the lack of script below? 下面缺少什么脚本?
using System;
using System.Windows.Forms;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Diagnostics;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
string result = CalcCRC16("503002080000024400003886030400000000010100");
Debug.Print(result);
// result = ACEE
// result expected = 354E
}
// CRC-CCITT (0xFFFF) with poly 0x1021
// input (hex string) = "503002080000024400003886030400000000010100"
// result expected (hex string) = "354E"
public string CalcCRC16(string strInput) {
ushort temp = 0;
ushort crc = 0xFFFF;
byte[] bytes = GetBytesFromHexString(strInput);
for (int j = 0; j < bytes.Length; j++) {
crc = (ushort)(crc ^ bytes[j]);
for (int i = 0; i < 8; i++) {
if ((crc & 0x0001) == 1)
crc = (ushort)((crc >> 1) ^ 0x1021);
else
crc >>= 1;
}
}
crc = (ushort)~(uint)crc;
temp = crc;
crc = (ushort)((crc << 8) | (temp >> 8 & 0xFF));
return crc.ToString("X4");
}
public Byte[] GetBytesFromHexString(string strInput) {
Byte[] bytArOutput = new Byte[] { };
if (!string.IsNullOrEmpty(strInput) && strInput.Length % 2 == 0) {
SoapHexBinary hexBinary = null;
try {
hexBinary = SoapHexBinary.Parse(strInput);
if (hexBinary != null)
bytArOutput = hexBinary.Value;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
return bytArOutput;
}
}
}
I found the answer and I will share here.. may be useful to others. 我找到了答案,我将在这里分享..可能对其他人有用。
strInput = 503002080000024400003886030400000000010100 strInput = 503002080000024400003886030400000000010100
initial = 0xFFFF 初始= 0xFFFF
poly = 0x1021 多边形= 0x1021
strOutput = 354E str输出= 354E
reference = Online CRC Calc 参考= 在线CRC计算
public string CalcCRC16(string strInput) {
ushort crc = 0xFFFF;
byte[] data = GetBytesFromHexString(strInput);
for (int i = 0; i < data.Length; i++) {
crc ^= (ushort)(data[i] << 8);
for (int j = 0; j < 8; j++) {
if ((crc & 0x8000) > 0)
crc = (ushort)((crc << 1) ^ 0x1021);
else
crc <<= 1;
}
}
return crc.ToString("X4");
}
public Byte[] GetBytesFromHexString(string strInput) {
Byte[] bytArOutput = new Byte[] { };
if (!string.IsNullOrEmpty(strInput) && strInput.Length % 2 == 0) {
SoapHexBinary hexBinary = null;
try {
hexBinary = SoapHexBinary.Parse(strInput);
if (hexBinary != null) {
bytArOutput = hexBinary.Value;
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
return bytArOutput;
}
Here's an example which works in my application. 这是一个适用于我的应用程序的示例。 I struggled somewhat, now I know its because I had to use char ptrs in stead of 16bit int pointers (because CCIT is LSB order first, so we pick 1 byte from the buffer, shift it 8 times to make it 16bit to validate the upper MSB bit 0x8000). 我有些挣扎,现在我知道了,因为我必须使用char ptrs代替16bit的int指针(因为CCIT首先是LSB顺序,所以我们从缓冲区中选择1个字节,将其移位8次以使其变为16bit,以验证高位MSB位0x8000)。
Most causes found when people struggle with 16bit CRC (while 8bit most of the time works): 人们在使用16位CRC进行挣扎时发现了大多数原因(而大多数时候8bit起作用):
BOOL = unsigned char. BOOL =未签名的字符。 UINT16 = unsigned short. UINT16 =无符号的短路。 The function runs in code, so not a while/forloop. 该函数在代码中运行,因此不是while / forloop。 When done, the CRC is copied to the address pointed by *crc. 完成后,将CRC复制到* crc指向的地址。 This way all ather tasks (M95 modem, MCP's I2C, Flash logs, TCP/IP etc. will be handled without too large delays). 这样,所有其他任务(M95调制解调器,MCP的I2C,闪存日志,TCP / IP等)都将得到处理,而不会出现太大的延迟。
BOOL CRC_16(UINT16 ui16_Bytes, char *src, UINT16 *crc)
{
static BOOL bNew = FALSE;
static UINT16 remainder = 0;
static UINT16 i = 0;
static UINT16 ui16_Loc_bytes;
static char *ptr;
static char locData;
if(!bNew)
{
ui16_Loc_bytes = ui16_Bytes;
ptr = src;
locData = *ptr;
i = 8;
remainder = 0x0000;
bNew = TRUE;
}
if(ui16_Loc_bytes)
{
if(i == 8)
{
remainder ^= (((UINT16)locData)<<8); //Only 8bits at a time filled with zeros
}
if(i)
{
if (remainder & 0x8000)
{
remainder = (remainder << 1);
remainder ^= POLYNOMIAL_16;
}
else
{
remainder = (remainder << 1);
}
i--;
}
else
{
ui16_Loc_bytes--;
ptr++;
locData = *ptr;
//ptr++;
i = 8;
}
}
else
{
bNew = FALSE;
*crc = remainder;
return TRUE;
}
return FALSE;
}
if(SDKaart.ui16_RecBytes >= SDKaart.ui16_ByteLen)//30-5-2018 edited SDKaart.CMD[SDKaart.ui8_ActiefCMD].ui16_RecLen)
{
SD_DESELECT;
if(SDKaart.bInitReady && SDKaart.b_BlockRead)
{
if(CRC_16(512,(char*)&SDKaart.Mem_Block.SD_Buffer[0], &SDKaart.ui16_MemBlock_CRC))
{
if((((UINT16)SDKaart.Mem_Block.SD_Buffer[512]<<8)|(UINT16)SDKaart.Mem_Block.SD_Buffer[513]) == SDKaart.ui16_MemBlock_CRC)
{
SDKaart.bRXReady = TRUE;
SDKaart.TXStat = SPI_IDLE;
printf("CRC16 OK %x\r\n",SDKaart.ui16_MemBlock_CRC);
}
else
{
SDKaart.bRXReady = TRUE;
SDKaart.TXStat = SPI_IDLE;
printf("CRC16 %u != 0x%x 0x%x\r\n",SDKaart.ui16_MemBlock_CRC,SDKaart.Mem_Block.SD_Buffer[512], SDKaart.Mem_Block.SD_Buffer[513] );
}
//printf("CRC citt: %u\r\n", Calculate_CRC_CCITT((char *)&SDKaart.Mem_Block.SD_Buffer[0],512));
}
}
else
{
SDKaart.bRXReady = TRUE;
SDKaart.TXStat = SPI_IDLE;
}
}
else
{
if(SD_SPI_TX_READY)
{
SDKaart.bNewSPIByte = TRUE;
SPI1BUF = SD_EMPTY_BYTE;
}
}
I have used many crcs found online, but a lottt didn't work. 我使用了许多在网上找到的crcs,但是lottt没用。 Be aware a lot of online "examples" do use <<1 behind the XOR, but it must be done before xor. 请注意,许多在线“示例”确实在XOR后面使用<< <<,但是必须在xor之前完成。
POLY_16 is 0x1021. POLY_16为0x1021。 Next oppurtunity is to build a table picker. 下一个机会是构建表选择器。 :) :)
Greetz, John 约翰·格蕾兹
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.