5

特定のバイトシーケンスが識別された後にのみデータを取得するように、ファイルからバイトを解析する必要があります。たとえば、シーケンスが単純に0xFF(1バイト)の場合、コレクションでLINQを使用できます。

byte[] allBytes = new byte[] {0x00, 0xFF, 0x01};
var importantBytes = allBytes.SkipWhile(byte b => b != 0xFF);
// importantBytes = {0xFF, 0x01}

しかし、マルチバイトシーケンス(たとえば、0xFF、0xFF)を検出するための洗練された方法はありますか?特に、誤検知の一致が発生し始めた場合にバックトラックする方法はありますか?

4

3 に答える 3

1

バイトを文字列に変換すると、使用しているバイトが実際には従来の意味での文字でなくても、それに組み込まれている無数の検索関数を利用できます。

于 2010-02-26T22:38:35.337 に答える
1

組み込みの方法は知りません。いつものように、いつでも独自の拡張メソッドを作成できます。これが私の頭の上にあるものです(それを実装するためのより効率的な方法があるかもしれません):

public static IEnumerable<T> AfterSequence<T>(this IEnumerable<T> source,
    T[] sequence)
{
    bool sequenceFound = false;
    Queue<T> currentSequence = new Queue<T>(sequence.Length);
    foreach (T item in source)
    {
        if (sequenceFound)
        {
            yield return item;
        }
        else
        {
            currentSequence.Enqueue(item);

            if (currentSequence.Count < sequence.Length)
                continue;

            if (currentSequence.Count > sequence.Length)
                currentSequence.Dequeue();

            if (currentSequence.SequenceEqual(sequence))
                sequenceFound = true;
        }
    }
}

これが正しいことを確認する必要がありますが、基本的な考え方は理解できるはずです。要素を反復処理し、取得した値の最後のシーケンスを追跡し、シーケンスが見つかったときにフラグを設定し、フラグが設定されると、後続の各要素を返し始めます。

編集 - テストを実行しましたが、正しく動作します。ここにいくつかのテストコードがあります:

static void Main(string[] args)
{
    byte[] data = new byte[]
    {
        0x01, 0x02, 0x03, 0x04, 0x05,
        0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA
    };
    byte[] sequence = new byte[] { 0x02, 0x03, 0x04, 0x05 };
    foreach (byte b in data.AfterSequence(sequence))
    {
        Console.WriteLine(b);
    }
    Console.ReadLine();
}
于 2010-02-26T22:48:35.253 に答える
0

ちょっとした理論として。これは通常の言語の問題です。正規表現エンジンを使用して検出できる場合があります。「ストリームの正規表現」の最初の Google ヒットが見つかりました

http://codeguru.earthweb.com/columns/experts/article.php/c14689

于 2010-02-26T23:02:57.340 に答える