CRC4 在 C 中的实现

2023-12-27

我修改了发现的实现here https://stackoverflow.com/questions/28656471/how-to-confgure-calculation-of-crc-table,为 CRC4 构建表生成函数,如下所示:

#define bufferSize 16
crc crcTable[bufferSize];
#define POLYNOMIAL 0x13

void Init()
{
    crc remainder;

     for(int dividend = 0; dividend < bufferSize; ++dividend)
     {
          remainder = dividend;
          for(uint8_t bit = 8; bit > 0; --bit)
          {
              if(remainder & 1)
                  remainder = (remainder >> 1) ^ POLYNOMIAL;
              else
                  remainder = (remainder >> 1);
          }

          crcTable[dividend] = remainder;
          printf("%hu\n", remainder);
    }
}

然后计算 CRC,如下所示:

uint8_t calc_crc4(uint8_t start_crc, uint8_t byte)
{
    byte ^= start_crc;
    start_crc = crcTable[byte] ^ (start_crc >> 8);

    return start_crc;
}

生成的 crcTable 为:

/*
* Table based on Polynomial 0x13
*/
uint8_t crcTable[tableSize] = {
    0x00, 0x0E, 0x1C, 0x12,
    0x1F, 0x11, 0x03, 0x0D,
    0x19, 0x17, 0x05, 0x0B,
    0x06, 0x08, 0x1A, 0x14
};

问题是,当我针对 ERF 文件运行它时,生成的 CRC 值都不等于附加到 ERF 帧末尾的值。当我打印值时,它看起来像是调用crcTable[byte]在里面calc_crc4函数几乎总是返回值 0x00,但我对这个概念的理解不够好,无法知道这是否是正确的值。我唯一能想到的是它在字节的索引位置没有找到任何东西,所以它返回0x00。我假设 CRC4 只能有 16 个值,所以该位置必须有一些东西。


您没有所需 CRC 的完整定义,并且您尝试将实现推断为四位有很多错误。

首先,您需要了解的不仅仅是多项式。您需要知道 CRC 是否被反映,输出是否也被反映,初始寄存器值是什么,以及输出是否与某个值进行异或。

其次,如果一次处理一个字节,则无论 CRC 的长度如何,该表都需要有 256 个条目。此外,每个条目必须是 CRC 的长度,在本例中为 4 位,而条目的长度为 5 位。此外,您还需要将 CRC 放在字节的正确末尾,以便在表查找之前进行初始异或操作,或者移动表。如前所述,下移八位的八位值为零,因此与之进行异或运算不会产生任何效果。

四位 CRC 的表驱动实现类似于其中之一,具体取决于反射。

static unsigned char const table_byte[256] = {
    0x90, 0xa0, 0xf0, 0xc0, 0x50, 0x60, 0x30, 0x00, 0x20, 0x10, 0x40, 0x70, 0xe0,
    0xd0, 0x80, 0xb0, 0xc0, 0xf0, 0xa0, 0x90, 0x00, 0x30, 0x60, 0x50, 0x70, 0x40,
    0x10, 0x20, 0xb0, 0x80, 0xd0, 0xe0, 0x30, 0x00, 0x50, 0x60, 0xf0, 0xc0, 0x90,
    0xa0, 0x80, 0xb0, 0xe0, 0xd0, 0x40, 0x70, 0x20, 0x10, 0x60, 0x50, 0x00, 0x30,
    0xa0, 0x90, 0xc0, 0xf0, 0xd0, 0xe0, 0xb0, 0x80, 0x10, 0x20, 0x70, 0x40, 0xe0,
    0xd0, 0x80, 0xb0, 0x20, 0x10, 0x40, 0x70, 0x50, 0x60, 0x30, 0x00, 0x90, 0xa0,
    0xf0, 0xc0, 0xb0, 0x80, 0xd0, 0xe0, 0x70, 0x40, 0x10, 0x20, 0x00, 0x30, 0x60,
    0x50, 0xc0, 0xf0, 0xa0, 0x90, 0x40, 0x70, 0x20, 0x10, 0x80, 0xb0, 0xe0, 0xd0,
    0xf0, 0xc0, 0x90, 0xa0, 0x30, 0x00, 0x50, 0x60, 0x10, 0x20, 0x70, 0x40, 0xd0,
    0xe0, 0xb0, 0x80, 0xa0, 0x90, 0xc0, 0xf0, 0x60, 0x50, 0x00, 0x30, 0x70, 0x40,
    0x10, 0x20, 0xb0, 0x80, 0xd0, 0xe0, 0xc0, 0xf0, 0xa0, 0x90, 0x00, 0x30, 0x60,
    0x50, 0x20, 0x10, 0x40, 0x70, 0xe0, 0xd0, 0x80, 0xb0, 0x90, 0xa0, 0xf0, 0xc0,
    0x50, 0x60, 0x30, 0x00, 0xd0, 0xe0, 0xb0, 0x80, 0x10, 0x20, 0x70, 0x40, 0x60,
    0x50, 0x00, 0x30, 0xa0, 0x90, 0xc0, 0xf0, 0x80, 0xb0, 0xe0, 0xd0, 0x40, 0x70,
    0x20, 0x10, 0x30, 0x00, 0x50, 0x60, 0xf0, 0xc0, 0x90, 0xa0, 0x00, 0x30, 0x60,
    0x50, 0xc0, 0xf0, 0xa0, 0x90, 0xb0, 0x80, 0xd0, 0xe0, 0x70, 0x40, 0x10, 0x20,
    0x50, 0x60, 0x30, 0x00, 0x90, 0xa0, 0xf0, 0xc0, 0xe0, 0xd0, 0x80, 0xb0, 0x20,
    0x10, 0x40, 0x70, 0xa0, 0x90, 0xc0, 0xf0, 0x60, 0x50, 0x00, 0x30, 0x10, 0x20,
    0x70, 0x40, 0xd0, 0xe0, 0xb0, 0x80, 0xf0, 0xc0, 0x90, 0xa0, 0x30, 0x00, 0x50,
    0x60, 0x40, 0x70, 0x20, 0x10, 0x80, 0xb0, 0xe0, 0xd0};

unsigned crc4interlaken_byte(unsigned crc, void const *mem, size_t len) {
    unsigned char const *data = mem;
    if (data == NULL)
        return 0;
    crc &= 0xf;
    crc <<= 4;
    while (len--)
        crc = table_byte[crc ^ *data++];
    crc >>= 4;
    return crc;
}

or

static unsigned char const table_byte[256] = {
    0x0, 0x7, 0xe, 0x9, 0x5, 0x2, 0xb, 0xc, 0xa, 0xd, 0x4, 0x3, 0xf, 0x8, 0x1, 0x6,
    0xd, 0xa, 0x3, 0x4, 0x8, 0xf, 0x6, 0x1, 0x7, 0x0, 0x9, 0xe, 0x2, 0x5, 0xc, 0xb,
    0x3, 0x4, 0xd, 0xa, 0x6, 0x1, 0x8, 0xf, 0x9, 0xe, 0x7, 0x0, 0xc, 0xb, 0x2, 0x5,
    0xe, 0x9, 0x0, 0x7, 0xb, 0xc, 0x5, 0x2, 0x4, 0x3, 0xa, 0xd, 0x1, 0x6, 0xf, 0x8,
    0x6, 0x1, 0x8, 0xf, 0x3, 0x4, 0xd, 0xa, 0xc, 0xb, 0x2, 0x5, 0x9, 0xe, 0x7, 0x0,
    0xb, 0xc, 0x5, 0x2, 0xe, 0x9, 0x0, 0x7, 0x1, 0x6, 0xf, 0x8, 0x4, 0x3, 0xa, 0xd,
    0x5, 0x2, 0xb, 0xc, 0x0, 0x7, 0xe, 0x9, 0xf, 0x8, 0x1, 0x6, 0xa, 0xd, 0x4, 0x3,
    0x8, 0xf, 0x6, 0x1, 0xd, 0xa, 0x3, 0x4, 0x2, 0x5, 0xc, 0xb, 0x7, 0x0, 0x9, 0xe,
    0xc, 0xb, 0x2, 0x5, 0x9, 0xe, 0x7, 0x0, 0x6, 0x1, 0x8, 0xf, 0x3, 0x4, 0xd, 0xa,
    0x1, 0x6, 0xf, 0x8, 0x4, 0x3, 0xa, 0xd, 0xb, 0xc, 0x5, 0x2, 0xe, 0x9, 0x0, 0x7,
    0xf, 0x8, 0x1, 0x6, 0xa, 0xd, 0x4, 0x3, 0x5, 0x2, 0xb, 0xc, 0x0, 0x7, 0xe, 0x9,
    0x2, 0x5, 0xc, 0xb, 0x7, 0x0, 0x9, 0xe, 0x8, 0xf, 0x6, 0x1, 0xd, 0xa, 0x3, 0x4,
    0xa, 0xd, 0x4, 0x3, 0xf, 0x8, 0x1, 0x6, 0x0, 0x7, 0xe, 0x9, 0x5, 0x2, 0xb, 0xc,
    0x7, 0x0, 0x9, 0xe, 0x2, 0x5, 0xc, 0xb, 0xd, 0xa, 0x3, 0x4, 0x8, 0xf, 0x6, 0x1,
    0x9, 0xe, 0x7, 0x0, 0xc, 0xb, 0x2, 0x5, 0x3, 0x4, 0xd, 0xa, 0x6, 0x1, 0x8, 0xf,
    0x4, 0x3, 0xa, 0xd, 0x1, 0x6, 0xf, 0x8, 0xe, 0x9, 0x0, 0x7, 0xb, 0xc, 0x5, 0x2};

unsigned crc4g_704_byte(unsigned crc, void const *mem, size_t len) {
    unsigned char const *data = mem;
    if (data == NULL)
        return 0;
    crc &= 0xf;
    while (len--)
        crc = table_byte[crc ^ *data++];
    return crc;
}

此代码和表格是由生成的我的代码 https://github.com/madler/crcany。这些函数使用以下方式推进 CRClen字节位于data。当使用以下命令调用时,将返回初始 CRC(即零字节的 CRC)data等于NULL。 CRC 位于返回值的最低有效位中。

这两个 CRC 定义在格雷格·库克的目录 http://reveng.sourceforge.net/crc-catalogue/1-15.htm#crc.cat-bits.4,其中两个 4 位 CRC 定义为:

width=4 poly=0x3 init=0xf refin=false refout=false xorout=0xf check=0xb residue=0x2 name="CRC-4/INTERLAKEN"
width=4 poly=0x3 init=0x0 refin=true refout=true xorout=0x0 check=0x7 residue=0x0 name="CRC-4/G-704"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CRC4 在 C 中的实现 的相关文章

  • 具有子列表属性映射问题的自动映射器

    我有以下型号 Models public class Dish Required public Int64 ID get set Required public string Name get set Required public str
  • 以编程方式检查页面是否需要基于 web.config 设置进行身份验证

    我想知道是否有一种方法可以检查页面是否需要基于 web config 设置进行身份验证 基本上如果有这样的节点
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • 实例化 Microsoft.Office.Interop.Excel.Application 对象时出现错误:800700c1

    实例化 Microsoft Office Interop Excel Application 以从 winforms 应用程序生成 Excel 时 出现以下错误 这之前是有效的 但突然间它停止工作了 尽管代码和 Excel 版本没有变化 我

随机推荐

  • 使用模板将一组成员函数声明为友元

    给出以下代码 class A struct B static void doIt A pa struct C static void doIt A pa class A int i 9 below works but requires a
  • 通过执行批处理文件/powershell脚本设置播放设备

    我已将计算机 Windows 7 连接到电视 并且经常在数字音频 S PDIF 高清音频设备 和耳机 2 Corsair CA HS1 USB 之间更改声音输出设备耳机 我希望能够执行一个为我更改此设置的批处理 脚本文件 这样我就不必 右键
  • 转换 .wav 文件中的 RTP 序列有效负载

    我有一个文本文件 其中包含 VoIP 对话的 RTP 数据包的有效负载 十六进制 有谁知道如何将文本转换为文件 使用 c c 的 wav 音频 PS 我使用的是 GNU Linux Thanks 我用 Java 做了同样的事情 这是我用于测
  • 设置 d3.curveBundle.beta 似乎没有效果

    d3 文档d3 curveBundle https github com d3 d3 shape blob master README md curveBundle提供了如何设置的示例beta https github com d3 d3
  • 在 Android 上从图像序列创建视频

    我想通过以下代码从图像序列 在 Android 上 创建视频 opencv core IplImage image cvLoadImage sdcard mytest testimage jpg FFmpegFrameRecorder re
  • 我可以在 rsync 调用中包含密码吗?

    我使用 rsync 来更新我的静态网站 我现在cd到本地网站目录 然后运行rsync命令 然后在下一行输入密码 我已经保存了我的rsync调用文本片段 这样 rs只是扩展到我的电话 有没有办法使用类似的东西 p在末尾标记并包含密码 我的电话
  • ActionBarCompat 下拉菜单上的单选按钮样式

    我正在开发一个使用扩展主题的应用程序 style Theme AppCompat Light DarkActionBar 在我的一项活动中 有一个操作栏图标 显示三个带有单选按钮的选项 以下是菜单 XML 文件的摘录
  • HTTP 标头样式表

    根据这个 http www w3 org TR html4 present styles html h 14 6 http www w3 org TR html4 present styles html h 14 6我可以直接在 http
  • Java ArrayList 中 contains 的使用

    如果我有一个 String 的 ArrayList 构成 Java 中类的一部分 如下所示 private ArrayList
  • Django REST如何设置节流周期以允许10分钟内一个请求?

    文件说该期间应该是以下之一 s sec m min h hour d day 我很好奇是否可以将时间设置为类似的内容1 10min 看着code https github com encode django rest framework b
  • Go 中的 strings.Split

    文件names txt由许多名称组成 其形式如下 KELLEE JOSLYN JASON INGER INDIRA GLINDA GLENNIS 有谁知道如何拆分字符串 使其成为用逗号分隔的单个名称 KELLEE JOSLYN JASON
  • 在编译时获取表达式类型

    编程时使用auto有时 了解编译器在编译时使用的类型会很方便 如果编译在我需要知道类型的地方中止 那并不重要 简单的例子 std vector lt int gt s 1 2 3 for auto elem s elem 5 for aut
  • 重构代码(如果是 else )

    我试图重构代码 发现了这段代码 您能否建议其中的任何重构 并请说出您使用的折射 private void setUpBag String language if language equals english add letters wit
  • 使用 dplyr 创建一个具有滞后值作为数值向量的数据框

    我的数据如下 data lt data frame A c 10 20 30 40 50 60 70 80 90 100 B c 110 120 130 140 150 160 170 180 190 200 我希望创建一个新列 按行从 A
  • 无法将 double [] [] 转换为 double **

    我有一个需要 3 个参数的函数 第一个是 double normalizeDataZeroMeanUnitSD double trainingActions int numberOfTrainingActions int descripto
  • 临时材料的保存期限有什么要求?

    考虑以下代码 class Test public Test memset buffer 0 sizeof buffer void Process printf buffer private char buffer 1000 int main
  • gensim 保存加载模型弃用警告

    保存 加载 gensim 词嵌入时 我收到以下弃用警告 model save mymodel model home lib python3 7 site packages smart open smart open lib py 398 U
  • 如何在 android M 上请求访问图库的权限?

    我有这个应用程序 它将选择图像到图库并使用 Imageview 将其显示给测试 我的问题是它在 Android M 上不起作用 我可以选择图像 但不会在我的测试中显示 他们说我需要请求许可才能访问 Android M 上的图像 但不知道如何
  • 使用Tomcat启动Spring Boot时的用户名和密码是什么?

    当我通过 Spring Boot 部署 Spring 应用程序并访问localhost 8080我必须进行身份验证 但是用户名和密码是什么或者如何设置 我尝试将其添加到我的tomcat users文件但它不起作用
  • CRC4 在 C 中的实现

    我修改了发现的实现here https stackoverflow com questions 28656471 how to confgure calculation of crc table 为 CRC4 构建表生成函数 如下所示 de