كيفية تحديد موقع سلسلة من القيم (على وجه التحديد ، بايت) ضمن مجموعة أكبر في .NET

StackOverflow https://stackoverflow.com/questions/2345304

  •  23-09-2019
  •  | 
  •  

سؤال

أحتاج إلى تحليل البايتات من ملف حتى لا أتناول البيانات إلا بعد تحديد تسلسل معين من البايتات. على سبيل المثال ، إذا كان التسلسل ببساطة 0xFF (بايت واحد) ، فيمكنني استخدام LINQ على المجموعة:

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

ولكن هل هناك طريقة أنيقة لاكتشاف تسلسل متعدد البايت - على سبيل المثال 0xFF ، 0xFF - خاصة الطريقة التي تتراجع في حال بدأت في الحصول على تطابق إيجابي خاطئ؟

هل كانت مفيدة؟

المحلول

لست على علم بأي طريقة مدمجة ؛ حسب المعتاد ، يمكنك دائمًا كتابة طريقة التمديد الخاصة بك. إليك واحدة من أعلى رأسي (قد تكون هناك طرق أكثر كفاءة لتنفيذها):

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;
        }
    }
}

سأضطر إلى التحقق للتأكد من أن هذا صحيح ، ولكن يجب أن يعطيك الفكرة الأساسية ؛ تكرار من خلال العناصر ، وتتبع التسلسل الأخير من القيم التي تم استردادها ، وضبط العلم عند العثور على التسلسل ، وبمجرد ضبط العلم ، ابدأ في إرجاع كل عنصر لاحق.

تحرير - قمت بإجراء اختبار ، وهو يعمل بشكل صحيح. إليك بعض رمز الاختبار:

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();
}

نصائح أخرى

إذا قمت بتحويل بايتك إلى سلسلة ، فيمكنك الاستفادة من عدد لا يحصى من وظائف البحث المضمنة في ذلك ، حتى لو كانت البايتات التي تعمل معها ليست أحرفًا بالمعنى التقليدي.

تماما كما قليلا من النظرية. هذه مشكلة لغة منتظمة. قد تكون قادرًا على استخدام محرك تعبير منتظم للكشف عنه. تم العثور على أول ضربة في Google لـ "تعبير منتظم على الدفق"

http://codeguru.earthweb.com/columns/experts/article.php/c14689

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top