2011-12-13 25 views
13

Estoy trabajando con algún código heredado y me encontré con una función que aparentemente se utiliza para realizar conversiones de orden de bytes de red en un campo arbitrariamente largo (más grande que ntohl puede manejar).¿Qué hace esto realmente? - Crazy C++ función

No puedo entenderlo lo suficiente como para saber si está haciendo algo más que invertir el orden de bytes en el rango del búfer de mensajes (o incluso si lo hace de manera confiable). ¿Alguien me puede ayudar a descomponerlo y analizarlo para poder reemplazarlo con algo que sea más inteligible (o al menos comentarlo bien)?

void swapit(unsigned char *msg, int length) { 
    for(;length>0;length--, msg++) { 
    *msg = ((*msg * 0x0802LU & 0x22110LU) | 
      (*msg * 0x8020LU & 0x88440LU)) * 
      0x10101LU >> 16; 
    } 
} 
+3

Consulte http://stackoverflow.com/a/746203/367273 donde aparece esta función junto con numerosas alternativas. Votación para cerrar sobre esa base. – NPE

+0

Erm ... ¿debería tomar eso como un "es perfectamente seguro y no te preocupes por eso?" –

+1

Eso depende de usted. Claramente merece un comentario (y tal vez un enlace a esa otra pregunta ASÍ :-)) – NPE

Respuesta

20

Para ver cómo funciona, considerar la aplicación de las operaciones para el patrón de bits abcdefgh. Representaré números binarios con . para 0, por lo que los bits que no sean cero se destacan.

La primera subexpresión es:

........ ........ abcdefgh 
* ........ ....1... ......1. (0x0802) 
= .....abc defgh..a bcdefgh. 
& ......1. ..1....1 ...1.... (0x22110) 
= ......b. ..f....a ...e.... 

El segundo es:

........ ........ abcdefgh 
* ........ 1....... ..1..... (0x8020) 
= .abcdefg h..abcde fgh..... 
& ....1... 1....1.. .1...... (0x88440) 
= ....d... h....c.. .g...... 

combinación de ellas y multiplicando por la constante final da:

......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.... 

último cambio descendente por 16 bits da hgfedcba, al revés del patrón original.

+0

Gracias por la respuesta detallada, hizo que fuera mucho más fácil de entender :) –

Cuestiones relacionadas