Cos’è l’endianness
Un numero di più byte deve essere memorizzato byte per byte, e ci sono due ordini ragionevoli per farlo. Big-endian mette il byte più significativo all’indirizzo più basso, come scriviamo i numeri: 0x12345678 diventa 12 34 56 78. Little-endian mette prima il byte meno significativo: 78 56 34 12. x86, x86-64 e (di default) ARM sono little-endian; i protocolli di rete (IP, TCP, DNS), i file class di Java, PNG e la maggior parte dei formati mainframe sono big-endian, per questo «ordine dei byte di rete» significa big-endian.
Quando conta
Dentro un programma su una macchina, mai: ci pensa la CPU. Conta nel momento in cui i byte attraversano un confine: scrivere una struct in un file, leggere un pacchetto, parlare con un sensore via SPI, mappare un formato di file binario o interpretare un dump hex. Leggere 78 56 34 12 in un dump di memoria x86 e scambiarlo per 0x78563412 è l’errore classico.
Le funzioni
| Linguaggio | Host → rete (big-endian) | Scambio arbitrario |
|---|---|---|
| C | htonl, htons, htobe64 | __builtin_bswap32 |
| Go | binary.BigEndian.PutUint32 | bits.ReverseBytes32 |
| Python | struct.pack('>I', x) | x.to_bytes(4, 'little') |
| Rust | x.to_be_bytes() | x.swap_bytes() |
| JavaScript | DataView.setUint32(o, x) | DataView con littleEndian=true |
UTF-16 e la BOM
Il testo in UTF-16 ha lo stesso problema, per questo i file possono iniziare con un byte order mark: FE FF per big-endian, FF FE per little-endian. UTF-8 non ha un ordine dei byte e non ha bisogno di BOM.
Domande
Che endianness usa il mio computer?
Quasi certamente little-endian: tutte le CPU x86 e x86-64 lo sono, e ARM (telefoni, Apple Silicon, Raspberry Pi) funziona in pratica little-endian. Il big-endian sopravvive nei protocolli di rete e in alcuni sistemi embedded e mainframe (s390x, vecchi PowerPC, SPARC).
Perché la rete è big-endian?
Convenzione storica del primo ARPANET e delle macchine IBM/Motorola, fissata nell’RFC 1700. Ogni protocollo successivo la segue, per questo ogni API socket ha htons/htonl.
L’endianness influisce sui bit dentro un byte?
No. Un byte si legge sempre per intero. L’ordine dei bit conta solo nei protocolli seriali e in alcuni algoritmi CRC, ed è una questione a parte.
Come rilevo l’endianness a runtime?
Scrivi un 1 in un intero a 32 bit e guarda il primo byte: 1 significa little-endian. In pratica è meglio usare funzioni di conversione esplicite perché il codice funzioni ovunque.
Cos’è il middle-endian?
Il PDP-11 memorizzava i valori a 32 bit come due metà little-endian a 16 bit in ordine big-endian (34 12 78 56). È estinto, ma il termine si usa ancora per formati di data come MM-DD-YYYY.