Skip to main content

How to Generate Random Bytes, Hex Strings, and Colors in Python

This guide explains how to generate random byte strings, hexadecimal strings, and random hex color codes in Python. We'll use the os, secrets, random, and binascii modules, covering both general-purpose random data and cryptographically secure random data.

Generating Random Bytes

Using os.urandom() (Cryptographically Secure)

The os.urandom() function generates cryptographically secure random bytes. This is suitable for security-sensitive applications.

import os

random_bytes = os.urandom(8) # Generate 8 random bytes
print(random_bytes) # Output: (e.g.,) b'\xd8\xa7\\\xe4~\xa2y\xe3'
print(len(random_bytes)) # Output: 8

random_bytes_16 = os.urandom(16) # Generate 16 random bytes
print(random_bytes_16) # Output: (e.g.,) b'\xeb\xba^\x81\xe1\x00\xb9\x0c\x99\x1e\xe9\x86\x86\x0bl]'
  • os.urandom(n): Returns a bytestring of n random bytes.
  • You can also create a random byte array by passing the result of os.urandom() to the bytearray constructor.

Using random.randbytes() (Python 3.9+, Not for Security)

Python 3.9 introduced random.randbytes(), which provides a way to generate random bytes without using the operating system's source of randomness. This method is not suitable for cryptographic purposes.

import random
import sys

if sys.version_info >= (3, 9): # Check for proper Python version
random_bytes = random.randbytes(8)
print(random_bytes) # Output (will vary): b'\xb0\x1c\x01:L\x95 \xa3'
print(len(random_bytes)) # Output: 8
else:
print("random.randbytes requires Python 3.9+")

Using secrets.token_bytes() (Cryptographically Secure)

For generating cryptographically secure random bytes (e.g., for keys, nonces, salts), use secrets.token_bytes():

import secrets

random_bytes = secrets.token_bytes(8)
print(random_bytes) # Output: (e.g.,) b'>C\xe3\xe3?m\xa4u'
print(len(random_bytes)) # Output: 8

random_bytes_16 = secrets.token_bytes(16) # Returns 16 random bytes.
print(random_bytes_16) # Output: b'\x84\x84>\xe0]o\xda\x1e\xc8qL\xde\xf0\x8e\xc7\xec'

random_bytes_default = secrets.token_bytes() # Returns a default number of bytes.
print(random_bytes_default) # Output: b'\xcc\xed\xf2\xd6Q\x9e\x02\x02\x1d\xbe\xddu\xf9\x11\xd5\x015\xccT\xf4\xe4)/S\xd9N\xed\x0b\xb0;Xt'
  • secrets.token_bytes(n): Returns a bytestring containing n random bytes. If n is None or not supplied, a reasonable default is used.
  • Use secrets for any security-sensitive random data.

Generating Random Hex Strings

A hexadecimal string is a string representation of bytes, where each byte is represented by two hexadecimal digits (0-9, a-f).

Using os.urandom() and binascii.b2a_hex()

import binascii
import os

result = binascii.b2a_hex(os.urandom(10)) # Generates 10 random bytes
print(result) # Output: (e.g.,) b'a28ad94dde798a004e4d' (as bytes)

string = result.decode('utf-8') # Decodes the bytes to a string.
print(string) # Output: (e.g.,) a28ad94dde798a004e4d
  • os.urandom(10): Generates 10 cryptographically secure random bytes.
  • binascii.b2a_hex(...): Converts the bytes to their hexadecimal representation (as a bytes object).
  • You can convert the bytes result to a str using decode.

Using random.choices() (Not for Security)

For non-security-critical random hex strings, you can use random.choices():

import random

def gen_random_hex_string(size):
return ''.join(random.choices('0123456789abcdef', k=size)) # Choose from hex digits

result = gen_random_hex_string(16)
print(result) # Output: (e.g.,) db688cb662842860
  • random.choices('0123456789abcdef', k=size): Selects size random characters from the string of hexadecimal digits.
  • ''.join(...): Joins the selected characters into a string.
  • The hex string can be made uppercase using '0123456789ABCDEF' instead.

For security-sensitive applications (e.g., generating session tokens), use secrets.token_hex():

import secrets

result = secrets.token_hex(16) # 16 bytes = 32 hex characters
print(result) # Output: (e.g.,) c39d47a82e4fda7cd43ca139db5cebb3
print(len(result)) # Output: 32
  • secrets.token_hex(nbytes): Returns a random hexadecimal string containing nbytes * 2 characters. This is the best way to generate secure tokens.

Generating Random Hex Color Codes

To generate a random hex color code (like #FF00AA):

Using random.choices()

import random

def gen_random_hex_color():
hex_digits = '0123456789ABCDEF'
return '#' + ''.join(random.choices(hex_digits, k=6))
print(gen_random_hex_color()) # Output: #6DB16C
  • The random hexadecimal color is formed by combining 6 random hexadecimal characters.

Using random.randint() and f-strings

You can also use random.randint to generate a random integer, and format the result to a hexadecimal string:

import random

def gen_random_hex_color():
def get_int():
return random.randint(0, 255) # Generates a random integer from 0 to 255 inclusive.
return f'#{get_int():02X}{get_int():02X}{get_int():02X}'

print(gen_random_hex_color()) # Output (Example) #A5F627
  • This approach generates three random integers (representing red, green, and blue components) and formats them as a 6-digit hexadecimal color code.