punycode-rs
A Rust implementation of Punycode (RFC 3492)
— the ASCII-compatible encoding at the heart of Internationalized Domain Names. It turns
Unicode into ASCII and back: münchen ⇄ mnchen-3ya (which IDNA then prefixes as
xn--mnchen-3ya).
The implementation is a faithful port of Python's standard-library punycode codec, and is
verified against it byte-for-byte (encode and decode, including malformed-input handling).
Usage
use ;
assert_eq!;
assert_eq!;
// Pure ASCII gains a trailing '-'.
assert_eq!;
// Decoding malformed input returns an error.
assert!;
Installation
[]
= "0.1"
Requires a Rust toolchain with 2024-edition support (Rust 1.85 or newer).
How it works
Punycode separates a string into its ASCII "base" (kept verbatim) and its non-ASCII characters, then encodes each non-ASCII character as a single integer delta that records both which character it is and where it gets inserted. Deltas are written as base-36 generalized variable-length integers using an adaptive bias that self-tunes for compactness. Decoding mirrors the process exactly. (See RFC 3492 §3.)
Scope
This crate is raw Punycode — the encoding algorithm itself. It does not include the full
IDNA ToASCII/ToUnicode pipeline (the xn-- prefix handling and UTS-46 Unicode mapping),
which layers on top and pulls in large Unicode data tables.
License
Licensed under the MIT License.