Punycode è un sistema di codifica definito nella RFC 3492 che serve a rappresentare univocamente una sequenza di caratteri unicode tramite una sequenza di caratteri ASCII, per rendere possibile l'uso di tali sequenze nei nomi di dominio, senza dover modificare infrastrutture e standard esistenti. In questo modo si possono gestire nomi di dominio internazionalizzati (IDNA) aggiungendo all'inizio della stringa punycode i caratteri 'xn--'.
La traduzione di sequenze Punycode nella codifica originaria è a carico dello user agent.
L'algoritmo non è semplicissimo, tuttavia può essere ricondotto a operazioni di base elementari, oltre ad essere facilmente implementabile e versatile. Gli elementi principali sono i seguenti:
Un esempio può essere dato da totò trascodificato in tot-ena.
Per capire il cuore dell'algoritmo dovremo soffermarci sul terzo punto. La sequenza alfanumerica dopo quel trattino solitario in realtà rappresenta uno o più numeri, chiamati delta, ognuno associato alla presenza di un carattere Unicode all'interno della stringa. L'ordine dei delta inseriti segue quello dei codici Unicode e non quello della posizione dei caratteri nella stringa iniziale.
Nel caso in questione, ad esempio, la stringa ena rappresenta la presenza della ò in 4ª posizione, ma a causa dell'algoritmo usato (in cui entrano in gioco la lunghezza della stringa, i caratteri già inseriti, e altri parametri) potrebbe significare anche un altro codice unicode in un'altra posizione.
Soffermandoci adesso sul singolo delta, esso:
Inoltre, cosa più importante, il delta rappresenta contemporaneamente sia il codice Unicode da inserire all'interno della stringa ASCII che la sua posizione.
Inoltre, dato <n,i> un particolare stato dove n è il codice di un carattere da inserire (anzi, lo scostamento rispetto ad un valore base) e i è la posizione di inserimento, i è vincolato a crescere fino alla lunghezza complessiva della stringa, per poi tornare a 0 e incrementare n di 1; dato i=0, la sequenza degli stati sarà simile a questa: <n,i>,<n,i+1>....<n,L>,<n+1,i>,<n+1,i+1>..... Il valore numerico del delta è definito come numero di stati precedenti a uno stato di inserimento.
In pratica, dato un certo delta, dividendolo per la lunghezza della stringa base +1, si ottiene come resto la posizione in cui inserire il carattere unicode (posizione che varia da 0 (inizio) a L (fine)), e come quoziente lo scostamento del valore unicode rispetto a un valore base (fissato inizialmente, per comodità, a 128).
I threshold sono calcolati digit per digit e rappresentano all'interno di ognuno di questi il numero di possibili caratteri-segnalatori della fine del delta, a partire da quello con valore più basso, la 'a' appunto. In particolare per calcolare il threshold di un singolo digit si avrà la formula: t(j)=base*(j+1)-bias
dove j è il numero di digit considerato (a partire da 0), base è appunto 36, e bias è un valore che inizialmente è posto a 72, ma che successivamente viene variato al passaggio da un delta all'altro in base ad una particolare formula. t(j) inoltre viene vincolato a essere compreso tra un tmin=1 e un tmax=26. Per raggiungere tale scopo, se per qualche motivo t(j) scende sotto tmin, viene posto t(j)=tmin e se t(j) va sopra tmax verrà posto t(j)=tmax
Essendo inoltre i caratteri definiti dai threshold dei segnalatori, essi influenzano indirettamente anche il peso di ogni digit, calcolato con la seguente formula:
Detto in forma più comprensibile, il peso di ogni digit non sarà semplicemente la base^j bensì (base-t(0))*(base-t(1))....*(base-t(n))
Ogni codifica di un delta successivo occorre:
Tornando al nostro totò (tot-ena) sarà facile adesso capire che per mettere la o accentata nella posizione precedente (toòt) basterà sottrarre al delta 1, e ricordando che esso è little-endian si deve modificare la sua prima lettera (e), ovverosia: (tot-dna).
Ponendo la ò accentata ancora prima tòot, la trascodifica sarà xn--tot-cna ('c'='e'-2) e nel caso di òtot, tot-bna ('b'='e'-3)
Ritornando ora a totò, con codifica tot-ena, se vogliamo aggiungere uno stato al delta, siccome abbiamo già raggiunto la fine della stringa, il carattere unicode assumerà il valore successivo (la o accentata al contrario ó) e l'indice i si azzererà come previsto, ponendosi all'inizio. ótot avrà insomma codifica tot-fna ('f'='e'+1)