5

文字列内の文字列の検索は .NET で非常によくサポートされていますが、検索する必要があるデータが文字列ではない場合はどうすればよいでしょうか?

NetworkStream を介して通常のチャンクで到着するバイナリ データがあります。パケットはバイナリですが、すべてバイトのシグネチャ シーケンスで始まります。チャンクをより大きなバッファーに蓄積し、パケット開始の署名を探します。

私が本当に探しているのは、メソッドbyte[]と同等です。String.IndexOf(ss)ループとステートマシンを使ってこれを自分で実装しなければならなくなる気がします。

助言がありますか?あなたに!


示唆されているように、 Array.IndexOf(byte) は少なくとも明示的なループを節約します。投稿以来、最初の署名バイトを見つけて、最後の署名バイトがあるべき場所を先に調べて、両方が一致する場合は、文字列の残りの部分を力ずくで比較してみることにしました。このアプローチには、誤った一致を安価に拒否し、別のチャンクを保留している部分的な署名がある場合に安価に拒否できるという利点があります。

Googleは、上記の素晴らしい計画が「KMP」またはKnuth-Morris-Prattアルゴリズムの退化したケースであることを明らかにしています. 明るい面では、クヌースが彼の名前を付けた場合、それはおそらく油を塗った稲妻です.

ドナルド・クヌースにポイントを与えることはできないので、ネルソンに行くと思います。

4

3 に答える 3

3

Array.IndexOf を使用して、1 バイトを検索できます。

ただし、一部の有効なデータが誤って署名になり、アプリケーションが完全に無効になる可能性があることに注意してください。私の意見では、より良い解決策は、パケットのサイズを含む 4 バイトの整数を常に送信することです。次に、そのパケットのバッファをクリアするために、そのバイト数を読み込みます。

TCPを使用している場合、クライアントがパケットサイズについて嘘をついたり、ばかげた量のメモリを要求したりした場合、クライアントをキックオフすることは完全に許容されます:)

于 2008-10-10T05:50:58.630 に答える
2

私が使用したバイト配列と文字列内のパターンを見つけるための最速のアルゴリズムは、Boyer-Mooreと単純な Boyer-Moore です (パターンが検索対象のテキストと大きく異なる場合に役立ちます)。これを使用して、Java で高速な MIME パーサーを実装しました。コードは簡単に .Net に移植できます (ライセンスは LGPL です) 。

于 2008-10-10T09:09:48.557 に答える
0

アンマネージ/アンセーフ コードを使用できますか? もしそうなら、バイト配列を検索するためにポインター演算を使用することを検討することをお勧めします。それがストリングスの効果です。同様のことができます。

別の解決策は、辞書を使用してパケット データを保存することです。鍵をあなたの署名にしてください。それから、それを見つけるのはかなり速くて簡単です。base64string、simepl ラッパー (これを行う場合は KeyedCollection を使用) など、バイトをキーとして使用する方法はいくつかあります。

于 2008-10-10T06:35:32.723 に答える