Actualmente estoy escribiendo algo en C#/.NET que implica enviar enteros de 16 bits sin firmar en un paquete de red. El orden de los bytes debe ser big endian.
En el nivel de bit, mi comprensión de 'big endian' es que el bit más significativo va al final y al revés para little endian.
Y a nivel de byte, mi comprensión es la misma: si estoy convirtiendo un entero de 16 bits en los dos enteros de 8 bits que lo componen, y la arquitectura es little endian, entonces esperaría que el byte más significativo fuera a el principio.
Sin embargo, BitConverter parece colocar el byte con el valor más pequeño al final de la matriz, a diferencia del byte con el valor menos significativo, por ejemplo
ushort number = 4; var bytes = BitConverter.GetBytes(number); Debug.Assert(bytes[BitConverter.IsLittleEndian ? 0 : 1] == 0); Para mayor claridad, si mi comprensión es correcta, entonces en una máquina little endian esperaría que lo anterior devuelva 0x00, 0x04 y en una máquina big endian 0x04, 0x00 . Sin embargo, en mi estación de trabajo Little Endian Windows x86 que ejecuta .NET 5, devuelve 0x04, 0x00
Incluso está documentado que han considerado el endianismo. De: https://docs.microsoft.com/en-us/dotnet/api/system.bitconverter.getbytes?view=net-5.0
El orden de los bytes en la matriz devuelta por el método GetBytes depende de si la arquitectura de la computadora es little-endian o big-endian.
¿Estoy siendo tonto o esto parece un comportamiento incorrecto?
De hecho, estoy siendo tonto. Como señaló @mjwills, y la documentación de Microsoft explica ( https://docs.microsoft.com/en-us/dotnet/api/system.bitconverter.islittleendian?view=net-5.0#remarks ):
"Big-endian" significa que el byte más significativo está en el extremo izquierdo de una palabra. "Little-endian" significa que el byte más significativo está en el extremo derecho de una palabra.
Wikipedia tiene una explicación un poco mejor:
Un sistema big-endian almacena el byte más significativo de una palabra en la dirección de memoria más pequeña y el byte menos significativo en la más grande. Un sistema little-endian, por el contrario, almacena el byte menos significativo en la dirección más pequeña.
Entonces, si imagina las direcciones de memoria, convertir un entero de 16 bits con un valor de 4 se convierte en:
| Dirección | 0x00 | 0x01 |
|---|---|---|
| little-endian | 0x04 | 0x00 |
| big-endian | 0x00 | 0x04 |
¡Espero que esto ayude a alguien igualmente tonto en el futuro!