Файл прочитан побайтово и переведён в массив. Элементов массива много, каждый элемент string, несколько сотен тысяч. Элементами массива являются числа от 00 до FF(шестнадцатиричная система исчисления). Т.е. вот что я имею на руках: $massiv = array("00", "20", "07", "AD", "60", "20", "FE", "12", "20" и т.д.); Задача: найти в массиве последовательность элементов массива, когда я не знаю значение этих элементов, но точно знаю что: какой-то один элемент(например "20" из примера выше) повторяется сначала через три других элемента("07", "AD", "60" из примера выше), а потом повторяется через 2 других элемента("FE", "12" из примера выше). Т.е. в идеале я буду функцией получать номер элемента массива, с которого начинается последовательность, которую я ищу. Уже два года мечтаю о таком скрипте))
Если это не массив а строка, то можно использовать регулярное выражение. Символ для подстановки в выражение можно получить из HEX с помощью функции chr: PHP: $char = chr(0x20);
Так если они должны повторяться по системе, то даже однопроходный алгоритм получается, элементарный. Идти по порядку по массиву, и смотреть PHP: if ($massiv[$i] == $massiv[$i +3] && $massiv[$i] == $massiv[$i + 5]) Что-то такое, если я на ночь глядя с цифрами не ошибся.
Всё здорово, получилось. Только каждое условие в отдельных скобках должно быть. И ещё и $i+4 && $i+7, т.к. текущая итерация
Незачем переводить байты в массив строк. В PHP есть прекрасная функция count_chars, которая за один вызов может посчитать сколько раз встретился каждый символ. Например вот такой код PHP: $source = "a\x12\xB0.L-dc.\xB0_h."; $counts = count_count($source); var_export($counts); выведет такой результат: Код (Text): array ( 18 => 1, 45 => 1, 46 => 3, 76 => 1, 95 => 1, 97 => 1, 99 => 1, 100 => 1, 104 => 1, 176 => 2, ) если надо найти с какой позиции начинаются эти серии байтов, то добавь strpos() PHP: <?php $source = "a\x12\xB0.L-dc.\xB0_h."; $counts = count_chars($source, 1); $sequences = array_map( fn ($i) => sprintf('The byte 0x%02X appears %d time(s), starting from position %d', $i, $counts[$i], strpos($source, chr($i))), array_keys($counts) ); echo implode("\n", $sequences); The byte 0x12 appears 1 time(s), starting from position 1 ...
Или так: PHP: <?php $source = "\x07\x00\x20\x07\xAD\x60\x20\xFE\x12\x20"; $counts = count_chars($source, 1); $sequences = []; foreach (array_keys($counts) as $i) { $positions = []; for ($j = 0, $p = -1; $j < $counts[$i]; $j++) { $p = strpos($source, chr($i), $p + 1); $positions[] = $p; } $sequences[] = sprintf('The byte 0x%02X appears %d times: at %s', $i, $counts[$i], implode(', ', $positions)); } echo implode("\n", $sequences); Код (Text): The byte 0x00 appears 1 times: at 1 The byte 0x07 appears 2 times: at 0, 3 The byte 0x12 appears 1 times: at 8 The byte 0x20 appears 3 times: at 2, 6, 9 The byte 0x60 appears 1 times: at 5 The byte 0xAD appears 1 times: at 4 The byte 0xFE appears 1 times: at 7
@artoodetoo Ему же надо проверить повторение по системе (когда первое повторение через 3 байта, а второе - через 5). Хотя да, можно и просто со строкой это сделать
я понимаю Поиск последовательности одинаковых элементов массива как поиск последовательности одинаковых элементов массива )) но возможно я не прав --- Добавлено --- но даже если конечная цель это нахождение известных паттернов в размещении, то скрипт мог бы проделать эту предварительную работу. будет всего навсего <= 256 цепочек для анализа --- Добавлено --- сразу после count_count() можно отбросить заведомо неподходящие варианты и сканировать остальные.