IDN domain converter (Unicode <-> punycode), auto-detects direction per label
Find a file
raf a4e3fd8f7c idn-convert v0.1.0 — IDN domain converter, auto-detects direction per label
Extracted from raf/scripts (commit ff1ac29) into its own repo per loop task 268.
Uses idna 3.x (IDNA 2008) via the shared /home/raf/scripts/.venv shebang shim;
README documents how to retarget the shebang for portable use.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:43:00 +02:00
idn-convert.py idn-convert v0.1.0 — IDN domain converter, auto-detects direction per label 2026-05-20 10:43:00 +02:00
README.md idn-convert v0.1.0 — IDN domain converter, auto-detects direction per label 2026-05-20 10:43:00 +02:00

idn-convert

Internationalized Domain Name converter. Auto-detects direction per label — Unicode → ASCII punycode, or ASCII punycode → Unicode.

Usage

# CLI args
./idn-convert.py müller.de xn--mller-kva.de

# stdin (one domain per line; blank lines and # comments skipped)
printf 'café.fr\nxn--caf-dma.fr\n' | ./idn-convert.py

Detection (per label, not per domain)

Label looks like Action Example
starts with xn-- decode to Unicode xn--mller-kva.demüller.de
has any non-ASCII codepoint encode to ASCII bücher.example.comxn--bcher-kva.example.com
plain ASCII, no xn-- left as-is example.comexample.com

Mixed-label domains are handled correctly — detection is per label.

Errors

Invalid A-labels surface as <input>\tERROR: <reason> on stderr; the process exits non-zero. Valid lines still print to stdout.

Dependency / shim

Single dependency: idna (IDNA 2008). The shipped shebang points at a shared venv on ps1raf:

#!/home/raf/scripts/.venv/bin/python3

For portable use, rewrite the shebang or install idna into your env:

pip install idna && sed -i '1c#!/usr/bin/env python3' idn-convert.py

Why not stdlib

Python's encodings.idna (stdlib) implements IDNA 2003, which mishandles ß, ZWJ, and other codepoints. The third-party idna package implements IDNA 2008/UTS-46.

Forgejo

https://ps1raf.tn.ps1.at:3300/raf/idn-convert