2011-12-13 15 views
13

Sto lavorando con qualche codice legacy e mi sono imbattuto in una funzione che è apparentemente usata per eseguire conversioni di ordine di byte di rete su un campo arbitrariamente lungo (più grande di ntohl in grado di gestire).Cosa fa in realtà questo? - Funzione Crazy C++

Non riesco a capirlo abbastanza bene da dire se sta facendo qualcosa di più che invertire l'ordine dei byte sul range del buffer msg (o anche se lo farà in modo affidabile). Qualcuno può aiutarmi a scomporlo e analizzarlo così posso sostituirlo con qualcosa che è più comprensibile (o almeno commentarlo bene!)?

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

Vedere http://stackoverflow.com/a/746203/367273 dove questa funzione viene visualizzata insieme a numerose alternative. Votare per chiudere su questa base. – NPE

+0

Erm ... dovrei prenderlo come "è perfettamente sicuro e non ti preoccupare?" –

+1

Dipende da te. Merita chiaramente un commento (e forse un link a quell'altra domanda SO? :-)) – NPE

risposta

20

Per vedere come funziona, è consigliabile applicare le operazioni al modello di bit abcdefgh. Rappresenterò i numeri binari con . per 0, quindi i bit diversi da zero si distinguono.

La prima subespressione è:

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

La seconda è:

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

loro combinazione e moltiplicando per la costante finale dà:

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

Infine spostando dalla 16 bit dà hgfedcba, il contrario del modello originale.

+0

Grazie per la risposta dettagliata, ha reso molto più facile da capire :) –