CRC-16(IBM)在C ++中的反向查找 [英] CRC-16 (IBM) Reverse Lookup in C++

查看:573
本文介绍了CRC-16(IBM)在C ++中的反向查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法创建匹配特定输出的Maxim CRC-16算法。我列出了我用来帮助我编写程序的资源:

I'm having trouble with creating a Maxim CRC-16 Algorithm that would match a specific output. I've listed the resources I've used to help me write the program below:

  • Maxim App Note 27
  • Sanity-Free CRC-16 Computation
  • Julia CRC Computation (By Andrew Cooke)
  • CRC-16 Lookup Table (in C)
  • Another CRC Lookup Table in C
  • CRC Wiki Page

对于上面的引用,我写了一个简单的程序,它将使用逐位方法计算CRC-16, up表方法。逐位方法如下所示

With the above references, I wrote a simple program that would compute the CRC-16 using both a bit by bit approach, and a look-up table approach. The bit-by-bit approach is shown below

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
#include <stdint.h>

using namespace std;

#define POLY 0x8005 // CRC-16-MAXIM (IBM) (or 0xA001)

unsigned int crc16(uint8_t data_p[])
{
    unsigned char i,j;
    unsigned int data;
    unsigned int crc = 0x0000;//0xFFFF;
    count = 0;

    //for (j = 0; j < (sizeof(data_p)/sizeof(uint8_t)); j++)
    for (j = 0; j < 11; j++)
    {
        for (i=0, data=(uint8_t)0xff & data_p[j];
                i < 8;
                i++, data >>= 1)
        {
            if ((crc & 0x0001) ^ (data & 0x0001))
            {
                crc = (crc >> 1) ^ POLY;
            }
            else  crc >>= 1;
        }
    }

    crc = ~crc;
    data = crc;
    crc = (crc << 8) | (data >> 8 & 0xff);

    return (crc);
}

以下是CRC-16计算的查找表版本

And below is the look-up table version of the CRC-16 computation

/*
 * CRC lookup table for bytes, generating polynomial is 0x8005
 * input: reflexed (LSB first)
 * output: reflexed also...
 */

const uint16_t crc_ibm_table[256] = {
  0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
  0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
  0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
  0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
  0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
  0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
  0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
  0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
  0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
  0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
  0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
  0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
  0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
  0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
  0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
  0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
  0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
  0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
  0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
  0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
  0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
  0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
  0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
  0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
  0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
  0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
  0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
  0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
  0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
  0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
  0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
  0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
};

static inline uint16_t crc_ibm_byte(uint16_t crc, const uint8_t c)
{
    const unsigned char lut = (crc ^ c) & 0xFF;
    return (crc >> 8) ^ crc_ibm_table[lut];
}



/**
 * crc_ibm - recompute the CRC for the data buffer
 * @crc - previous CRC value
 * @buffer - data pointer
 * @len - number of bytes in the buffer
 */
uint16_t crc_ibm(uint16_t crc, uint8_t const *buffer, size_t len)
{
        while (len--)
                crc = crc_ibm_byte(crc, *buffer++);
        return crc;
}

使用这些方程式,我可以计算一个8位十六进制数字数组计算CRC-16校验和值。代码编译并运行没有任何错误。

With these equations, I can compute an array of 8-bit hex numbers to calculate a CRC-16 check-sum value. The code does compile and run without any errors.

当我尝试验证这些计算的正确性时出现此问题。我的目标是试图使CRC-16的工作方式与它为这个系统相同的方式。换句话说,我想创建一个模拟在另一个系统上使用的CRC-16计算的系统。

The issue comes up when I try to verify the correctness of these computations. My goal is to try to make the CRC-16 work the same way as it does for this system. In other words, I would like to create a system that emulates the CRC-16 computation used on another system.

以下是发送到原始系统的CRC-16计算器的消息的描述:

Below is a description of what message is sent to the original system's CRC-16 calculator:


使用CRC-16多项式生成CRC,首先清除CRC发生器的
,然后移入
Write Scratchpad命令的命令代码(0Fh),目标地址TA1和TA2),所有
数据字节...数据从暂存器的
开始写入暂存器。

"This CRC is generated using the CRC-16 polynomial by first clearing the CRC generator and then shifting in the command code (0Fh) of the Write Scratchpad command, the target addresses (TA1 and TA2), and all the data bytes...The data is written to the scratchpad starting at the beginning of the scratchpad."

这样,我使用以下输入:

With this, I use the following input:

uint8_t data1[11] =
{0x0F, 0x00, 0x00, 0x91, 0x0D, 0x38, 0xA0, 0x50, 0x00, 0x00, 0x00};

在原始系统中,CRC-16以 0x4E2A ,这不是查找表或逐位CRC-16的输出。实际上,查找表计算器的CRC-16输出与逐位计算器的CRC-16输出不匹配。这不是一个大惊喜,因为我用于这个计算的表很可能不是像我计算CRC-16的其他方法一样计算。

In the original system, the CRC-16 comes out as 0x4E2A, which is not the output for either the look-up table or bit-by-bit CRC-16. In fact, the CRC-16 output from the look-up table calculator does not match the CRC-16 output from the bit-by-bit calculator. This doesn't come as a big surprise, since the table that I use for this calculation most likely was not calculated the same way as my other approach in calculating the CRC-16.

TL; DR:最后,我想要的是一种计算CRC-16的方法,使得它匹配当我发送给定输入时原始系统给出的输出。我也有兴趣了解如何使一个CRC-16查找表,以便它将匹配我的逐位方法(也使用我的8位数字作为输入数组)。

TL;DR: Ultimately, what I would like is a way to calculate the CRC-16 so that it matches the output the original system gives when I send the given input. I'm also interested in learning about how I can make a CRC-16 look-up table so that it would match my -bit-by-bit approach (with also using my array of 8-bit numbers as inputs). Any advice would be appreciated.

推荐答案

此代码:

#include <stdio.h>

#define POLY 0xa001

unsigned crc16(unsigned crc, unsigned char *buf, size_t len)
{
    while (len--) {
        crc ^= *buf++;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
    }
    return crc;
}

int main(void)
{
    unsigned crc;
    unsigned char buf[] = {0x75};

    crc = crc16(0x90f1, buf, 1);
    printf("%04x\n", crc);
    return 0;
}

将打印在maxim页面上显示的示例结果, 6390

will print the example result shown on the maxim page, 6390.

这篇关于CRC-16(IBM)在C ++中的反向查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆