2009-10-02 60 views
31

Tôi có một chuỗi các byte mà tôi phải tìm kiếm trong một tập hợp các tệp nhị phân bằng cách sử dụng Java.Tìm kiếm một chuỗi các byte trong một Tệp nhị phân với Java

Ví dụ: Tôi đang tìm chuỗi byte DEADBEEF (trong hex) trong tệp nhị phân. Làm cách nào để tôi thực hiện điều này trong Java? Có phương pháp tích hợp nào, chẳng hạn như String.contains() cho các tệp nhị phân không?

Trả lời

47

Không, không có phương pháp tích hợp để thực hiện điều đó. Nhưng, sao chép trực tiếp từ HERE (với hai bản vá áp dụng cho mã cũ):

/** 
* 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

Tôi yêu StackOverflow. Cảm ơn! – Teekin

+0

Tối ưu hóa rất ít: bạn không cần phải tính toán chức năng thất bại của mẫu nếu data.length là zero ==> bạn có thể di chuyển dữ liệu.length zero kiểm tra đến dòng đầu tiên của hàm. – 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

Sẽ không hoạt động trên chuỗi cuối cùng của chuỗi. –

+1

'

+0

Nơi nào để giới hạn 1024 byte cho mẫu được tuyên bố bởi thành viên MAX_PATTERN_LENGTH chưa sử dụng? – user1767316

3

Bạn có thể tìm chuỗi các byte từ giga-byte tập tin để sử dụng bigdoc.

Lib và Ví dụ ở đây trên Github tại địa chỉ: 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); 
    } 
} 

Nếu bạn muốn tìm kiếm nó trên bộ nhớ, kiểm tra điều này. Ví dụ ở đây trên Github tại địa chỉ: 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); 
    } 
} 

Returns tất cả các vị trí phù hợp trong mảng byte

Nó cũng có thể chịu được một mảng lớn các byte :)

Các vấn đề liên quan