Что это на самом деле? - Сумасшедшая функция С++
Я работаю с каким-то унаследованным кодом, и я наткнулся на функцию, которая, по-видимому, используется для преобразования сетевых байтовых порядков на произвольно длинном поле (больше, чем ntohl может обрабатывать).
Я не могу понять это достаточно хорошо, чтобы сказать, делает ли он что-то большее, чем отменяет порядок байтов по диапазону буфера msg (или даже если он сделает это надежно). Может кто-то помочь мне разобраться с этим и проанализировать его, чтобы я мог заменить его чем-то более понятным (или, по крайней мере, прокомментировать его)??
void swapit(unsigned char *msg, int length) {
for(;length>0;length--, msg++) {
*msg = ((*msg * 0x0802LU & 0x22110LU) |
(*msg * 0x8020LU & 0x88440LU)) *
0x10101LU >> 16;
}
}
Ответы
Ответ 1
Чтобы узнать, как это работает, рассмотрите применение операций к битовой схеме abcdefgh
.
Я буду представлять двоичные числа с .
для 0
, поэтому выделяются ненулевые бит.
Первое подвыражение:
........ ........ abcdefgh
* ........ ....1... ......1. (0x0802)
= .....abc defgh..a bcdefgh.
& ......1. ..1....1 ...1.... (0x22110)
= ......b. ..f....a ...e....
Вторая:
........ ........ abcdefgh
* ........ 1....... ..1..... (0x8020)
= .abcdefg h..abcde fgh.....
& ....1... 1....1.. .1...... (0x88440)
= ....d... h....c.. .g......
Объединяя их и умножая на конечную константу, получим:
......b. ..f....a ...e....
| ....d... h....c.. .g......
= ....d.b. h.f..c.a .g.e....
* .......1 .......1 .......1 (0x10101)
= ....d.b. h.f..c.a .g.e....
+h.f..c.a .g.e.... ........
+.g.e.... ........ ........
= hgfedcba hgfe.c.a .g.e....
Наконец, переход вниз на 16 бит дает hgfedcba
, обратную к исходному шаблону.
Ответ 2
Из этого вопроса: Лучший алгоритм для бит-реверса (от MSB- > LSB до LSB- > MSB) в C
Кажется, это реверсивные биты.
0010 0000 => 0000 0100
Ответ 3
Он упоминается в битных твист-хаках как Обратный бит в байте с 7 операциями (без 64-разрядных).