Bulog Ответов: 1

Как перетасовать большие группы байтов? Процедура должна быть обратимой.


Тего задача чисто математическая, потому что они являются доминирующими комбинаторикой и вероятностью. Можно решить проблему, не зная программирования, но гораздо легче решить ее с помощью программирования.

В следующей 40 - байтовой группе есть 3 пары одинаковых байтов:

248, 195, 38, 169, 202, 202, 133, 240, 232, 204, 142, 40, 86, 89, 215, 138, 15, 217, 123, 33, 183, 105, 239, 239, 229, 192, 226, 191, 23, 158, 12, 94, 222, 253, 6, 113, 146, 146, 183, 209.

Пара байтов 169 202 это пара разных байтов.
Пара байтов 202 202 это пара одинаковых байтов.

Байты должны быть перетасованы так, чтобы пары одинаковых байтов не появлялись. Результирующие байты должны состоять только из пар разных байтов!

Пример результирующих байтов (своп 2*n и 2*n+1 байт, n=1..19) :

248, 38, 195, 202, 169, 133, 202, 232, 240, 142, 204, 86, 40, 215, 89, 15, 138, 123, 217, 183, 33, 239, 105, 229, 239, 226, 192, 23, 191, 12, 158, 222, 94, 6, 253, 146, 113, 183, 146, 209.

The procedure must be reversible. Instead of 40 bytes (in case of example), the procedure should be applied to a group of 1500 bytes. In a group of 1500 bytes, most pairs are different bytes. There are also pairs with the same bytes, but there are no more than 10 and they do not know where they are in the group. Multiple consecutive same bytes do not exist. In a group of 1500 bytes, all bytes appeared at least once. If the algorithm has to use additional numbers to shuffle a group of 1500 bytes, then these numbers must be the same for each group. The algorithm does not have to be successful in every call. It is enough that from 8 consecutive different groups of 1500 bytes it succeeds to shuffle any two.

Любая группа байтов из любого типа файла может быть преобразована в группу, как описано в задаче. Группа из таких 1500 байт представляет интерес для сжатия и шифрования.

Проблема в том, что происходит рекомбинация байтов - одни и те же пары устраняются в тех местах, где они были, но появляются в другом месте. Эта проблема возникает с большими группами байтов. Группа из 40 байт решит почти все известные алгоритмы перетасовки чисел, но группа из 1500 байт не решила ни одного!

Желательно предоставить решение в коде delphi 7 или псевдокоде.

Следующая процедура достаточно хорошо моделирует группу из 1500 байт:

var
  b : array [1..1500] of byte;

procedure MakePseudorandomNumbersWithEqualPairs (sum : longint; max : word);
var
  i, lastb : longint;
  range : word;
begin
  Randomize;                    // Prepare a random number generator
  lastb := sum;                 // How many total bytes
  range := max;                 // Bytes from the range 0..max-1
  for i := 1 to lastb do        // They can be the same neighbors!      
    b[i] := Random (range);
end;

После вызова процедуры:

MakePseudorandomNumbersWithEqualPairs (1500, 256);


массив b содержит байты, моделирующие данную группу.

Что я уже пробовал:

const
  lastb = 1500;
var
  b, c : array [1..lastb] of byte;
  
procedure PerfectShuffle;      // Perfect shuffle
var
  i : integer;

begin
  if (lastb mod 2) = 0     // only if is a even number of bytes!
   then
    begin
      for i := 1 to (lastb div 2) do
        c[i*2-1] := b[i];
      for i := (lastb div 2)+1 to lastb do
        c[i*2-lastb] := b[i];

      for i := 1 to lastb do
        b[i] := c[i];
    end;


Входной сигнал: б
Вывод: б

OriginalGriff

И что же?
Что он делает такого, чего вы не ожидали, или не делает того, что вы сделали?
Где ты застрял?
Какая помощь вам нужна?

1 Ответов

Рейтинг:
1

CPallini

Я бы попробовал так: для каждой найденной пары (начиная с индекса i) выберите случайное число r и поменять местами элемент в индексе i с товаром по адресу (i+r) (с обертыванием вокруг), если только такой элемент сам не равен членам пары. В таком несчастливом случае попробуйте с (i+r+1), (i+r+2) ..., пока вы не найдете подходящий предмет.
В соответствии с требованием обратимости обратите внимание на произошедшие свопы и примените их в обратном порядке.


Bulog

The idea is quite good. I myself tried with random indexes. But the problem is that it's forbidden to remember different extra numbers for each group separately. It is permissible to remember only the same additional numbers that apply to all groups of bytes that are being processed, and a different group of bytes enters each call. Pairs with the same bytes are in each following group at completely different locations and their exact number is unknown. It is not allowed for each group, for example, to remember locations where pairs with the same bytes are located. This random number r is allowed, but it should apply to each group, at each call procedure. It simply has space for Nx1500 bytes + a few control bytes (like r) and that's it. The procedure must be universal, valid for each group of 1500 bytes. Maybe a problem looks naïve, but it's a very difficult problem.