Skip to main content

Pythonic conversion toolkit for bytes, hex, integers, arrays, binary strings, base64, and text.

Project description

hexconv

hexconv is a small, dependency-free Python toolkit for converting between bytes, hex, integers, arrays, binary strings, base encodings, escaped strings, hexdumps, structs, bits, and text.

It is built around ergonomic one-liners and composable format objects.

Install

pip install hexconv

Fast compose

The intended interface is small pieces snapped together: source format >> optional transforms >> target format.

import hexconv as hx

to_bytes = hx.Hex() >> hx.Bytes()
to_bytes("de ad be ef")
# b'\xde\xad\xbe\xef'

spaced_hex = hx.Bytes() >> hx.Hex(sep=" ")
spaced_hex(b"\xde\xad\xbe\xef")
# 'de ad be ef'

words = hx.Hex(sep=" ") >> hx.Chunk(2) >> hx.IntArray(width=2)
words("12 34 56 78")
# [4660, 22136]

text_to_urlsafe = hx.Text() >> hx.Base64(urlsafe=True, padding=False)
text_to_urlsafe("data")
# 'ZGF0YQ'

Hex input accepts common separators, so spaced or copied hex usually does not need manual cleanup before conversion. Hex(sep=" ") is also how you emit space-separated hex.

Quick tour

Use direct helpers when you want one obvious conversion across many representations:

hx.from_hex("de ad be ef").bytes
# b'\xde\xad\xbe\xef'

hx.from_text("data").to_hex_array(prefix=True)
# ['0x64', '0x61', '0x74', '0x61']

hx.from_int(0xdeadbeef).bytes
# b'\xde\xad\xbe\xef'

hx.from_int_array([0x1234, 0x5678], width=2).to_hex_array(width=2)
# ['1234', '5678']

hx.from_binary("01100100 01100001 01110100 01100001").text
# 'data'

hx.from_base64("ZGF0YQ==").text
# 'data'

hx.from_escaped(r"\xde\xad").hex
# 'dead'

hx.from_struct((0x1234, 0x5678), fmt=">HH").hex
# '12345678'

hx.from_bits("101", pad=True).hex
# '05'

Use from_auto when you want a quick best-effort parse:

hx.from_auto("0xdeadbeef").bytes
# b'\xde\xad\xbe\xef'

hx.from_auto(b"\xde\xad").hex
# 'dead'

hx.from_auto([0xde, 0xad, 0xbe, 0xef]).to(hx.Hex(prefix=True))
# '0xdeadbeef'

Composable interface

hexconv is built around small format objects. A format can parse directly:

hx.Hex()("de ad be ef").bytes
# b'\xde\xad\xbe\xef'

hx.Text()("data").hex
# '64617461'

hx.Int(width=4, endian="little")(0x12345678).hex
# '78563412'

Formats compose with >>, so reusable converters are normal Python objects:

to_text = hx.HexArray() >> hx.Text()
to_text([0x48, 0x65, 0x6C, 0x6C, 0x6F])
# 'Hello'

to_hex = hx.Text() >> hx.Hex(prefix=True)
to_hex("data")
# '0x64617461'

Transforms sit between formats when data needs shaping:

words = hx.Hex() >> hx.Chunk(2) >> hx.IntArray(width=2)
words("12345678")
# [4660, 22136]

reverse_hex = hx.Hex() >> hx.Reverse() >> hx.Hex()
reverse_hex("deadbeef")
# 'efbeadde'

pad_hex = hx.Hex() >> hx.Pad.left(width=4) >> hx.Hex()
pad_hex("dead")
# '0000dead'

Use the builder form when named steps read better:

conv = (
    hx.pipeline()
    .from_(hx.Hex())
    .chunk(2)
    .to(hx.HexArray(prefix=True))
)

conv("12345678")
# ['0x1234', '0x5678']

Configurable one-shot conversions

Use convert when you want an explicit source and target in one expression:

hx.convert("de ad be ef", hx.Hex(sep=" "), hx.Bytes())
# b'\xde\xad\xbe\xef'

hx.convert(b"\xde\xad\xbe\xef", hx.Bytes(), hx.Hex(sep=" "))
# 'de ad be ef'

hx.convert("data", hx.Text(), hx.Hex(prefix=True))
# '0x64617461'

hx.convert("π", hx.Text(encoding="utf-8"), hx.Hex())
# 'cf80'

hx.convert("-_8", hx.Base64(urlsafe=True, padding=False), hx.Hex())
# 'fbff'

Hex strings may include common separators, so you do not need to manually strip spaces, colons, dashes, or 0x prefixes before converting.

Common conversion patterns

Text, bytes, and hex:

hx.Text()("hello").bytes
# b'hello'

hx.Hex()("68656c6c6f").text
# 'hello'

hx.BytesArray()([0x68, 0x69]).to(hx.Text())
# 'hi'

Integer packing:

hx.Int(width=2)(0x1234).hex
# '1234'

hx.Int(width=2, endian="little")(0x1234).hex
# '3412'

(hx.Hex() >> hx.Chunk(2) >> hx.IntArray(width=2))("12345678")
# [4660, 22136]

Base encodings:

hx.Text()("data").to(hx.Base64())
# 'ZGF0YQ=='

hx.Text()("data").to(hx.Base32(padding=False))
# 'MRQXIYI'

hx.Base64(urlsafe=True, padding=False)("-_8").hex
# 'fbff'

Escaped strings, hexdumps, structs, and bits:

hx.Escaped()(r"\xde\xad").hex
# 'dead'

dump = hx.Hex()("deadbeef").to(hx.Hexdump(width=2))
hx.Hexdump()(dump).hex
# 'deadbeef'

hx.Struct(">HH")((0x1234, 0x5678)).hex
# '12345678'

hx.Hex()("12345678").to(hx.Struct(">HH"))
# (4660, 22136)

hx.Bits()([1, 0, 1]).hex
# '05'

Why explicit formats?

Some values are genuinely ambiguous:

"face"

That can mean raw text:

hx.Text()("face").hex
# '66616365'

or hex bytes:

hx.Hex()("face").bytes
# b'\xfa\xce'

hexconv keeps the recommended path explicit so conversions are predictable. If you want convenience heuristics, use from_auto:

hx.from_auto("0xdead").hex
# 'dead'

If you want to see what from_auto would infer, use infer:

result = hx.infer("0xdead")

result.value.hex
# 'dead'

result.reason
# '0x-prefixed hex string'

from_auto(..., explain=True) returns the same explanation object:

result = hx.from_auto("0b101", explain=True)

result.value.hex
# '05'

Design priorities

  • Easy: obvious conversions stay one-liners.
  • Composable: reusable converters are just format >> transform >> format.
  • Flexible: configure endianness, width, padding, grouping, text encoding, and base encodings where needed.
  • Fast and lightweight: no runtime dependencies, bytes-native internals, and direct use of Python's optimized bytes, int, base64, and struct primitives.

Format objects

Format objects are both parsers and pipeline endpoints.

value = hx.Hex()("deadbeef")
value.to(hx.Int())
# 3735928559

conv = hx.Hex() >> hx.Int()
conv("deadbeef")
# 3735928559

Available format specs:

  • Bytes()
  • BytesArray()
  • BytesString()
  • Hex()
  • HexArray()
  • HexInt() / LargeHexNumber()
  • Int()
  • IntArray()
  • Text()
  • Binary()
  • Base64()
  • Base32()
  • Base85()
  • Ascii85()
  • Escaped()
  • Hexdump()
  • Struct(fmt)
  • Bits()

Transforms

Transforms are byte-to-byte steps that sit between input and output formats.

hx.Hex() >> hx.Chunk(2) >> hx.HexArray()
hx.Hex() >> hx.Group(2) >> hx.IntArray(width=2)
hx.Hex() >> hx.Pad.left(width=8) >> hx.Hex()
hx.Hex() >> hx.Pad.right(block_size=8, byte=0xFF) >> hx.Hex()
hx.Hex() >> hx.Reverse() >> hx.Hex()

Current transforms:

  • Chunk(width, strict=True) — set downstream grouping width.
  • Group(width, strict=True) — alias for Chunk.
  • Pad.left(width=..., block_size=..., byte=0) — left-pad bytes.
  • Pad.right(width=..., block_size=..., byte=0) — right-pad bytes.
  • Reverse() — reverse byte order.

Classic helper API

The original helper style is still supported:

hx.from_hex("dead beef").bytes
# b'\xde\xad\xbe\xef'

hx.from_text("data").hex
# '64617461'

hx.convert("data", from_=hx.Text, to=hx.HexString)
# '64617461'

Source helpers:

  • from_bytes(value)
  • from_bytes_array(values)
  • from_bytes_string(value)
  • from_hex(value)
  • from_hex_array(values)
  • from_hex_int(value)
  • from_int(value)
  • from_int_array(values, width=...)
  • from_text(value)
  • from_binary(value)
  • from_base64(value)
  • from_base32(value)
  • from_base85(value)
  • from_ascii85(value)
  • from_escaped(value)
  • from_hexdump(value)
  • from_struct(value, fmt=...)
  • from_bits(value)
  • from_auto(value)
  • infer(value)

Common Value outputs:

  • to_bytes()
  • to_bytearray()
  • to_bytes_array()
  • to_bytes_string()
  • to_hex(sep="", prefix=False, uppercase=False)
  • to_hex_array(width=1, prefix=False, uppercase=False)
  • to_hex_numbers(width=1)
  • to_int(endian="big", signed=False)
  • to_int_array(width=1, endian="big", signed=False)
  • to_text(encoding="ascii", errors="strict")
  • to_binary(sep="")
  • to_base64()
  • to_base32()
  • to_base85()
  • to_ascii85()
  • to_escaped()
  • to_hexdump()
  • to_struct(fmt)
  • to_bits()
  • to(format_spec)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hexconv-0.2.4.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hexconv-0.2.4-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file hexconv-0.2.4.tar.gz.

File metadata

  • Download URL: hexconv-0.2.4.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for hexconv-0.2.4.tar.gz
Algorithm Hash digest
SHA256 fe73106eac02cc0686350278a881bf405612fcf1f918449359f889f9850f4367
MD5 a7a0bf9be8490bad8ecc67acd259108a
BLAKE2b-256 7c11ba269fdcca0c4dfe7cc42034ba48cdd062202bc83fd765a27297cfb2632a

See more details on using hashes here.

File details

Details for the file hexconv-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: hexconv-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for hexconv-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 23aa3098983dde4a9a7c068d5753e81d0255a237dd2f7018a5d4e94c2ae0872a
MD5 d995200c8eb627da0738c443978e418c
BLAKE2b-256 5c7fbcc470f3dc41f49d12089cce488c8090fdc9a2ead1de9efe8113e4f87366

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page