Пpивет, Igor !
VI>> 1) как "перевернуть" байт ?
VI>> те изначально биты расположены 0,1,..7
VI>> нужно получить байт с битами 7,6,..0
VI>> интересует алгоритм (код на c++)
IK> Hапример, так:
IK> unsigned char bitRev(unsigned char x)
IK> {
01234567
IK> x = ((x&0x55) << 1) | ((x&0xAA) >> 1);
перестановка1
1010101 55
10101010 AA
10325476
IK> x = ((x&0x33) << 2) | ((x&0xCC) >> 2);
перестановка2
110011 33
11001100 CC
32107654
IK> x = ((x&0x0F) << 4) | ((x&0xF0) >> 4);
перестановка3
0F 1111
F0 11110000
76543210
IK> return x;
все верно
IK> }
математическое обьяснение :
перестановка = перестановка3*перестановка2*перестановка1
в самом деле
перестановка3 : i -> (i-4) mod 8
перестановка2 : i -> i1= (i-2) mod 4 если рассматривать внутренний
набор в 4 бита и в общем - i -> i1 + ( i div 4) * 4
перестановка1: i -> i2 = (i-1) mod 2 если рассматривать
внутренний набор и в общем i -> i2 + (i div 2)*2
теперь считаем:
1: i-> (i-1) mod 2 + (i div 2)* 2 = i_1
2: i_1 -> (i_1-2) mod 4 + (i_1 div 4)*4 = i_2
3: i_2 -> (i_2 - 4) mod 8 = i_3
подсчитав получаем i_3 = 7-i
действительно представим индекс i = 2^2*i2+2*i1+1*i0 = (i2,i1,i0) в двоичной
системе
тогда перестановка 1:
i div 2 = 2*i2+i1
(i-1) mod 2 = (i0-1) mod 2 = (1-i0)
те i=(i2,i1,i0) -> 2*(2*i2+i1)+(1-i0) = 4*i2 + 2*i1 + (1-i0) -> (i2,i1,1-i0)
перестановка 2:
i div 4 = i2
(i-2) mod 4 = (2*(i1-1) + 1*i0) mod 4 = 2*(1-i1)+i0
те i = (i2,i1,i0) -> 4 * (i2) + 2* (1 -i1) + i0 -> (i2,1-i1,i0)
перестановка3
i -> (i-4) mod 8 = (4*(i2-1)+2*i1+1*i0) mod 8 = 4*(1-i2)+2*i1+1*i0 ->
(1-i2,i1,i0)
комбинация перестановок даст нам i = (i2,i1,i0) -> (1-i2,1-i1,1-i0) = 7-i
ps это я просто прокомментировал
кстати, при разборе можно попробовать воспользоваться
1) средствами мат логики
тогда последняя строка например расшифруется так
((x&0x0F)<<4)| ((x&0xF0)>>4) = ((x<<4)&0xF0)|(x>>4)&0x0F)=
= (x<<4)|(x>>4)
2) средствами чистой математики
вспомним что x mod k = k*{x/k} , {x} - дробная часть x
x div k = [x/k] [x] - целая часть x, x = {x}+[x],
0<={x}<1
тогда например перестановка 1 разберется так :
(i-1) mod 2 + 2* (i div 2) =
{(i-1)/2}*2 + 2* ( [i/2] )=
(i-1) + 2* ( [i/2]-[(i-1)/2])
но [i/2] - [(i-1)/2] = 1 , i - четное, = 0 , i - нечетное
следовательно
перестановка1 : i -> i+1 , i- четное,
i-1, i- нечетное