2012-01-05 29 views
4

如何在流中搜索十六進制高效且快速?
如果流很大,如何在流中快速搜索並重新定位?如何在流中搜索十六進制?

function FindInMemStream(Stream: TMemoryStream; What: String):Integer; 
var 
    bufBuffer, bufBuffer2: array[0..254] of Char; 
    i: Integer; 
begin 
    Result := 0; 
    i := 0; 
    FillChar(bufBuffer, 255, #0); 
    FillChar(bufBuffer2, 255, #0); 
    StrPCopy(@bufBuffer2, What); 
    Stream.Position:=0; 
    while Stream.Position <> Stream.Size do 
    begin 
    Stream.Read(bufBuffer[0],Length(What)); 
    if CompareMem(@bufBuffer,@bufBuffer2,Length(What)) then 
    begin 
     Result := Stream.Position-Length(What); 
     Exit; 
    end; 
    i := i + 1; 
    Stream.Seek(i,0) 
    end; 
end; 

我想將函數更改爲serch hex,這個函數是否有效?你能給我一個有效的功能來切割十六進制嗎?

+3

你應該重新格式化您的代碼,這是非常很難閱讀。 – 2012-01-05 11:08:58

+2

如果未格式化,則效率不高。 – m0skit0 2012-01-05 11:09:48

+6

你不是在尋找一個十六進制,你正在搜索一個字符串,也許你可以從看Boyer-Moore搜索算法中受益。它允許你跳過搜索的文本,而這個算法前進字符。 – 2012-01-05 11:13:46

回答

2

我已經適應了在system.pas提供POS功能的代碼:) 如果你需要找一些十六進制,你可以像使用:

PosHex(#$15#$AA#$04, MyStream); 
function PosHex(const SubStr: AnsiString; const StrStream: TMemoryStream): Integer; 
var 
    SubLen, SrcLen, Len, I, J: Integer; 

    C1: AnsiChar; 
    Str: PAnsiChar; 
begin 
    SrcLen := StrStream.Size; 
    SubLen := Length(SubStr); 

    Result := 0; 
    if (SubLen <= 0) or (SrcLen <= 0) or (SrcLen < SubLen) then Exit; 

    StrStream.Position := 0; 
    Str := StrStream.Memory; 

    Len := SrcLen - SubLen + 1; 
    C1 := SubStr[1]; 
    for I := 1 to Len do 
    begin 
    if Str[I] = C1 then 
    begin 
     Result := I; 
     for J := 1 to SubLen-1 do 
     begin 
     if Str[I+J] <> SubStr[1+J] then 
     begin 
      Result := 0; 
      break; 
     end; 
     end; 
     if Result <> 0 then Exit; 
    end; 
    end; 
end; 


Usage: 
procedure TForm3.FormCreate(Sender: TObject); 
Var 
    M: TMemoryStream; 
    S: AnsiString; 
begin 
S := 'I would like to Find This string!'; 

M := TMemoryStream.Create; 
M.WriteBuffer(S[1], Length(S)); 

Memo1.Lines.Add(IntToStr(PosHex('Find This', M))); 

M.Free; 
end; 
+0

(+1)建議一個類似於標準或「常用」庫的函數。如後所述,它可以被優化,但是,它仍然是一個好主意;-) – umlcat 2012-01-05 15:34:35