1

Естественно, что XOR можно использовать дважды, чтобы вернуть исходное значение. Что, если исходное значение является частью маски?Решение побитового уравнения XOR и ADD

Кодирование:

e[i] = c[i]^(c[i] + c[i-1]) 

Предполагая: начальное значение с [-1] = 0,^означает побитовое исключающее

В императивной форме C:

void encode(byte *p, int len) 
{ 
    byte prev = 0; 
    for (auto i = 0; i < len; i++) 
    { 
     auto byt = p[i]; 
     p[i] = byt^(prev + byt); 
     prev = byt; 
    } 
} 

Как создать шаг декодирования, который меняет это значение на e => c?

Я упростил/разъяснил (прочитал: изменен) вопрос, учитывая то, что я узнал из ваших ответов! Используя аналогичные шаги для DanL, начиная с исходного уравнения:

e[i] = c[i]^(c[i] + c[i-1]) 

e[i]^c[i] = c[i]^(c[i] + c[i-1])^c[i] 
e[i]^c[i] = c[i] + c[i-1] 
c[i] = e[i]^c[i] - c[i-1] 
c[i]^c[i] = (e[i]^c[i] - c[i-1])^c[i] 
0 = e[i]^c[i]^c[i] - c[i-1]^c[i] 
0 = e[i] - c[i-1]^c[i] 
c[i-1]^c[i] = e[i] 
c[i-1]^c[i]^c[i-1] = e[i]^c[i-1] 
c[i] = e[i]^c[i-1] 

????

Теперь, глядя на исходный код - первый байт всегда будет равен нулю (= c [i]^(c [i] + 0)). Так что да, должна быть потеряна по одному байту над множеством.

+0

Простой. По определению. c = e^(p + c) – LawfulEvil

+0

Э-э, да. Как насчет только с слева? :) – Fil

+0

Верно ли, что: a^(b + c) = (a^b) + (a^c); или похожие? – Fil

ответ

1

В каждой итерации цикла вы фактически вычисления

c_i = e^(p + c_(i-1)) 

Если вы хотите отменить петлю затем дали c_i вам нужно вычислить C_ (я-1)

Однако, как вы сказали XORing дважды получает вас обратно к исходному значению и исключающее является коммутативной операцией, так что если вы XOR вышеприведенное уравнение на е мы тогда получаем

c_i^e = e^(p + c_(i-1))^e 

, который упрощает для

c_i^e = p + c_(i-1) 

затем забрать р с обеих сторон, чтобы дать вам

(c_i^e) - p = c_(i-1) 

Таким образом, в вашем "реверса" петли

вы хотите код

c = (c^e) - p 

Edit: После просмотра пересмотренный вопрос с кодом в контексте, я не считаю, что это возможно, поскольку я считаю, что функция mix эффективно mapp с помощью массива len byte на массив длиной len-1.

Я считаю, что это из-за следующий аргумент:

Пусть несмешанный массив можно назвать несмешанным и смешанный массив после применения функции смешивания можно назвать смешанным

mixed[0] = unmixed[0]^(0 + unmixed[0]) //Remember prev = 0 initially 

поэтому смешанными [0] = unmixed [0]^unmixed [0] = 0

поэтому первый байт смешанного массива всегда будет 0.

Функция смешивания не увеличивать или уменьшать размер массива таким образом, мы в конечном итоге с массивом байтов Len с первым элементом является 0.

Поэтому мы эффективно сопоставляются пространство Len байтовых массивов на len-1 байт.

Если бы это было совершенно обратимо, мы могли бы сжать массив n байтов в массив байтов n-1, а затем сжать этот n-1 байтовый массив в n-2-байтовый массив и так далее.

Если мы используем один байтовый массив в качестве примера, то мы видим, что mix просто создает массив с одним элементом из 0, откуда вы знаете, какой из 256 возможных несмешанных массивов он был перед рукой?

+0

Фактически, любые нулевые биты в исходном массиве заставляют потерять эквивалентный бит следующего байта. Довольно потеряно :) – Fil