Claude Code for binhex: Python BinHex 4.0 Encoding — Claude Skills 360 Blog
Blog / AI / Claude Code for binhex: Python BinHex 4.0 Encoding
AI

Claude Code for binhex: Python BinHex 4.0 Encoding

Published: January 16, 2029
Read time: 5 min read
By: Claude Skills 360

Python’s binhex module (deprecated Python 3.11, removed Python 3.13) encodes and decodes files in the BinHex 4.0 format — a text-safe binary encoding that combines a Macintosh file’s data and resource forks with CRC checksums. import binhex. Encode: binhex.binhex(input_file, output_file) — read input_file path, write .hqx to output_file path. Decode: binhex.hexbin(input_file, output_file) — read .hqx from input_file, write data fork to output_file. Low-level encoder: binhex.BinHex(info_tuple, output_file) → object with .write(data) and .close(); info_tuple = (filename, creator, type, dlen, rlen). Low-level decoder: binhex.HexBin(input_file) → object with .read(n), .read_data(), .read_rsrc(), .close(); .FInfo has .Creator, .Type, .Flags. Exception: binhex.Error — raised on CRC mismatch, truncated data, or unsupported header. BinHex 4.0 encodes binary using a 6-bit alphabet (similar to base64) wrapped in : delimiters and applies run-length compression before encoding. Claude Code generates legacy Mac file archive tools, BinHex stream validators, and binary-to-text encoding pipeline handlers.

CLAUDE.md for binhex

## binhex Stack
- Stdlib: import binhex  (3.11 deprecated, removed 3.13)
- Encode: binhex.binhex("input.bin", "output.hqx")
- Decode: binhex.hexbin("input.hqx", "output.bin")
- Error:  binhex.Error  (CRC fail / bad format)
- Low-level encode:
-   hbx = binhex.BinHex(("filename", "APPL", "TEXT", data_len, 0), outf)
-   hbx.write(data); hbx.close()
- Low-level decode:
-   hbx = binhex.HexBin(infile)
-   data = hbx.read_data(); hbx.close()
- Note:  BinHex 4 = RLE compress → 6-bit encode (like base64) → wrap in ':'

binhex BinHex 4.0 Pipeline

# app/binhexutil.py — encode, decode, roundtrip, inspect, batch, stream validator
from __future__ import annotations

import io
import os
import struct
import tempfile
from dataclasses import dataclass
from pathlib import Path


# Graceful import — removed in Python 3.13
_BINHEX_AVAILABLE = False
try:
    import binhex as _bh
    _BINHEX_AVAILABLE = True
except ImportError:
    pass


# ─────────────────────────────────────────────────────────────────────────────
# 1. High-level encode / decode helpers
# ─────────────────────────────────────────────────────────────────────────────

def encode_file(src: "str | Path", dst: "str | Path | None" = None) -> Path:
    """
    BinHex-encode src to dst (default: src + '.hqx').
    Returns the output path.

    Example:
        out = encode_file("document.rtf")         # → "document.rtf.hqx"
        out = encode_file("image.png", "/tmp/img.hqx")
    """
    if not _BINHEX_AVAILABLE:
        raise RuntimeError("binhex module not available (Python >= 3.13)")
    src = Path(src)
    dst = Path(dst) if dst else src.with_suffix(src.suffix + ".hqx")
    _bh.binhex(str(src), str(dst))
    return dst


def decode_file(src: "str | Path", dst: "str | Path | None" = None) -> Path:
    """
    Decode a BinHex .hqx file to dst (default: strip .hqx extension).
    Returns the output path.

    Example:
        out = decode_file("document.rtf.hqx")     # → "document.rtf"
        out = decode_file("archive.hqx", "/tmp/out.bin")
    """
    if not _BINHEX_AVAILABLE:
        raise RuntimeError("binhex module not available (Python >= 3.13)")
    src = Path(src)
    if dst is None:
        dst = src.with_suffix("") if src.suffix == ".hqx" else src.with_suffix(".bin")
    else:
        dst = Path(dst)
    _bh.hexbin(str(src), str(dst))
    return dst


def encode_bytes(data: bytes,
                 filename: str = "data.bin",
                 file_type: str = "    ",
                 creator: str = "    ") -> bytes:
    """
    BinHex-encode raw bytes in memory.  Returns the .hqx bytes.

    Example:
        hqx = encode_bytes(b"Hello, world!", "hello.txt", "TEXT", "ttxt")
        print(hqx.decode("ascii")[:80])
    """
    if not _BINHEX_AVAILABLE:
        raise RuntimeError("binhex module not available (Python >= 3.13)")
    buf = io.BytesIO()
    info = (filename, creator[:4], file_type[:4], len(data), 0)
    enc = _bh.BinHex(info, buf)
    enc.write(data)
    enc.close()
    return buf.getvalue()


def decode_bytes(hqx: bytes) -> bytes:
    """
    Decode BinHex-encoded bytes and return the data fork as bytes.

    Example:
        data = decode_bytes(encode_bytes(b"Hello!"))
        assert data == b"Hello!"
    """
    if not _BINHEX_AVAILABLE:
        raise RuntimeError("binhex module not available (Python >= 3.13)")
    buf = io.BytesIO(hqx)
    dec = _bh.HexBin(buf)
    data = dec.read_data()
    dec.close()
    return data


# ─────────────────────────────────────────────────────────────────────────────
# 2. Roundtrip check
# ─────────────────────────────────────────────────────────────────────────────

def roundtrip_check(data: bytes) -> bool:
    """
    Encode and immediately decode data; return True if output matches input.

    Example:
        assert roundtrip_check(b"Claude Skills 360")
        assert roundtrip_check(bytes(range(256)))
    """
    if not _BINHEX_AVAILABLE:
        return True   # assume ok if module missing
    try:
        hqx = encode_bytes(data)
        recovered = decode_bytes(hqx)
        return recovered == data
    except Exception:
        return False


# ─────────────────────────────────────────────────────────────────────────────
# 3. BinHex header inspector
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class HqxHeader:
    filename:  str
    file_type: str
    creator:   str
    data_len:  int
    rsrc_len:  int
    ok:        bool
    error:     str = ""


def inspect_hqx(hqx: "bytes | str | Path") -> HqxHeader:
    """
    Parse and return the header info from a BinHex stream without fully
    decoding it. Returns HqxHeader with ok=False and error set on failure.

    Example:
        header = inspect_hqx("archive.hqx")
        print(header.filename, header.file_type, header.data_len)
    """
    if not _BINHEX_AVAILABLE:
        return HqxHeader("", "", "", 0, 0, False, "binhex module not available")
    try:
        if isinstance(hqx, (str, Path)):
            buf: io.IOBase = open(str(hqx), "rb")
        else:
            buf = io.BytesIO(hqx)
        dec = _bh.HexBin(buf)
        fi = dec.FInfo
        name = getattr(dec, "FName", "")
        data_len = getattr(dec, "FDataLen", 0)
        rsrc_len = getattr(dec, "FRsrcLen", 0)
        dec.close()
        return HqxHeader(
            filename=name,
            file_type=fi.Type,
            creator=fi.Creator,
            data_len=data_len,
            rsrc_len=rsrc_len,
            ok=True,
        )
    except Exception as e:
        return HqxHeader("", "", "", 0, 0, False, str(e))


# ─────────────────────────────────────────────────────────────────────────────
# 4. Batch encoder
# ─────────────────────────────────────────────────────────────────────────────

def encode_directory(src_dir: "str | Path",
                     dst_dir: "str | Path | None" = None,
                     pattern: str = "*") -> list[tuple[Path, Path]]:
    """
    BinHex-encode all matching files in src_dir, writing .hqx to dst_dir.
    Returns list of (src, dst) pairs for successfully encoded files.

    Example:
        pairs = encode_directory("mac_files/", "hqx_out/", pattern="*.bin")
        for src, dst in pairs:
            print(f"  {src.name} → {dst.name}")
    """
    src_dir = Path(src_dir)
    dst_dir = Path(dst_dir) if dst_dir else src_dir / "hqx"
    dst_dir.mkdir(parents=True, exist_ok=True)
    results: list[tuple[Path, Path]] = []
    for src in src_dir.glob(pattern):
        if not src.is_file():
            continue
        dst = dst_dir / (src.name + ".hqx")
        try:
            encode_file(src, dst)
            results.append((src, dst))
        except Exception:
            pass
    return results


# ─────────────────────────────────────────────────────────────────────────────
# 5. BinHex stream validator
# ─────────────────────────────────────────────────────────────────────────────

def validate_hqx_stream(hqx: bytes) -> tuple[bool, str]:
    """
    Validate a BinHex stream by attempting a full decode. Returns
    (True, "") on success or (False, error_message) on failure.

    Example:
        ok, msg = validate_hqx_stream(encode_bytes(b"test"))
        assert ok
        ok, msg = validate_hqx_stream(b"(corrupted)")
        assert not ok
    """
    if not _BINHEX_AVAILABLE:
        return True, ""
    try:
        buf = io.BytesIO(hqx)
        dec = _bh.HexBin(buf)
        dec.read_data()
        dec.read_rsrc()
        dec.close()
        return True, ""
    except _bh.Error as e:
        return False, str(e)
    except Exception as e:
        return False, str(e)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== binhex demo ===")
    print(f"  binhex available: {_BINHEX_AVAILABLE}")

    if not _BINHEX_AVAILABLE:
        print("  (Python >= 3.13: binhex was removed)")
        print("  Use base64 module for binary-to-text encoding instead.")
    else:
        # ── encode_bytes / decode_bytes ───────────────────────────────────────
        print("\n--- encode_bytes / decode_bytes ---")
        test_data = b"Claude Skills 360 — BinHex test payload\x00\x01\x02\xff"
        hqx = encode_bytes(test_data, "test.bin", "TEXT", "CLAS")
        print(f"  original  : {len(test_data)} bytes")
        print(f"  encoded   : {len(hqx)} bytes  ({len(hqx)/len(test_data):.1f}x)")
        decoded = decode_bytes(hqx)
        print(f"  decoded   : {len(decoded)} bytes")
        print(f"  match     : {decoded == test_data}")
        print(f"  hqx preview: {hqx[:80].decode('ascii', errors='replace')!r}")

        # ── roundtrip_check ───────────────────────────────────────────────────
        print("\n--- roundtrip_check ---")
        for payload in [b"", b"x", bytes(range(256)), b"A" * 1024]:
            ok = roundtrip_check(payload)
            print(f"  {len(payload):5d} bytes: {'OK' if ok else 'FAIL'}")

        # ── inspect header ────────────────────────────────────────────────────
        print("\n--- inspect_hqx header ---")
        hdr = inspect_hqx(encode_bytes(b"hello", "readme.txt", "TEXT", "MSWD"))
        print(f"  filename  = {hdr.filename!r}")
        print(f"  file_type = {hdr.file_type!r}")
        print(f"  creator   = {hdr.creator!r}")
        print(f"  data_len  = {hdr.data_len}")
        print(f"  ok        = {hdr.ok}")

        # ── validate_hqx_stream ───────────────────────────────────────────────
        print("\n--- validate_hqx_stream ---")
        good_hqx = encode_bytes(b"good data", "g.bin")
        ok, msg = validate_hqx_stream(good_hqx)
        print(f"  good stream: ok={ok}  msg={msg!r}")
        ok, msg = validate_hqx_stream(b"(this is not valid binhex)")
        print(f"  bad stream:  ok={ok}  msg={msg!r}")

        # ── file-based encode / decode ────────────────────────────────────────
        print("\n--- file encode/decode ---")
        with tempfile.TemporaryDirectory() as tmpdir:
            src = os.path.join(tmpdir, "payload.bin")
            hqx_path = os.path.join(tmpdir, "payload.bin.hqx")
            out = os.path.join(tmpdir, "recovered.bin")
            original = bytes(range(128)) * 4
            open(src, "wb").write(original)
            encode_file(src, hqx_path)
            decode_file(hqx_path, out)
            recovered = open(out, "rb").read()
            print(f"  encoded size : {os.path.getsize(hqx_path)} bytes")
            print(f"  match        : {recovered == original}")

    print("\n=== done ===")

For the base64 stdlib replacement — base64.b64encode(data) and base64.b64decode(s) provide the modern, cross-platform binary-to-text encoding used in MIME email, JSON, and HTTP — use base64 for all new code; BinHex 4.0 was a Macintosh-specific format from the 1980s–90s and the binhex module was removed in Python 3.13. For the binascii stdlib alternative — binascii.b2a_hqx(data) and binascii.a2b_hqx(data) expose the raw BinHex 4.0 6-bit codec at the per-chunk level used internally by binhex — use binascii if you need low-level per-block HQX encoding/decoding without the full file envelope (headers, run-length compression, CRC); use binhex for complete .hqx file compliance when working with legacy Macintosh archives on Python ≤ 3.11. The Claude Skills 360 bundle includes binhex skill sets covering encode_file()/decode_file() path helpers, encode_bytes()/decode_bytes() in-memory codecs, roundtrip_check() verifier, inspect_hqx()/HqxHeader dataclass header parser, encode_directory() batch encoder, and validate_hqx_stream() integrity checker. Start with the free tier to try BinHex encoding patterns and binhex pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free