How to Convert Between Binary, Hexadecimal, and Decimal in Python
Python provides robust built-in functions for base conversion between decimal, binary, and hexadecimal. No external libraries are required for standard operations.
This guide covers the essential conversion techniques, formatting options, and byte-level operations.
Core Conversion Functions
Python offers three primary functions for base conversion: bin(), hex(), and int().
Converting Decimal to Other Bases
num = 255
# Decimal to Binary (returns string with '0b' prefix)
binary = bin(num)
print(binary) # OUtput: 0b11111111
# Decimal to Hexadecimal (returns string with '0x' prefix)
hexadecimal = hex(num)
print(hexadecimal) # Output: 0xff
# Decimal to Octal (returns string with '0o' prefix)
octal = oct(num)
print(octal) # Output: 0o377
Converting Other Bases to Decimal
Use int(string, base) to convert strings in any base back to decimal:
# Binary to Decimal
print(int('0b11111111', 2)) # Output: 255
print(int('11111111', 2)) # Output: 255 (prefix is optional)
# Hexadecimal to Decimal
print(int('0xff', 16)) # Output: 255
print(int('FF', 16)) # Output: 255 (case insensitive)
# Octal to Decimal
print(int('0o377', 8)) # Output: 255
print(int('377', 8)) # Output: 255
The second argument to int() specifies the base. Common values:
2for binary8for octal16for hexadecimal0for automatic detection based on prefix
Formatting Without Prefixes
For display purposes, you often need the raw string without 0b or 0x prefixes.
Using f-strings (Recommended)
F-strings provide the most control over formatting:
val = 255
# Binary without prefix
print(f"{val:b}") # Output: 11111111
# Hexadecimal (lowercase and uppercase)
print(f"{val:x}") # Output: ff
print(f"{val:X}") # Output: FF
# Octal without prefix
print(f"{val:o}") # Output: 377
Padding with Zeros
Fixed-width formatting is essential for consistent output:
val = 5
# 8-bit binary representation
print(f"{val:08b}") # Output: 00000101
# 16-bit binary
print(f"{val:016b}") # Output: 0000000000000101
# 2-digit hex (useful for byte representation)
print(f"{val:02x}") # Output: 05
# 4-digit hex
print(f"{val:04X}") # Output: 0005
Using String Slicing
An alternative approach for removing prefixes:
print(bin(255)[2:]) # Output: 11111111
print(hex(255)[2:]) # Output: ff
Direct Base-to-Base Conversion
To convert directly between binary and hexadecimal, chain the operations:
# Binary string to Hex string
binary_str = '11111111'
hex_str = hex(int(binary_str, 2))
print(hex_str) # Output: 0xff
# Clean version without prefix
hex_clean = f"{int(binary_str, 2):x}"
print(hex_clean) # Output: ff
# Hex string to Binary string
hex_str = 'ff'
binary_str = bin(int(hex_str, 16))
print(binary_str) # Output: 0b11111111
# Clean version
binary_clean = f"{int(hex_str, 16):08b}"
print(binary_clean) # Output: 11111111
Working with Bytes
In network programming and file I/O, you work with raw bytes rather than strings.
Integer to Bytes
# Single byte
byte_val = (255).to_bytes(1, byteorder='big')
print(byte_val) # Output: b'\xff'
# Multiple bytes (e.g., 32-bit integer)
num = 256
byte_val = num.to_bytes(4, byteorder='big')
print(byte_val) # Output: b'\x00\x00\x01\x00'
# Little-endian (least significant byte first)
byte_val = num.to_bytes(4, byteorder='little')
print(byte_val) # Output: b'\x00\x01\x00\x00'
Bytes to Integer
# Single byte
print(int.from_bytes(b'\xff', byteorder='big')) # Output: 255
# Multiple bytes
data = b'\x00\x00\x01\x00'
print(int.from_bytes(data, byteorder='big')) # Output: 256
'big'(Big-Endian): Most significant byte first. Standard for network protocols.'little'(Little-Endian): Least significant byte first. Common on x86/x64 processors.
Converting Bytes to Hex String
data = b'\xde\xad\xbe\xef'
# Using .hex() method (Python 3.5+)
hex_str = data.hex()
print(hex_str) # Output: deadbeef
# With separator (Python 3.8+)
print(data.hex(':')) # Output: de:ad:be:ef
# Converting hex string back to bytes
restored = bytes.fromhex('deadbeef')
print(restored) # Output: b'\xde\xad\xbe\xef'
Practical Examples
Color Code Conversion
def hex_to_rgb(hex_color: str) -> tuple:
"""Convert hex color to RGB tuple."""
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
def rgb_to_hex(r: int, g: int, b: int) -> str:
"""Convert RGB values to hex color."""
return f"#{r:02x}{g:02x}{b:02x}"
print(hex_to_rgb("#ff5733")) # Output: (255, 87, 51)
print(rgb_to_hex(255, 87, 51)) # Output: #ff5733
IP Address Conversion
def ip_to_int(ip: str) -> int:
"""Convert IP address to integer."""
octets = [int(x) for x in ip.split('.')]
return (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3]
def int_to_ip(num: int) -> str:
"""Convert integer to IP address."""
return f"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}"
print(ip_to_int("192.168.1.1")) # Output: 3232235777
print(int_to_ip(3232235777)) # Output: 192.168.1.1
Quick Reference
| Conversion | Function/Pattern | Example |
|---|---|---|
| Decimal → Binary | bin(x) | bin(255) → '0b11111111' |
| Decimal → Hex | hex(x) | hex(255) → '0xff' |
| String → Decimal | int(s, base) | int('ff', 16) → 255 |
| Clean Binary | f"{x:b}" | f"{255:b}" → '11111111' |
| Padded Binary | f"{x:08b}" | f"{5:08b}" → '00000101' |
| Int → Bytes | x.to_bytes(n, order) | (255).to_bytes(1, 'big') |
| Bytes → Int | int.from_bytes(b, order) | int.from_bytes(b'\xff', 'big') |
Summary
- Use
bin(),hex(), andoct()to convert integers to string representations. - Use
int(string, base)to convert strings back to integers. - Use f-strings like
f"{x:08b}"for formatted output without prefixes. - Use
.to_bytes()andint.from_bytes()for byte-level operations.