DEV Community

Michael Lip
Michael Lip

Posted on • Originally published at zovo.one

Hexadecimal Is Not Hard Once You Stop Being Afraid of Letters in Numbers

Hexadecimal is base-16 numbering. Instead of digits 0-9 (base 10), it uses digits 0-9 plus A-F, where A=10, B=11, C=12, D=13, E=14, F=15. That is the entire concept. Every developer encounters hex regularly -- memory addresses, color codes, Unicode code points, MAC addresses, cryptographic hashes -- and understanding the conversion between hex, decimal, and binary makes debugging and data inspection significantly easier.

Why hex exists

Binary (base 2) is what computers actually use, but binary numbers are long and hard for humans to parse. The number 255 in binary is 11111111 -- eight digits for a small number. In hex, it is FF -- two digits.

Hex works as a compact representation of binary because 16 is a power of 2 (16 = 2^4). Each hex digit maps exactly to four binary digits (bits):

Hex  Binary
0    0000
1    0001
2    0010
...
9    1001
A    1010
B    1011
C    1100
D    1101
E    1110
F    1111
Enter fullscreen mode Exit fullscreen mode

A byte (8 bits) is always exactly two hex digits. This perfect alignment makes hex the natural human-readable format for binary data. The memory address 0x7FFF5FBFF8A0 is much more readable than its binary equivalent, and each hex digit directly corresponds to 4 bits if you need to inspect at the bit level.

Converting hex to decimal

Multiply each digit by its positional power of 16 and sum:

0x2F = (2 * 16) + (15 * 1) = 32 + 15 = 47
0xFF = (15 * 16) + (15 * 1) = 240 + 15 = 255
0x1A3 = (1 * 256) + (10 * 16) + (3 * 1) = 256 + 160 + 3 = 419
Enter fullscreen mode Exit fullscreen mode

Converting decimal to hex

Repeatedly divide by 16, keeping the remainders:

419 / 16 = 26 remainder 3 → 3
26 / 16 = 1 remainder 10 → A
1 / 16 = 0 remainder 1 → 1
Read remainders bottom to top: 1A3
Enter fullscreen mode Exit fullscreen mode

In programming languages

Every major language supports hex literals:

// JavaScript
let x = 0xFF;        // 255
let y = parseInt("FF", 16);  // 255
let z = (255).toString(16);  // "ff"

// Hex string padding
let hex = (42).toString(16).padStart(2, '0');  // "2a"
Enter fullscreen mode Exit fullscreen mode
# Python
x = 0xFF           # 255
y = int("FF", 16)  # 255
z = hex(255)        # '0xff'
f"{255:02x}"        # 'ff'
Enter fullscreen mode Exit fullscreen mode

Common hex patterns developers encounter

Memory addresses: 0x7FFF5FBFF8A0 -- the 0x prefix signals hex notation. Debuggers show stack and heap addresses in hex.

Color codes: #FF6B35 -- each pair is a hex byte for red, green, blue.

Unicode code points: U+1F600 is the grinning face emoji. The 1F600 is hex; in decimal that is 128512.

MAC addresses: 00:1A:2B:3C:4D:5E -- six hex bytes identifying a network interface.

File signatures (magic numbers): PDF files start with 25 50 44 46 (hex for %PDF). PNG files start with 89 50 4E 47. Hex editors show these patterns.

Cryptographic hashes: SHA-256 produces a 32-byte hash displayed as 64 hex characters. e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 is the SHA-256 of an empty string.

Hex arithmetic

For quick mental math, knowing a few anchor points helps:

  • 0x10 = 16
  • 0x40 = 64
  • 0x80 = 128
  • 0xFF = 255
  • 0x100 = 256
  • 0x400 = 1,024 (1 KB)
  • 0x10000 = 65,536 (64 KB)
  • 0x100000 = 1,048,576 (1 MB)

I built a hex converter at zovo.one/free-tools/hex-converter that converts between hexadecimal, decimal, binary, and octal in real time. Enter a value in any base and see the conversions instantly. Handles large numbers and includes common reference values.


I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.

Top comments (0)