2009-10-02 14 views
31

Javaを使用してバイナリファイルのセットを検索する必要があるバイトシーケンスがあります。Javaでバイナリファイル内のバイト列を検索する

例:バイナリファイルでバイトシーケンスDEADBEEF(16進数)を検索しています。 Javaでこれをどうやってやりますか?バイナリファイルのためのString.contains()のような組み込みメソッドはありますか?

答えて

47

いいえ、それを行う組み込みの方法はありません。しかし、直接HEREからコピー(元のコードに適用された2回の修正で):ライブラリを好む人のため

/** 
* Knuth-Morris-Pratt Algorithm for Pattern Matching 
*/ 
class KMPMatch { 
    /** 
    * Finds the first occurrence of the pattern in the text. 
    */ 
    public int indexOf(byte[] data, byte[] pattern) { 
     int[] failure = computeFailure(pattern); 

     int j = 0; 
     if (data.length == 0) return -1; 

     for (int i = 0; i < data.length; i++) { 
      while (j > 0 && pattern[j] != data[i]) { 
       j = failure[j - 1]; 
      } 
      if (pattern[j] == data[i]) { j++; } 
      if (j == pattern.length) { 
       return i - pattern.length + 1; 
      } 
     } 
     return -1; 
    } 

    /** 
    * Computes the failure function using a boot-strapping process, 
    * where the pattern is matched against itself. 
    */ 
    private int[] computeFailure(byte[] pattern) { 
     int[] failure = new int[pattern.length]; 

     int j = 0; 
     for (int i = 1; i < pattern.length; i++) { 
      while (j > 0 && pattern[j] != pattern[i]) { 
       j = failure[j - 1]; 
      } 
      if (pattern[j] == pattern[i]) { 
       j++; 
      } 
      failure[i] = j; 
     } 

     return failure; 
    } 
} 
+3

私はStackOverflowのが大好きバイト:)の大きな配列を耐えることができます。ありがとう! – Teekin

+0

はほとんどの最適化:data.lengthがゼロの場合は、==>あなたが関数の最初の行にdata.lengthゼロチェックを移動することができ、パターンの故障関数を計算する必要はありません。 – dexametason

4
private int bytesIndexOf(byte[] source, byte[] search, int fromIndex) { 
    boolean find = false; 
    int i; 
    for (i = fromIndex; i < (source.length - search.length); i++) { 
     if (source[i] == search[0]) { 
      find = true; 
      for (int j = 0; j < search.length; j++) { 
       if (source[i + j] != search[j]) { 
        find = false; 
       } 
      } 
     } 
     if (find) { 
      break; 
     } 
    } 
    if (!find) { 
     return -1; 
    } 
    return i; 
} 
+0

文字列の最後のバイトでは機能しません。 –

+1

'

+0

未使用のMAX_PATTERN_LENGTHメンバーが示すように、パターンの1024バイトの制限に対応する場所はありますか? – user1767316

3

あなたは、Githubの上のライブラリを見つけることができます。

ここのGithub上でlibと例:https://github.com/riversun/bigdoc

package org.example; 

import java.io.File; 
import java.util.List; 

import org.riversun.bigdoc.bin.BigFileSearcher; 

public class Example { 

    public static void main(String[] args) throws Exception { 

     byte[] searchBytes = "hello world.".getBytes("UTF-8"); 

     File file = new File("/var/tmp/yourBigfile.bin"); 

     BigFileSearcher searcher = new BigFileSearcher(); 

     List<Long> findList = searcher.searchBigFile(file, searchBytes); 

     System.out.println("positions = " + findList); 
    } 
} 

あなたはメモリ上でそれを検索したい場合は、これを確認してください。ここのGithub上で 例:https://github.com/riversun/finbin

import java.util.List; 

import org.riversun.finbin.BigBinarySearcher; 

public class Example { 

    public static void main(String[] args) throws Exception { 

     BigBinarySearcher bbs = new BigBinarySearcher(); 

     byte[] iamBigSrcBytes = "Hello world.It's a small world.".getBytes("utf-8"); 

     byte[] searchBytes = "world".getBytes("utf-8"); 

     List<Integer> indexList = bbs.searchBytes(iamBigSrcBytes, searchBytes); 

     System.out.println("indexList=" + indexList); 
    } 
} 

返しバイト

のアレイ内のすべての一致した位置には、それはまた

関連する問題