2010-02-26 3 views
5

Ho bisogno di analizzare i byte da un file in modo tale che prendo solo i dati dopo che una determinata sequenza di byte è stata identificata. Ad esempio, se la sequenza è semplicemente 0xFF (un byte), allora posso utilizzare LINQ sulla raccolta:Come individuare una sequenza di valori (in particolare, byte) all'interno di una raccolta più grande in .NET

byte[] allBytes = new byte[] {0x00, 0xFF, 0x01}; 
var importantBytes = allBytes.SkipWhile(byte b => b != 0xFF); 
// importantBytes = {0xFF, 0x01} 

ma c'è un modo elegante per rilevare una sequenza multi-byte - esempio 0xFF, 0xFF - specialmente uno che esegue il backtrack nel caso in cui inizi a ottenere una corrispondenza falsamente positiva?

risposta

1

Non sono a conoscenza di alcun modo integrato; come al solito, puoi sempre scrivere il tuo metodo di estensione. Ecco uno al largo della parte superiore della mia testa (ci possono essere modi più efficaci per attuare it):

public static IEnumerable<T> AfterSequence<T>(this IEnumerable<T> source, 
    T[] sequence) 
{ 
    bool sequenceFound = false; 
    Queue<T> currentSequence = new Queue<T>(sequence.Length); 
    foreach (T item in source) 
    { 
     if (sequenceFound) 
     { 
      yield return item; 
     } 
     else 
     { 
      currentSequence.Enqueue(item); 

      if (currentSequence.Count < sequence.Length) 
       continue; 

      if (currentSequence.Count > sequence.Length) 
       currentSequence.Dequeue(); 

      if (currentSequence.SequenceEqual(sequence)) 
       sequenceFound = true; 
     } 
    } 
} 

dovrò controllare per assicurarsi che questo è corretto, ma dovrebbe dare l'idea di base; scorrere tra gli elementi, tracciare l'ultima sequenza di valori recuperati, impostare un flag quando viene trovata la sequenza e, una volta impostato il flag, iniziare a restituire ogni elemento successivo.

Modifica - Ho eseguito un test e funziona correttamente. Ecco qualche codice di prova:

static void Main(string[] args) 
{ 
    byte[] data = new byte[] 
    { 
     0x01, 0x02, 0x03, 0x04, 0x05, 
     0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA 
    }; 
    byte[] sequence = new byte[] { 0x02, 0x03, 0x04, 0x05 }; 
    foreach (byte b in data.AfterSequence(sequence)) 
    { 
     Console.WriteLine(b); 
    } 
    Console.ReadLine(); 
} 
1

Se si convertono i byte in una stringa, è possibile sfruttare la miriade di funzioni di ricerca incorporate in questo, anche se i byte con cui si sta lavorando non sono in realtà caratteri nel senso tradizionale.

+0

Non ti devi preoccuparti di ciò che .NET potrebbe supporre sulla codifica e tali che darebbe risultati errati? – thelsdj

+0

Credo che finché cercherete un'esatta sequenza di byte, la codifica non avrà davvero importanza (purché sia ​​la sorgente che la sequenza di ricerca siano nella stessa codifica). È possibile utilizzare la classe ASCIIEncoding per consentire la conversione avanti e indietro. – MikeP