DevToys Web Pro iconDevToys Web ProBlog
Értékeljen minket:
Próbáld ki a böngészőbővítményt:
← Back to Blog

Swap Endianness: Byte Order, Little-Endian vs Big-Endian Explained

7 min read

When a multi-byte integer is stored in memory, the processor must decide which byte goes first. That ordering is called endianness. It sounds like a minor implementation detail, but it becomes critical the moment two systems — or two different layers of the same system — exchange raw binary data. Use the Swap Endianness tool to convert values interactively as you work through the examples below.

What Is Endianness?

Every integer wider than one byte spans multiple memory addresses. Endianness describes which of those addresses holds the most-significant byte (MSB) and which holds the least-significant byte (LSB).

Take the 32-bit value 0x12345678. It has four bytes: 0x12, 0x34, 0x56, and 0x78, where 0x12 is the most significant and 0x78 is the least significant.

Byte orderAddress +0Address +1Address +2Address +3
Big-endian (BE)12345678
Little-endian (LE)78563412

Big-endian stores the most-significant byte at the lowest address — the same order you read a number on paper. Little-endian stores the least-significant byte first. Neither is universally "correct"; they are just conventions that must match on both ends of a data exchange.

Value: 0x12345678 (decimal 305 419 896)

Big-endian memory layout:
  [addr+0] 12  [addr+1] 34  [addr+2] 56  [addr+3] 78

Little-endian memory layout:
  [addr+0] 78  [addr+1] 56  [addr+2] 34  [addr+3] 12

Big-Endian vs Little-Endian in Practice

Most modern desktop and server CPUs — x86, x86-64, and the majority of ARM deployments (Android, iOS, Apple Silicon in LE mode) — are little-endian. If you read a 32-bit integer from memory on any of these platforms without converting, you get the value in little-endian order.

Big-endian is less common on CPUs today but remains the dominant byte order in network protocols and many binary file formats. SPARC, IBM z/Architecture, and older MIPS and PowerPC systems default to big-endian. ARM is bi-endian and can run either way, but almost always runs little-endian in modern devices.

ContextDefault byte orderNotes
x86 / x86-64 CPULittle-endianAll modern Intel & AMD chips
ARM (Android, iOS, Apple Silicon)Little-endianBi-endian hardware, but LE in practice
Network protocols (TCP/IP, UDP)Big-endianDefined as "network byte order" by RFC 1700
PNG, BMP, WAV headersMixed (format-specific)BMP uses LE; PNG and WAV use BE for most fields
ELF binariesMatches target architectureEI_DATA byte in header declares the order

Network Byte Order

Internet protocols standardize on big-endian, which is why big-endian is also called network byte order. RFC 1700 establishes this convention: port numbers, IP addresses, and protocol fields are all transmitted MSB first.

The C standard library provides four functions to convert between host byte order and network byte order:

  • htons() — host to network, 16-bit (short)
  • htonl() — host to network, 32-bit (long)
  • ntohs() — network to host, 16-bit
  • ntohl() — network to host, 32-bit

On a little-endian host these functions swap the bytes. On a big-endian host they are no-ops — the bytes are already in network order. Writing portable network code means always calling these functions rather than assuming your host byte order.

Word Size Matters: 16, 32, and 64-Bit Swaps

Endianness swapping is always tied to a specific word width. Swapping a 16-bit value reverses 2 bytes; a 32-bit swap reverses 4 bytes; a 64-bit swap reverses 8 bytes. You cannot swap "a buffer" without knowing the element size — applying a 32-bit swap to a buffer of 16-bit values corrupts every pair of adjacent values.

16-bit value 0x1234:
  BE: 12 34
  LE: 34 12

32-bit value 0xDEADBEEF:
  BE: DE AD BE EF
  LE: EF BE AD DE

64-bit value 0x0102030405060708:
  BE: 01 02 03 04 05 06 07 08
  LE: 08 07 06 05 04 03 02 01

Swapping Bytes in JavaScript

JavaScript gives you two practical tools for byte-order work: DataView and Node.js Buffer swap methods.

DataView is available in both browsers and Node.js. Its getter methods accept a littleEndian boolean parameter that lets you read any integer as either byte order regardless of how it was stored:

// DataView: read a 32-bit integer in either byte order
const buf = new ArrayBuffer(4);
const view = new DataView(buf);

// Write 0x12345678 as big-endian bytes: 12 34 56 78
view.setUint32(0, 0x12345678, false); // false = big-endian

// Read it back as little-endian — DataView interprets the same bytes differently
const asLE = view.getUint32(0, true);  // true = little-endian
const asBE = view.getUint32(0, false); // false = big-endian

console.log(asBE.toString(16)); // "12345678"
console.log(asLE.toString(16)); // "78563412"  <- bytes reversed

// Swapping: write as one endianness, read as the other
function swapUint32(value) {
  const buf = new ArrayBuffer(4);
  const view = new DataView(buf);
  view.setUint32(0, value, false); // store as BE
  return view.getUint32(0, true);  // read as LE = swapped
}

console.log(swapUint32(0x12345678).toString(16)); // "78563412"

Node.js Buffer provides in-place swap methods that reverse bytes within a buffer treating each element as a fixed-width integer:

// Node.js Buffer swap methods — mutate the buffer in place
const buf16 = Buffer.from([0x12, 0x34, 0x56, 0x78]);
buf16.swap16(); // swap each 16-bit pair
console.log([...buf16].map(b => b.toString(16))); // ["34","12","78","56"]

const buf32 = Buffer.from([0x12, 0x34, 0x56, 0x78]);
buf32.swap32(); // swap as one 32-bit word
console.log([...buf32].map(b => b.toString(16))); // ["78","56","34","12"]

// swap64 is also available for 8-byte chunks
const buf64 = Buffer.from([0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08]);
buf64.swap64();
console.log([...buf64].map(b => b.toString(16)));
// ["8","7","6","5","4","3","2","1"]

For working with hex strings and binary data directly, the Hex ↔ ASCII tool lets you inspect and convert raw byte sequences. See also the Hex to ASCII guide for a walkthrough of hex encoding fundamentals.

When You Encounter Endianness

Endianness problems surface most often in these situations:

  • Binary network protocols — parsing raw TCP/UDP payloads, custom wire formats, or reading DNS/TLS records without a library. Forgetting to call ntohs() on a port number produces a byte-swapped value that looks valid but is wrong.
  • File format headers — BMP stores image width in little-endian 32-bit integers; PNG stores chunk lengths in big-endian 32-bit integers. Mixing them up produces corrupted reads.
  • Reading hex dumps — a hex dump shows bytes in memory order. On a little-endian machine, the integer value 0x0400 (decimal 1024) is stored as 00 04 in the dump — reversed from how you would write it.
  • Cross-architecture data exchange — serializing a struct on an x86 host and deserializing it on a big-endian embedded device without an explicit byte-order convention will corrupt every multi-byte field.
  • ELF and Mach-O binaries — binary loaders check the endianness byte in the file header and refuse to execute a binary built for the wrong byte order.

Common Pitfalls

  • Forgetting the word size — always know whether you are swapping 16, 32, or 64 bits. A buffer containing packed 16-bit samples silently corrupts if you apply a 32-bit swap.
  • Double-swapping — applying a swap on input and again on output produces the original value, which looks correct in unit tests but fails at runtime when the data comes from the network.
  • Assuming host byte order — code that calls memcpy a struct directly from a socket buffer works on a big-endian server but silently misreads every field on any x86 machine.
  • Single-byte values are unaffected — endianness only applies to values wider than one byte. A buffer of uint8_t values needs no swapping regardless of the host byte order.

Whether you are debugging a binary protocol, reading a file format spec, or building a network parser, understanding byte order is essential. Use the Swap Endianness tool to convert values between big-endian and little-endian instantly without writing any code.