8

我目前正在开发一个需要解析一些定制数据结构的 C 程序,幸运的是我知道它们的结构,但是我不确定如何在 C 中实现我的解析器。

每个结构的长度都是 32 位,每个结构都可以通过它的二进制签名来识别。

例如,有两个我感兴趣的特定结构,它们具有以下二进制模式(x 表示 0 或 1)

 0000-00xx-xxxx-xxx0
 0000-10xx-10xx-xxx0

在这些结构中,“x”位包含我需要的实际数据,因此基本上我需要一种基于位在每个结构中的写入方式来识别每个结构的方法。

以伪代码为例:

if (binaryPattern = 000010xxxxxxxxx0) {
do something with it;
}

我猜想将它们读取为整数,然后执行某种位掩码将是可行的方法,但我对 C 的了解不是很好,也许一个简单的逻辑 OR 操作就可以做到,但我只是想要一些在我开始之前这样做的建议。

谢谢

非常感谢所有回答的人,非常有帮助!!

4

4 回答 4

7

要检查您的数据是否与特定的二进制模式匹配,您可以首先屏蔽非签名位,然后将其与签名模板进行比较。

例如,要检查您的数据是否与 0000 10xx 10xx xxx0 签名匹配:

  1. 将您的输入数据与 1111 1100 1100 0001 (掩码)
  2. 检查输出是否等于 0000 1000 1000 0000 (模板)

用一些示例数据来说明:

DATA_1   0010 1011 1101 1100                DATA_2   0000 1011 1010 1100
  MASK   1111 1100 1100 0001  &               MASK   1111 1100 1100 0001  &
        --------------------                        --------------------
         0010 1000 1100 0000 (NO_MATCH)              0000 1000 1000 0000 (MATCH)
        --------------------                        --------------------

因此,您的每个规则都可以由一个掩码模板对表示,您所需要的只是一个函数/操作,它将上述操作应用于您的数据以检查它是否匹配。

于 2013-01-17T13:36:54.177 回答
3

顺便说一句,您只显示了 16 位模式,而不是 32 位...

无论如何,您可以只定义表示您感兴趣的模式部分的掩码。用你的值和掩码执行按位与,如果结果是测试模式,你已经找到了你想要的。

#define PATTERN1 0x0000
#define MASK1 0xfc01

#define PATTERN2 0x0880
#define MASK2 0xfcc1

if ((value & MASK1) == PATTERN1) {
  // have pattern 1
}
else if ((value & MASK2) == PATTERN2) {
  // have pattern 2
}

如果您有更多模式,显然最好将模式和掩码放在一个表格中并循环遍历它。

于 2013-01-17T13:37:36.893 回答
2

你需要的是一个二进制 AND (&)

if( (value & matchPattern) == matchPattern ) {
   // do something with it.
}

正如你所说的是 32 位,所以我假设你使用类似 uint32_t 的东西。如果是这种情况,您可能会遇到这样的情况:

uint32_t value = 0xF0F0ABCD;
//                            0xFOF0XXXD X = data
uint32_t const matchPattern = 0xF0F0000D;
if( (value & matchPattern) == matchPattern) {
     uint32_t use = value & 0x0000FFF0; // extracts the XXX part
}

等等

于 2013-01-17T13:38:59.413 回答
1

我认为您可以对它们进行位掩码,将 1 放在您有指定位的位置,当该位无关紧要时放置 0。
例子:

000000xxxxxxxxx0    000010xx10xxxxx0
1111110000000001    1111110011000001

然后将这个 secondo 模式与 & 按位运算一起使用,并将其与您需要的值进行比较(只需将 x 置零)。
第二种模式的示例应该是:

if( (value&0b1111110011000001)== 0b0000100010000000){
     //pattern found
}
于 2013-01-17T13:37:50.817 回答