8

私は現在、いくつかの特注のデータ構造を解析する必要がある C プログラムを開発しています。幸いなことに、それらがどのように構造化されているかは知っていますが、C でパーサーを実装する方法がわかりません。

各構造体の長さは 32 ビットで、各構造体はそのバイナリ署名によって識別できます。

例として、私が興味を持っている 2 つの特定の構造があり、それらには次のバイナリ パターンがあります (x は 0 または 1 を意味します)。

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

これらの構造内の「x」ビットには、必要な実際のデータが含まれているため、基本的に、各構造内でのビットの書き込み方法に基づいて各構造を識別する方法が必要です。

したがって、疑似コードの例として:

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

それらを int として読み取ってから、ある種のビットマスキングを実行するのがよい方法だと推測していますが、私の C の知識はあまり高くなく、単純な論理 OR 演算でそれができるかもしれません。始める前にこれを行うためのアドバイス。

ありがとう

回答してくださった皆様、大変助かりました!!

4

4 に答える 4

7

データが特定のバイナリ パターンと一致するかどうかを確認するには、まず署名以外のビットをマスクしてから、署名テンプレートと比較します。

たとえば、データが 0000 10xx 10xx xxx0 署名と一致するかどうかを確認するには:

  1. AND 入力データと 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

ところで、32ビットではなく、16ビットパターンのみを示しました...

とにかく、パターンのどの部分に関心があるかを表すマスクを定義するだけです。値とマスクでビットごとの AND を実行し、結果がテスト パターンである場合は、必要なものが見つかりました。

#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 をゼロにするだけです)。
2 番目のパターンの例は次のようになります。

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