在C语言中匹配二进制模式

8

我目前正在开发一款需要解析特定数据结构的C程序,幸运的是我知道这些结构的组成方式,但我不确定如何在C中实现我的解析器。

每个数据结构长度为32位,并且可以通过其二进制标识进行识别。

例如,我关心的有两种特定的结构,它们具有以下二进制模式(x表示0或1):

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

在这些结构中,“x”位包含我所需的实际数据,因此基本上我需要一种根据每个结构中写入的位来识别每个结构的方法。
因此,以伪代码为例:
if (binaryPattern = 000010xxxxxxxxx0) {
do something with it;
}

我猜测将它们作为整数读取,然后执行某种位掩码操作可能是正确的方式,但我对C语言的了解不是很多,也许一个简单的逻辑或操作就能做到,但在开始之前我只是想听听建议。
谢谢。
非常感谢所有回答的人,非常有帮助!

这两种模式之外还有其他的吗? - Daniel Fischer
有的,总共有13个。 - Tony
好的,那么简单的 if (binaryPattern < 0x0800) 这样的语句行不通。所以需要进行位掩码操作。你需要帮忙吗? - Daniel Fischer
4个回答

7

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

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

  1. 使用1111 1100 1100 0001(掩码)AND输入数据
  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)
        --------------------                        --------------------

每个规则都可以通过掩码模板对来表示,你只需要一个函数/操作来将上述操作应用于你的数据以检查是否匹配。


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
}

如果您有更多的模式,最好将模式和掩码放在一个表格中,并循环处理它。

2
你需要的是二进制与(&)。
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
}

等等,等等


那个算法只能检测到模式中的1,无法检测到0。你需要为此使用单独的掩码和模板。 - Kalle Pokki

1

我认为你可以使用位掩码,将1放在指定位的位置,0表示该位不重要。
例如:

000000xxxxxxxxx0    000010xx10xxxxx0
1111110000000001    1111110011000001

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

if( (value&0b1111110011000001)== 0b0000100010000000){
     //pattern found
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接