Converting Python Bytes to Hex

Mateen Kiani

Mateen Kiani

Published on Wed Jul 30 2025·5 min read

converting-python-bytes-to-hex:-a-comprehensive-guide

Introduction

Working with binary data is a daily task for many Python developers, especially when dealing with network protocols or file formats. Yet one small step that often slips under the radar is how we convert raw bytes into a readable hex string. Why does this simple conversion matter when you can just print raw bytes?

Fortunately, Python offers built-in ways to turn bytes into hex quickly and reliably. By mastering methods like bytes.hex() or the binascii module, you can debug data flows, optimize memory use, and avoid unexpected errors.

Understanding Bytes and Hex

Before diving into code, it helps to understand what bytes and hex strings represent. A byte in Python is an immutable sequence of integers between 0 and 255. Internally, each byte holds 8 bits of data. You can create a bytes object using a constructor like:

data = bytes([104, 101, 108, 108, 111]) # b'hello'

Hexadecimal is a base-16 numbering system. It uses digits 0 to 9 and letters a to f to represent values. One hex digit represents 4 bits, so two hex digits map exactly to one byte. For example, the byte value 255 becomes ff in hex, while 16 becomes 10.

Representing bytes as hex strings offers clear advantages. It makes logs more readable, eases debugging when you inspect raw data, and helps when sending binary over text-based channels like JSON or HTTP. Once you see raw bytes as hex pairs, it is easier to spot patterns and errors.

Built-in Python Methods

Python provides simple built-in tools for converting bytes to hex.

data = bytes([0, 255, 16])
hex_str = data.hex()
print(hex_str) # 00ff10

The bytes.hex() method works in Python 3.5 and later. It returns a lowercase string with two hex digits per byte. For uppercase output, you can chain a call:

hex_str_upper = data.hex().upper()
print(hex_str_upper) # 00FF10

For older versions or more control, use the binascii module:

import binascii
raw = bytes([0x1a, 0x2b, 0x3c])
hexl = binascii.hexlify(raw)
print(hexl) # b'1a2b3c'
print(hexl.decode()) # 1a2b3c

Tip: use bytes.hex() for simple cases. Reach for binascii.hexlify when you need a bytes result or work in older environments.

Both approaches are reliable. Choose based on your version, output format, and performance needs.

Converting Hex to Bytes

Often you need to reverse the process. To turn a hex string back into bytes, Python offers a straightforward method:

hex_str = 'deadbeef'
raw = bytes.fromhex(hex_str)
print(list(raw)) # [222, 173, 190, 239]

The bytes.fromhex class method expects a string with an even number of hex digits. If you include spaces between pairs, it still works:

raw2 = bytes.fromhex('de ad be ef')
print(list(raw2)) # [222, 173, 190, 239]

Be cautious when reading hex from user input or files. Always validate the length and content:

if len(hex_str) % 2 != 0:
raise ValueError('Hex string length must be even')

Converting back and forth ensures data integrity when you encode, transmit, then decode binary content.

Performance Considerations

When handling large volumes of bytes, conversion speed can matter. Benchmark with the timeit module:

import timeit
import binascii
setup = 'data = bytes([120] * 1024)'
stmt1 = 'data.hex()'
stmt2 = 'binascii.hexlify(data)'
print(timeit.timeit(stmt1, setup=setup, number=10000))
print(timeit.timeit(stmt2, setup=setup, number=10000))

Results vary by Python version and system, but bytes.hex() is typically optimized in C. Meanwhile, binascii.hexlify may be faster if you avoid an extra decode call.

  • Reuse data buffers where possible
  • Avoid calling hex conversion in tight loops
  • Profile with real-world data sizes

Performance tip: if you only need a bytes result from hexlify, skip the decode step to save cycles.

Understanding performance helps you choose the right method when processing logs, cryptographic hashes, or binary protocols.

Common Use Cases

Converting bytes to hex appears in many areas of development:

  • Debugging network traffic: hex dumps reveal packet contents.
  • Hashing and checksums: digest methods like SHA256 return bytes that you often display as hex.
  • Data serialization: encoding binary in text formats (JSON, XML).
  • File I/O: inspecting binary files before writing or after reading.
  • Encoding-aware conversions: bridge to string operations like binary to string conversion.

In some workflows you may also convert hex back to ints:

value = int.from_bytes(raw, 'big')

For more on that, see the guide on bytes to int conversion.

Tips and Best Practices

To make your hex conversions robust:

  • Validate inputs: check string length and character set.
  • Control case: decide on upper or lower hex and stick with it.
  • Add separators: use a join expression for spaced formats.
  • Reuse buffers: avoid creating new objects in heavy loops.

Always log both raw and hex output in tandem when diagnosing tricky encoding issues.

By following consistent patterns, teammates can read your logs without confusion. Automated tools can then parse predictable hex formats reliably.

Conclusion

Converting bytes to hex in Python is a small but powerful skill. You can use bytes.hex(), binascii.hexlify, and bytes.fromhex to inspect, log, and process data in a readable form. Understanding performance differences and common pitfalls ensures you make the right choice for your project.

Whether you are debugging network packets, generating cryptographic digests, or building data pipelines, knowing how to round-trip between bytes and hex gives you clarity and control. Try these techniques in your next script and see how much smoother your binary data tasks become.


Mateen Kiani
Mateen Kiani
kiani.mateen012@gmail.com
I am a passionate Full stack developer with around 4 years of experience in MERN stack development and 1 year experience in blockchain application development. I have completed several projects in MERN stack, Nextjs and blockchain, including some NFT marketplaces. I have vast experience in Node js, Express, React and Redux.