punycode
Punycode encoding/decoding library.
Punycode represents Unicode text using only the ASCII letters, digits and hyphen ([a-z0-9-]), it is used by IDNA to store internationalized domain names in DNS, where each encoded label is marked with the ACE prefix "xn--".
punycode.pack/punycode.unpackwork on a single label given as code points.punycode.encode/punycode.decodework on a whole UTF-8 domain, label by label.
Only the Punycode transform itself is implemented, IDNA mapping and normalization (lowercasing, NFC, disallowed characters) are left to the caller.
Functions
punycode.decode | Decodes an ASCII (Punycode) domain name into UTF-8. |
punycode.encode | Encodes a UTF-8 domain name into its ASCII (Punycode) form. |
punycode.pack | Encodes a single label, given as Unicode code points, into Punycode. |
punycode.unpack | Decodes a single Punycode label into Unicode code points. |
#punycode.decode
function punycode.decode(punycode_str: string, ignore_prefix?: boolean, start_position?: integer, end_position?: integer, lax?: boolean): string | nil, nil | string
Decodes an ASCII (Punycode) domain name into UTF-8.
The string is split on "." and every label starting with "xn--" (case-insensitive) is decoded with punycode.unpack, other labels are left untouched.
punycode.decode( "xn--mnchen-3ya.de" ) -- "münchen.de"
punycode.decode( "mnchen-3ya", true ) -- "münchen"
punycode.decode( "xn--b.de" ) -- nil, "invalid input exception occurred"Invalid UTF-8 in labels without the prefix raises an error, unless lax is true.
| Name | Type | Description |
|---|---|---|
punycode_str | string | The domain name to decode. |
ignore_prefixoptional | boolean | If true, every label is decoded as Punycode without looking for the "xn--" prefix. |
start_positionoptional | integer | The position to start from in bytes, negative values count from the end. |
end_positionoptional | integer | The position to end at in bytes, negative values count from the end. |
laxoptional | boolean | If true, malformed labels are decoded leniently and invalid code points become U+FFFD instead of being rejected. |
| Type | Name | Description |
|---|---|---|
string | nil | str | The decoded UTF-8 domain name, nil if an error occurred. |
nil | string | err_msg | The error message, nil if no error occurred. |
#punycode.encode
function punycode.encode(str: string, ignore_prefix?: boolean, start_position?: integer, end_position?: integer, lax?: boolean): string | nil, nil | string
Encodes a UTF-8 domain name into its ASCII (Punycode) form.
The string is split on "." and every label containing non-ASCII characters is encoded with punycode.pack, ASCII-only labels and empty labels are left untouched.
punycode.encode( "münchen.de" ) -- "xn--mnchen-3ya.de"
punycode.encode( "bücher.example.рф" ) -- "xn--bcher-kva.example.xn--p1ai"
punycode.encode( "münchen.de", true ) -- "mnchen-3ya.de"Invalid UTF-8 raises an error, unless lax is true.
| Name | Type | Description |
|---|---|---|
str | string | The UTF-8 domain name to encode. |
ignore_prefixoptional | boolean | If true, encoded labels are not prefixed with "xn--". |
start_positionoptional | integer | The position to start from in bytes, negative values count from the end. |
end_positionoptional | integer | The position to end at in bytes, negative values count from the end. |
laxoptional | boolean | If true, invalid UTF-8 sequences become U+FFFD and surrogates are encoded as well instead of being rejected. |
| Type | Name | Description |
|---|---|---|
string | nil | punycode_str | The encoded domain name, nil if an error occurred. |
nil | string | err_msg | The error message, nil if no error occurred. |
#punycode.pack
function punycode.pack(codepoints: integer[], codepoint_count?: integer, ignore_prefix?: boolean, lax?: boolean): string | nil, nil | string
Encodes a single label, given as Unicode code points, into Punycode.
A label made of basic (ASCII) code points only is returned as is, without the "xn--" prefix or the trailing "-" delimiter, the way IDNA treats such labels.
Basic code points keep their case, the encoded digits are always lowercase.
punycode.pack( { 0x6D, 0xFC, 0x6E, 0x63, 0x68, 0x65, 0x6E } ) -- "xn--mnchen-3ya"
punycode.pack( { 0x6D, 0xFC, 0x6E, 0x63, 0x68, 0x65, 0x6E }, nil, true ) -- "mnchen-3ya"
punycode.pack( { 0x61, 0x62, 0x63 } ) -- "abc"| Name | Type | Description |
|---|---|---|
codepoints | integer[] | The code points of the label to encode. |
codepoint_countoptional | integer | The number of code points to encode, defaults to the length of codepoints. |
ignore_prefixoptional | boolean | If true, the "xn--" prefix is not prepended to the result. |
laxoptional | boolean | If true, surrogates (U+D800 - U+DFFF) and code points above U+10FFFF are encoded as well instead of being rejected. |
| Type | Name | Description |
|---|---|---|
string | nil | punycode_str | The Punycode string, nil if an error occurred. |
nil | string | err_msg | The error message, nil if no error occurred. |
#punycode.unpack
function punycode.unpack(punycode_str: string, ignore_prefix?: boolean, lax?: boolean): integer[] | nil, integer | nil, nil | string
Decodes a single Punycode label into Unicode code points.
Unless ignore_prefix is true, the label must start with the "xn--" prefix (case-insensitive), a label without it is treated as plain UTF-8 and returned as is.
Encoded digits are case-insensitive, basic code points are copied without case changes.
punycode.unpack( "xn--mnchen-3ya" ) -- { 0x6D, 0xFC, 0x6E, 0x63, 0x68, 0x65, 0x6E }, 7
punycode.unpack( "mnchen-3ya", true ) -- { 0x6D, 0xFC, 0x6E, 0x63, 0x68, 0x65, 0x6E }, 7
punycode.unpack( "xn--b" ) -- nil, nil, "invalid input exception occurred"Invalid UTF-8 in a label without the prefix raises an error, unless lax is true.
| Name | Type | Description |
|---|---|---|
punycode_str | string | The Punycode label to decode. |
ignore_prefixoptional | boolean | If true, punycode_str is decoded as Punycode without looking for the "xn--" prefix. |
laxoptional | boolean | If true, non-ASCII bytes before the delimiter, surrogates and code points above U+10FFFF are accepted instead of being rejected. |
| Type | Name | Description |
|---|---|---|
integer[] | nil | codepoints | The decoded code points, nil if an error occurred. |
integer | nil | codepoint_count | The number of decoded code points, nil if an error occurred. |
nil | string | err_msg | The error message, nil if no error occurred. |