# Punycode

Punycode (codi puny, en anglès, petit, insignificant) és una sintaxi de codificació usada en programació per a representar una cadena Unicode utilitzant només caràcters del joc ASCII bàsic i, per tant, és compatible amb el DNS. Punycode està pensat per a la codificació d'etiquetes en el marc d'IDNA (inicials de noms de dominis internacionalitzats en anglès). La sintaxi està definida en el document RFC 3492.

## Procediment de codificació

Està secció demostra el procediment per a la codificació Punycode mostrant com la cadena "bücher" (llibres, en alemany) es converteix en "bcher-kva".

### Separació de caràcters ASCII

Primer es copien tots els caràcters ASCII directament des de l'entrada a la sortida saltant els altres caràcters (per exemple: "bücher" → "bcher"). Si s'ha copiat algun caràcter dels bàsics, s'afegeix un guió en ASCII al final de la cadena (és a dir: "bücher" → "bcher-"). El guió, que és un caràcter bàsic pot aparèixer a la cadena abans d'aquest guió addicional, però això no provoca ambigüitat: no hi ha cap fase posterior del procés que n'afegeixi cap més i, per tant, l'últim guió (si n'hi ha) sempre és el que marca el final dels caràcters bàsics.

### Codificació d'inserció de caràcters no-ASCII com a codis numèrics

Per entendre la part següent del procés de codificació necessitem comprendre primer com funciona el descodificador, el mateix és una màquina d'estat amb dues variables d'estat, i i n. i és un índex dins del rang de la cadena que pot anar des de zero (per representar una possible inserció al començament) fins a la longitud actual de la cadena estesa (per representar una possible inserció al final).
i comença en zero mentre que "n" 'comença a 128 (el primer caràcter no-ASCII). La progressió de l'estat és una funció monòtona. Quan hi ha un canvi d'estat, s'incrementa i, o bé si ja està en el valor màxim el reseteja a "0" i incrementa "n". A cada canvi d'estat, el punt de codi assenyalat per "n" s'insereix o no.
Els nombres de codi generats pel codificador representen quantes possibilitats s'ha de saltar el descodificador abans de fer una inserció. "ü" correspon al punt de codi 252. Per tant, abans que tinguem la possibilitat d'inserir ü a la posició 1, cal saltar sis ("bcher" té cinc caràcters i, per tant, s'hi poden inserir caràcters en sis posicions diferents) insercions possibles dels 124 punts de codi no-ASCII precedents (124 = 252 − 128, el límit superior d'ASCII) i una inserció possible (la de la posició zero) del punt de codi 252. Per això cal dir-li al descodificador que se salti un total de (6 × 124) + 1 = 745 insercions possibles abans d'arribar a la que cal.

### Recodificació de codis numèrics com a seqüències de codis ASCII

Punycode usa sencers de longitud variable generalitzats per representar aquests valors. Per exemple, el codi numèric es representa com a "kva":
    S'utilitza un sistema numèric little-endian, que permet codis de longitud variable sense delimitadors separats: un dígit menor que un llindar determinat marca que és el dígit més significatiu, i per tant, el final del nombre. El valor del llindar depèn de la posició dins del nombre, i també de les insercions precedents, per augmentar l'eficiència. Com a conseqüència, els pesos dels dígits poden variar.
    En aquest cas, s'utilitza un sistema numèric de 36 dígits, on les lletres (indistintament majúscules o minúscules) de l'a a la z representen els nombres 0 a 25, i els dígits 0 a 9, equivalen als nombres 26 a 35. Per tant, "kva" correspon a "10 21 0" (k és l'onzena lletra, però comencem a comptar des de zero, igualment amb la v, que és la vint-i-dosena).
Per descodificar aquesta cadena de dígits, el llindar comença com a 1 i el pes és d'1. El primer dígit és el de les unitats, 10 amb un pes d'1 és igual a 10. Després d'això, el valor llindar s'ajusta. En nom de la simplicitat, assumim que és ara 2. La segona xifra té un pes de 36 menys el valor llindar anterior (1), per tant 35. Per tant, la suma dels dos primers dígits és de 10 × 1 + 21 × 35. Com que el segon "dígit" no és menor que el valor llindar de 2, encara en queda. El pes del tercer dígit és el pes anterior, multiplicat per 36 menys el nou valor llindar, és a dir 35 × 34. El tercer dígit en aquest exemple és 0, que és inferior al 2, el que significa que és l'últim dígit (i el més significatiu) del nombre. Per tant, "kva" representa el nombre 10 × 1 + 21 × 35 + 0 × 35 × 34 = 745.
El llindar el determina un algorisme que el manté sempre entre 1 i 26 (ambdós inclusius). Això garanteix que l'últim caràcter d'una codificació sigui sempre alfabètic. Llavors es pot utilitzar en majúscula o minúscula, per donar informació sobre la capitalització del caràcter original.
Per a la inserció d'un segon caràcter especial en "bücher", la primera possibilitat és "büücher" amb el codi "bcher-kvaa", el segon "bücüher" amb el codi "bcher-kvab", etc. Després de "bücherü" amb el codi "bcher-kvae" ve "ýbücher" amb el codi "bcher-kvaf". "übücher" seria "bcher-jvab".
Per a mantenir la simplicitat dels algorismes de codificació i descodificació, no s'ha previst que s'impedeixi de codificar valors Unicode inadmissibles: però, aquests han de ser controlats i detectats durant la descodificació.
Compareu l'ASCII 'Punycode' presentat a xn--tdali-d8a8w.lv que inclou la representació Unicode de la cadena escrita en idioma letó "amb una u macron", i amb "ena trencada ", en lloc de la base de caràcters sense marcar: tūdaliņ.lv

## Requeriments per utilitzar Punycode

Punycode està dissenyat per treballar amb tots els sistemes d'escriptura, i per autooptimitzar-se, tractant d'adaptar-se als rangs del joc de caràcters utilitzat a la cadena mentre va funcionant. Està optimitzat per al cas que la cadena es compongui de zero o més caràcters ASCII i a més caràcters de només un altre sistema d'escriptura, però pot codificar qualsevol cadena arbitrària Unicode. Tingueu en compte que per al cas del DNS, la cadena del nom de domini se suposa que ha estat normalitzada utilitzant Nameprep i (per als dominis de primer nivell) filtrada amb una taula d'idioma registrada oficialment abans de passar-se a Punycode, i que el protocol DNS fixa límits en les longituds acceptables de la cadena Punycode de sortida.

## Referències

* ↑ A Bootstring encoding of Unicode for Internationalized Domain names in Applications (IDNA)

## Enllaços externs (en anglès)

* Conversor UTF-8 a Punycode Arxivat 2014-11-29 a Wayback Machine.
* RFC 3492
* Punycode encoding and decoding Arxivat 2008-05-18 a Wayback Machine.
* Punycode converter
* Online Punycode/IDN Decoder/Encoder
* IDN Library-Libidn
* ICU IDNA Demonstration An online Demonstration of how ICU performs IDN operations
* for Domains Convert Unicode to Punycode
* List of TLDs consideri by the Mozilla developers to have an effective anti-spoofing policy for name registration
* IDN and Punycode in IE7
* converter for Korean