Introduction
Converting an integer to a byte array is essential for binary protocols, network communication, file I/O, and serialization. The key consideration is byte order (endianness) — big-endian stores the most significant byte first, while little-endian stores the least significant byte first. Most network protocols use big-endian (network byte order), while x86 CPUs use little-endian. Every language provides built-in methods for this conversion with explicit endianness control.
Python
1# int.to_bytes() — Python 3.2+
2number = 1024
3
4# Big-endian (network byte order)
5big = number.to_bytes(4, byteorder='big')
6print(big) # b'\x00\x00\x04\x00'
7
8# Little-endian (x86 native order)
9little = number.to_bytes(4, byteorder='little')
10print(little) # b'\x00\x04\x00\x00'
11
12# Convert back
13int.from_bytes(big, byteorder='big') # 1024
14int.from_bytes(little, byteorder='little') # 1024
15
16# Using struct module (C-compatible layout)
17import struct
18
19packed = struct.pack('>I', 1024) # > = big-endian, I = unsigned 32-bit
20print(packed) # b'\x00\x00\x04\x00'
21
22unpacked = struct.unpack('>I', packed)[0] # 1024
struct format characters: > big-endian, < little-endian, I unsigned int (4 bytes), Q unsigned long long (8 bytes), H unsigned short (2 bytes).
Java
1import java.nio.ByteBuffer;
2import java.nio.ByteOrder;
3
4int number = 1024;
5
6// Big-endian (default for ByteBuffer and network protocols)
7byte[] big = ByteBuffer.allocate(4).putInt(number).array();
8// [0, 0, 4, 0]
9
10// Little-endian
11byte[] little = ByteBuffer.allocate(4)
12 .order(ByteOrder.LITTLE_ENDIAN)
13 .putInt(number)
14 .array();
15// [0, 4, 0, 0]
16
17// Convert back
18int fromBig = ByteBuffer.wrap(big).getInt(); // 1024
19int fromLittle = ByteBuffer.wrap(little)
20 .order(ByteOrder.LITTLE_ENDIAN)
21 .getInt(); // 1024
22
23// Manual bit shifting (no ByteBuffer)
24byte[] manual = new byte[] {
25 (byte)(number >> 24),
26 (byte)(number >> 16),
27 (byte)(number >> 8),
28 (byte)number
29};
C#
1int number = 1024;
2
3// BitConverter uses system endianness (usually little-endian on x86)
4byte[] bytes = BitConverter.GetBytes(number);
5// [0, 4, 0, 0] on little-endian systems
6
7// Check system endianness
8Console.WriteLine(BitConverter.IsLittleEndian); // True on x86
9
10// Convert back
11int result = BitConverter.ToInt32(bytes, 0); // 1024
12
13// Force big-endian (network byte order)
14byte[] bigEndian = BitConverter.GetBytes(number);
15if (BitConverter.IsLittleEndian)
16 Array.Reverse(bigEndian);
17// [0, 0, 4, 0]
18
19// Using BinaryPrimitives (.NET Core 2.1+) — no allocation
20Span<byte> buffer = stackalloc byte[4];
21BinaryPrimitives.WriteInt32BigEndian(buffer, 1024);
22BinaryPrimitives.WriteInt32LittleEndian(buffer, 1024);
23
24int value = BinaryPrimitives.ReadInt32BigEndian(buffer);
JavaScript
1// Using DataView for explicit endianness control
2const buffer = new ArrayBuffer(4);
3const view = new DataView(buffer);
4
5// Big-endian (default)
6view.setInt32(0, 1024, false); // false = big-endian
7console.log(new Uint8Array(buffer)); // [0, 0, 4, 0]
8
9// Little-endian
10view.setInt32(0, 1024, true); // true = little-endian
11console.log(new Uint8Array(buffer)); // [0, 4, 0, 0]
12
13// Convert back
14const big = view.getInt32(0, false); // 1024
15const little = view.getInt32(0, true); // 1024
16
17// Node.js Buffer
18const buf = Buffer.alloc(4);
19buf.writeInt32BE(1024, 0); // Big-endian
20buf.writeInt32LE(1024, 0); // Little-endian
21
22const value = buf.readInt32BE(0); // 1024
C/C++
1#include <stdint.h>
2#include <string.h>
3#include <arpa/inet.h> // for htonl/ntohl
4
5int32_t number = 1024;
6
7// Method 1: memcpy (preserves native endianness)
8uint8_t bytes[4];
9memcpy(bytes, &number, sizeof(number));
10
11// Method 2: Bit shifting (explicit big-endian)
12bytes[0] = (number >> 24) & 0xFF;
13bytes[1] = (number >> 16) & 0xFF;
14bytes[2] = (number >> 8) & 0xFF;
15bytes[3] = number & 0xFF;
16
17// Method 3: htonl for network byte order (big-endian)
18uint32_t network_order = htonl((uint32_t)number);
19memcpy(bytes, &network_order, 4);
20
21// Convert back
22int32_t restored = ((int32_t)bytes[0] << 24) |
23 ((int32_t)bytes[1] << 16) |
24 ((int32_t)bytes[2] << 8) |
25 bytes[3];
Go
1import (
2 "encoding/binary"
3 "fmt"
4)
5
6number := int32(1024)
7buf := make([]byte, 4)
8
9// Big-endian
10binary.BigEndian.PutUint32(buf, uint32(number))
11fmt.Println(buf) // [0 0 4 0]
12
13// Little-endian
14binary.LittleEndian.PutUint32(buf, uint32(number))
15fmt.Println(buf) // [0 4 0 0]
16
17// Convert back
18value := binary.BigEndian.Uint32(buf)
Common Pitfalls
Ignoring endianness: Systems use different byte orders. Sending little-endian bytes to a big-endian receiver corrupts the value. Always agree on endianness in protocols — network byte order (big-endian) is the standard convention.
Wrong byte array size: A 32-bit int needs 4 bytes, a 64-bit long needs 8 bytes. Using the wrong size truncates or pads the value. Match the byte array size to the integer type's bit width.
Signed vs unsigned interpretation: The same bytes [0xFF, 0xFF, 0xFF, 0xFF] represent -1 as a signed int or 4294967295 as an unsigned int. Use the matching signed/unsigned conversion function for your data type.
Using BitConverter in C# without checking endianness: BitConverter.GetBytes() uses the system's native endianness, which is little-endian on x86. For portable code, use BinaryPrimitives with explicit big/little endian methods.
Integer overflow when converting back: Reconstructing a 32-bit int from bytes using bit shifts in languages without unsigned types (like Java) can produce unexpected negative values. Use & 0xFF masks on each byte to prevent sign extension.
Summary
Use int.to_bytes() / struct.pack() in Python, ByteBuffer in Java, BitConverter / BinaryPrimitives in C#
Always specify endianness explicitly — big-endian for network protocols, little-endian for x86 native
htonl() / ntohl() in C convert between host and network byte order
JavaScript uses DataView for endianness control, Node.js uses Buffer
Match byte array size to integer bit width (4 bytes for 32-bit, 8 bytes for 64-bit)
Use & 0xFF masks when reconstructing integers from bytes to prevent sign extension