簡體   English   中英

在 C 中搜索二進制模式(讀取緩沖的二進制文件)

[英]Search for Binary Pattern in C (Read buffered binary file)

嘿。 我正在嘗試編寫一個小程序,該程序將在最后一次出現“0xFF 0xC0 0x00 0x11”后讀取以下四個字節,該程序可以輕松轉換為二進制或十進制。 目的是最后一次出現該十六進制模式后的 2-5 個字節表示 JPEG 文件的寬度和高度。

#include <stdio.h>

 int main () {
  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;

  pFile = fopen ( "pano8sample.jpg" , "rb" );
  if(pFile==NULL){
   fputs ("File error",stderr);
   exit (1);
  }

  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  printf("\n\nFile is %d bytes big\n\n", lSize);

  buffer = (char*) malloc (sizeof(char)*lSize);
  if(buffer == NULL){
   fputs("Memory error",stderr);
   exit (2);
  }

  result = fread (buffer,1,lSize,pFile);
  if(result != lSize){
   fputs("Reading error",stderr);
   exit (3);
  }

  //0xFF 0xC0 0x00 0x11 (0x08)

  //Logic to check for hex/binary/dec

  fclose (pFile);
  free (buffer);
  return 0;
 }

問題是我不知道如何遞歸地從緩沖內存中讀取並使用最近讀取的變量作為 int 與我的二進制/十六進制/十進制進行比較。

我該怎么做呢?

byte needle[4] = {0xff, 0xc0, 0x00, 0x11};
byte *last_needle = NULL;
while (true) {
  byte *p = memmem(buffer, lSize, needle, 4); 
  if (!p) break;
  last_needle = p;
  lSize -= (p + 4) - buffer;
  buffer = p + 4;
}

如果last_needle不為空,則可以打印出last_needle+4 ...

我會使用一些狀態機,而不是將整個文件讀入內存。 我的 C 有點生疏,但是:

char searchChars[] = {0xFF,0xC0,0x00,0x11};
char lastBytes[5];
int pos = 0; int curSearch = 0;
while(pos <= lSize) {
    curChar = getc(pfile); pos++;            /*readone char*/

    if(curChar == searchChars[curSearch]) { /* found a match */
        curSearch++;                        /* search for next char */
        if(curSearch > 3) {                 /* found the whole string! */
            curSearch = 0;                  /* start searching again */
            read = fread(lastBytes,1,5,pfile); /* read 5 bytes */
            pos += read;                      /* advance position by how much we read */
        }
    } else { /* didn't find a match */
        curSearch = 0;                     /* go back to searching for first char */
    }
 }

最后,您在 lastBytes 中剩下 5 個字節,這是您上次找到 searchChars 之后的五個字節

就個人而言,我會使用一次吞下一個字符的函數。 該函數將使用有限狀態機進行簡單的正則表達式匹配,將細節保存在靜態局部變量或參數塊結構中。 您需要兩個子塊 - 一個用於部分匹配狀態,一個用於最后一次完整匹配 - 每個都根據需要指示相關位置或值。

在這種情況下,您應該能夠手動設計它。 對於更復雜的需求,請查看Ragel

如果數據以 ascii 編碼,則可以在 C/C++ 中使用 fscanf 函數。 如果不是,您將必須編寫自己的函數來執行此操作。 簡單的方法是從文件中讀取 N 個字節,在字節字符串中搜索您想要的模式,然后繼續直到 EOF。

您的代碼實際上一次讀取整個文件(如果您要查找的行靠近文件頂部,則不需要。)您的代碼將文件作為字節數組存儲在堆上(char 相當於 C++ 中的一個字節) with buffer 指向內存中連續數組開頭的指針。 像操作任何其他數組一樣操作緩沖區數組。

此外,如果您打算在讀取大小后執行任何操作,請確保釋放 malloced 緩沖區對象以避免泄漏。

使用magic_open() 和magic_print() 更安全易用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM