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 中的实现 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当

随机推荐

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

    给出以下代码 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