C # Как извлечь несколько меньших байтов [] из 1 большего байта []?

Этот вопрос связан с: C# Как извлечь байты из массива байтов? С известным начальным байтом

У меня есть «100 байт байт []», который состоит из нескольких «14 байт байт []», которые случайным образом встречаются в большем байте.

Мой меньший байт [] начинается с (байта) 0x55 и заканчивается на 16 байтов позже

Я использую код:

        byte[] results = new byte[16];
        int index = Array.IndexOf(readBuffer, (byte)0x55, 2);
        Array.Copy(readBuffer, index, results, 0, 16);

Но при этом я получаю только первое вхождение моего меньшего байта [].

Как получить ВСЕ меньшие блоки byte[]?

PS: я работаю с .Net Micro Framework


person Jónatas Brás    schedule 18.02.2015    source источник
comment
Как насчет цикла for, который будет перебирать исходный массив? Что вы должны делать с результирующими подмассивами?   -  person Groo    schedule 18.02.2015
comment
Вам просто нужно обернуть весь этот код в цикл   -  person Sriram Sakthivel    schedule 18.02.2015
comment
Если ваш меньший массив имеет только 14 элементов, как он может закончиться на 16 байт позже? Как числа, кратные 14, 15 или 16 байтам, могут поместиться в 100 байт? Ваш вопрос трудно понять. О, я пропустил случайную часть. Ваша идея состоит в том, что 0x55 всегда запускает последовательность из 15 байтов, включая саму себя?   -  person Peter - Reinstate Monica    schedule 18.02.2015
comment
которые появляются в старшем байте случайным образом Подождите секунду. Что значит случайно? Разве они не расположены последовательно? Что, если последовательность байтов содержит значение 0x55 в середине? Я предполагаю, что это 0x55 + 14 байт + байт контрольной суммы?   -  person Groo    schedule 18.02.2015
comment
@PeterSchneider, да, ox55 всегда запускает последовательность из 16 байтов, включая себя. забудьте 14, это была ошибка. :)   -  person Jónatas Brás    schedule 18.02.2015
comment
@Groo, 0x55 всегда находится в начале последовательности. Забудьте о 14, это была ошибка, это 16, включая 0x55. случайно означает, что 0x55 может появиться в любом месте исходного массива байтов, за которым всегда следует еще 15. Контрольная сумма также включена. по порядку: 0x55 + 1 синхбайт + 2 контрольных суммы + 12 байт данных.   -  person Jónatas Brás    schedule 18.02.2015
comment
@Jónatas: Хорошо, тогда алгоритм аналогичен приведенному ниже, просто смещения немного отличаются от того, что я предполагал.   -  person Groo    schedule 18.02.2015
comment
@Гру. спасибо, я постараюсь и дам вам знать. Кстати, почему люди минусуют мой вопрос? Это так глупо? или так плохо написано?   -  person Jónatas Brás    schedule 18.02.2015
comment
@JónatasBrás: Что ж, вопросы, которые, кажется, требуют кода, считаются не по теме SO, и вы также должны приложить некоторые усилия для решения (например, опубликовать код, который вы пробовали, но не работали). Это также довольно похоже на ваш предыдущий вопрос, и вы не указали свои точные требования (например, контрольную сумму, фактический протокол и т. д.).   -  person Groo    schedule 18.02.2015
comment
@Гру Хорошо. благодарю вас. Я новичок в SO и у меня нет большого опыта в программировании. Я думал, что хорошо поступаю, отделяя этот вопрос от предыдущего. Я пробовал кое-что, но, как я уже сказал, я ограничен не только потому, что я не программист, но и потому, что я использую микрофреймворк .Net, и некоторые вещи, с которыми я привык работать (списки, например), не недоступен.   -  person Jónatas Brás    schedule 18.02.2015
comment
Я проголосовал против, потому что вопрос был плохо написан (я мог только догадываться, что вы хотели) и потому, что любое вероятное значение было тривиальным, то есть неинтересным. Алгоритм (перебор данных до тех пор, пока вы не нажмете 0x55, соберите данные, включите цикл), а также необходимые языковые функции (цикл, ради всего святого) были очевидны. Понижающее голосование было предназначено - извините за прямоту - чтобы другие не тратили здесь свое время. Я думаю, вы смогли бы найти решение для себя, если бы действительно попытались. Я надеюсь.   -  person Peter - Reinstate Monica    schedule 18.02.2015
comment
Спасибо за твою честность. :) действительно ценю это. Я надеюсь, что буду становиться все лучше и лучше в программировании. Я техник по мехатронике, и впервые мне пришлось что-то программировать (на другом языке, кроме Ladder) полторы недели назад. А вот такие мелочи для меня пока большой вопрос, понятия не имел как это сделать.   -  person Jónatas Brás    schedule 18.02.2015
comment
@Jónatas: Надеюсь, у вас было время попробовать это реализовать. Поскольку вы только начинаете программировать, я добавил пример того, как вы можете написать это, чтобы вы могли сравнить с вашей попыткой, поэтому попробуйте выполнить код с помощью отладчика и посмотреть, что происходит.   -  person Groo    schedule 18.02.2015


Ответы (1)


Я предполагаю, что ваше сообщение состоит из начального байта файла cookie 0x55, 14 байтов фактических данных и 1 байта контрольной суммы (поскольку вы использовали 14 и 16 байтов взаимозаменяемо). Единственный способ для того, чтобы случайные подмассивы имели смысл, - это иметь значение контрольной суммы в конце, чтобы подтвердить, что ваш начальный байт действительно является действительным файлом cookie (а не байтом данных).

(отредактировано после вашего обновления)

Итак, ваши фактические данные 0x55 + 1syncbyte + 2 checksum + 12 databytes, а это означает, что ваша функция должна:

Начните с индекса i = 0 и повторите пока i + 15 ‹ длина ввода:

  1. Check the cookie at index i.
    • If cookie is not 0x55, increment i and start again.
  2. Check the byte at index i + 1.
    • If incorrect sync byte, increment i and start again.
  3. Read the 16-bit checksum at i + 2/i + 3, calculate actual data checksum and compare.
    • If checksum doesn't match, increment i and start again.
  4. Copy bytes i + 4 to i + 15 into a segment of size 12.
    • Either yield return this result or process it right away.
  5. Увеличьте i на 16, чтобы пропустить обработанный блок и начать заново.

Вы можете перейти к первому вхождению 0x55, используя Array.IndexOf, но, поскольку вам все равно нужно отслеживать индекс, вы можете просто выполнить проверку самостоятельно и упростить код (алгоритмическая сложность та же O(n)).

Один из способов закодировать это будет примерно так:

private static IEnumerable<byte[]> EnumerateSegments(byte[] input)
{
    var i = 0;
    while (i + 15 < input.Length)
    {
        // check if it starts with 'sync' bytes
        // (not sure which is the second one, though?)
        var cookie = input[i];
        if (input[i] != 0x55 || input[i + 1] != 0xAA)
        {
            i++;
            continue;
        }

        // get the 16-bit checksum
        // (check if this is the correct endian, i.e. you
        // might need to swap bytes)
        var receivedChecksum = (input[i + 2] << 8) | (input[i + 3]);

        // calculate the checksum over data only
        var calculatedChecksum = CalculateChecksum(input, i + 4, 12);
        if (receivedChecksum != calculatedChecksum)
        {
            i++;
            continue;
        }

        // if we're here, data should be valid, so the last
        // thing left to do is to copy the data into the subarray
        var segment = new byte[12];
        Array.Copy(input, i + 4, segment, 0, 12);
        yield return segment;

        // skip this segment
        i += 16;
    }
}

И вы могли бы использовать его в цикле foreach для перебора сегментов:

foreach (var segment in EnumerateSegments(input)) 
{
    ProcessSegment(segment);
}

Или вы можете получить список сегментов, если хотите перебирать элементы несколько раз:

List<byte[]> listOfSegments = EnumerateSegments(input).ToList();

Поскольку вы новичок в C# (и вообще в программировании), я предлагаю вам поставить точку останова внутри метода и шаг за шагом понять, что происходит.

person Groo    schedule 18.02.2015
comment
Спасибо. Перед вашим примером я начал пытаться реализовать его и пришел к решению, близкому к вашему. Но потом я увидел вашу и был заинтригован этой строкой: var ReceiveChecksum = (input[i + 2] ‹‹ 8) | (ввод [я + 3]); Я не знал, почему там было или . Но потом я нашел побитовые операторы. Спасибо за это. Я все еще работаю над реализацией этого и некоторых других вещей, когда я закончу, я дам вам знать. Еще раз спасибо - person Jónatas Brás; 18.02.2015