IDN domain converter (Unicode <-> punycode), auto-detects direction per label
- Python 100%
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> |
||
|---|---|---|
| idn-convert.py | ||
| README.md | ||
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.de → müller.de |
| has any non-ASCII codepoint | encode to ASCII | bücher.example.com → xn--bcher-kva.example.com |
plain ASCII, no xn-- |
left as-is | example.com → example.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.