---
title: 'Byte Order'
source: 'https://academia.sh/en/courses/how-computers-work/byte-order'
course: 'How Computers Work'
language: en
updated: '2026-08-17T18:08:08+00:00'
license: 'CC BY-SA 4.0'
---

# Byte Order

The order in which multi-byte values are laid out in memory, little- and big-endian representation, and the problems this creates when exchanging data.

Up to this point, how many bits a value has and how those bits are interpreted have
been established. One question remains open: memory is addressed at the byte level,
yet the value `0x41424344` is four bytes. In which order do these four bytes occupy
four consecutive addresses?

The question has no single correct answer. Different families of hardware have given
different answers, and this difference leads to silent corruption when data is moved
between two systems. This lesson defines the difference and the safeguard taken
against it.

## Two Layouts

The value's most significant byte is `0x41`, and its least significant byte is
`0x44`. There are two layout arrangements:

In **big-endian** order, the most significant byte is written to the lowest address:

| Address | $A$ | $A{+}1$ | $A{+}2$ | $A{+}3$ |
|---|---|---|---|---|
| Byte | `41` | `42` | `43` | `44` |

In **little-endian** order, the least significant byte is written to the lowest
address:

| Address | $A$ | $A{+}1$ | $A{+}2$ | $A{+}3$ |
|---|---|---|---|---|
| Byte | `44` | `43` | `42` | `41` |

The value is the same in both orders: $1{,}094{,}861{,}636$. What changes is the
physical layout of that value in memory. The names are a reference to the dispute in
*Gulliver's Travels* over which end an egg should be cracked from; the naming
captures well the gap between the technical weight of the question and the practical
fatigue it produces.

## The Rationale Behind Each Order

The case for little-endian order is that a width conversion does not change the
address. On a little-endian system, reading a single byte from the address of a
32-bit value gives that value's least significant byte; reading two bytes from the
same address gives the low sixteen bits. Narrowing a value to a smaller type requires
no address arithmetic.

The case for big-endian order is readability and ordering. When a memory dump is read
left to right, the bytes appear in the same order the number is written. Multi-byte
values compared byte by byte also produce a comparison that matches numeric ordering,
which is a convenience for structures that rely on lexicographic key ordering.

Both cases are technically valid, and the choice is largely historical. What matters
is that a system's chosen order is **known**, and that the order is **fixed
explicitly** whenever data leaves that system.

## Same Bytes, Different Values

The concrete form of the problem is this: when the four bytes `41 42 43 44` are read
from a file, which number results?

- Under a big-endian reading: `0x41424344` = $1{,}094{,}861{,}636$
- Under a little-endian reading: `0x44434241` = $1{,}145{,}258{,}561$

The two values differ by more than fifty million, and no error is raised anywhere:
the program runs, and its result is wrong. This is the final instance of a principle
repeated throughout previous lessons: bytes carry no meaning of their own — meaning
comes from the rule used to read them.

The situation differs for text. ASCII and UTF-8 are sequences made of single-byte
units; a byte sequence's order is determined by the encoding itself, so the byte-order
problem does not arise. The bytes `41 42 43 44` read as UTF-8 give `ABCD` on every
system.

By contrast, the units of UTF-16 and UTF-32 are two and four bytes; in these
encodings, byte order must be stated explicitly. The way it is stated is by writing
the code point U+FEFF, the **byte order mark**, at the start of the text. UTF-8 text
does not need the same mark; its presence implies only the encoding, not the order,
and it causes unexpected behavior in some parsers.

## Network Byte Order

Network protocols must be independent of the layout of the hardware at either end.
For this reason, a single order is fixed for multi-byte fields in protocol headers:
big-endian. This convention is called **network byte order**.

The program performs the conversion from host order to network order explicitly.
Conversion functions do nothing if the host order is already big-endian; if it is
little-endian, they reverse the bytes. Code working correctly on both kinds of
hardware depends on this conversion never being skipped.

The same discipline applies to file formats: when a binary format is defined, field
widths and byte order are written into the documentation. Writing memory contents
directly to disk or to the network as-is produces a file that depends on the hardware
that created it.

## In Practice

In Python, byte order is stated explicitly to the conversion functions:

```python
import sys, struct

print(sys.byteorder)                      # this system's order: 'little' or 'big'

value = 0x41424344

print(value.to_bytes(4, "big").hex())     # 41424344
print(value.to_bytes(4, "little").hex())  # 44434241

raw = b"ABCD"                             # bytes 41 42 43 44
print(hex(int.from_bytes(raw, "big")))    # 0x41424344
print(hex(int.from_bytes(raw, "little"))) # 0x44434241

print(struct.pack(">I", value))           # b'ABCD'
print(struct.pack("<I", value))           # b'DCBA'
print(struct.unpack("!I", b"ABCD")[0])    # 1094861636  — '!' is network byte order
```

The call `struct.pack(">I", 0x41424344)` producing `b'ABCD'` ties together every
lesson of this topic in a single line: the same thirty-two bits read as
$1{,}094{,}861{,}636$ as an integer, $12.141422271728515625$ as a floating-point
number, `ABCD` as text, and, in memory, as the sequence `41 42 43 44` or
`44 43 42 41` depending on the system.

The first character of the format string states the order: `<` little-endian, `>`
big-endian, `!` network byte order (equivalent to big-endian). If this character is
omitted, the running system's order is used — the situation that portable code must
avoid.

## Not to Be Confused with Bit Order

The endianness discussion concerns **bytes**, not bits. The positional values of the
bits within a byte are the same under both orders: the most significant bit is on the
left, the least significant bit is on the right. On a little-endian system, the byte
`0x41` is still the pattern `0100 0001`; it is not reversed.

Bit order is a separate concept that applies in a different context: in the hardware
layers where data is transmitted serially over a wire, which end the bits are sent
from depends on the protocol. This is a decision independent of the byte-level order
that software sees, and it is treated in the physical layer topic of the networks
curriculum.

A third source of confusion is the memory layout of bit fields. The order in which
fields with a specified bit width are packed inside a structure depends on the
compiler, in addition to byte order. For this reason bit fields are not used in
binary formats that need to be portable; fields are instead produced with explicit
masking and shifting — exactly what the operators from the fifth lesson are for.

## The Discipline of Data Exchange

The way to avoid the byte-order problem is to handle it explicitly at every boundary:

1. **Order is documented in binary formats.** Field widths and byte order are part of
   the format definition; both the reader and the writer conform to the same
   document.
2. **Conversion happens at boundaries.** A value is converted to host order as it
   enters the system, and to the fixed order as it leaves; the code in between never
   thinks about order at all.
3. **Memory contents are not transferred directly.** A raw copy of a structure is not
   portable, due to alignment and padding differences in addition to byte order.
4. **Text formats do not solve the problem by themselves.** Text-based formats such
   as JSON have no byte-order problem, but numeric precision and encoding decisions
   must be documented instead.

This discipline will come up again in every layer that works with network protocols
and file formats.

## Summary

- The bytes of a multi-byte value can be laid out in memory in two different orders:
  little-endian places the least significant byte at the lowest address, big-endian
  places the most significant byte there.
- The value stays the same; the layout changes — the same byte sequence gives a
  different number under the two orders.
- Little-endian order frees width narrowing from address arithmetic; big-endian order
  gives memory-dump readability and lexicographic ordering.
- Encodings made of single-byte units (ASCII, UTF-8) have no byte-order problem;
  UTF-16 and UTF-32 state their order with a byte order mark.
- Network protocols fix big-endian order; the conversion is performed explicitly by
  the program.
- In binary data exchange, byte order is part of the format definition; a raw memory
  copy is not portable.

## Next Step

This topic established how data is represented in memory: bits, integers, real
numbers, text, and byte layout. What comes next is what is done with that data. The
next topic takes up how memory connects to the processor and the steps by which an
instruction is executed in hardware; there, the `0x41424344` pattern will appear once
more, this time possibly as an instruction itself.
