stringtranslate.com

código puny

Punycode es una representación de Unicode con el subconjunto limitado de caracteres ASCII utilizado para los nombres de host de Internet . Con Punycode, los nombres de host que contienen caracteres Unicode se transcodifican a un subconjunto de ASCII que consta de letras, dígitos y guiones, que se denomina subconjunto letra, dígito y guión (LDH). Por ejemplo, München ( nombre alemán de Munich ) está codificado como Mnchen-3ya .

Si bien el Sistema de nombres de dominio (DNS) técnicamente admite secuencias arbitrarias de octetos en las etiquetas de nombres de dominio, los estándares DNS recomiendan el uso del subconjunto LDH de ASCII utilizado convencionalmente para nombres de host y requieren que las comparaciones de cadenas entre nombres de dominio DNS se realicen entre mayúsculas y minúsculas. insensible. La sintaxis Punycode es un método para codificar cadenas que contienen caracteres Unicode, como nombres de dominio internacionalizados (IDNA), en el subconjunto LDH de ASCII favorecido por DNS. Se especifica en la Solicitud de comentarios 3492 del IETF . [1]

Procedimiento de codificación

Como se indica en RFC 3492, "Punycode es una instancia de un algoritmo más general llamado Bootstring , que permite que cadenas compuestas a partir de un pequeño conjunto de puntos de código 'básicos' representen de forma única cualquier cadena de puntos de código extraídos de un conjunto más grande". Punycode define parámetros para que el algoritmo general Bootstring coincida con las características del texto Unicode. Esta sección demuestra el procedimiento para la codificación Punycode, utilizando el ejemplo de la cadena "bücher" ( Bücher significa libros en alemán ), que se traduce a la etiqueta "bcher-kva".

Separación de caracteres ASCII

Primero, todos los caracteres ASCII de la cadena se copian de la entrada a la salida, omitiendo cualquier otro carácter. Por ejemplo, "bücher" se copia en "bcher". Si se copiaron caracteres, es decir, si había al menos un carácter ASCII en la entrada, se añade un guión ASCII a la salida (p. ej., "bücher" → "bcher-", pero "ü" → "").

Tenga en cuenta que los guiones son en sí mismos caracteres ASCII. Así, pueden estar presentes en la entrada y, de ser así, se copiarán en la salida. Esto no causa ambigüedad: si la salida contiene guiones, el que se agregó es siempre el último. Marca el final de los caracteres ASCII.

Codificación de caracteres no ASCII

Para cada carácter no ASCII en la entrada, el codificador calcula dos números:

Por ejemplo, la letra "ü" en la palabra "bücher" está en la posición i = 1 y tiene el punto de código 0xFC = 252, por lo que n = 252 - 127 = 125. Dado que hay 124 × 6 = 744 posiciones de inserción para caracteres con 124 códigos más pequeños ( numerados del 0 al 743), la posición ( n =125, i =1) estará representada por un número 745.

Para cada carácter siguiente, el codificador calcula el número de pasos en la secuencia ( i , n ), ( i +1, n ), ..., ( 0 , n+1 ), ..., ( i next , n next ), y codifica el número resultante en una secuencia de dígitos en base 36. Los representa en ASCII y agrega el resultado a la cadena de salida.

La representación ASCII es: 0 → 'a', ..., 25 → 'z', 26 → '0', ..., 35 → '9', con los dígitos del número ordenados en orden little-endian .

El proceso de codificación no es base-36 sino de alguna manera más complejo. Genera números enteros de longitud variable . Tienen la propiedad de que el dígito más significativo de cada número (por ejemplo, el dígito "1" en el número "123") es reconocible sin contexto. Por lo tanto, los dígitos de varios números se pueden concatenar, sin que nada los separe, pero aún así se pueden reconocer y extraer los números originales.

El número 745 se codificará como 10 + 21 × 35 + 0 (la base 35 se usa para el segundo dígito, el dígito más significativo 0 se necesita como terminador), 10 → 'k', 21 → 'v', 0 → 'a', por lo que "bücher" → "xn--bcher-kva".

Prefijo ACE para nombres de dominio internacionalizados

Para evitar que los guiones en nombres de dominio no internacionales activen una decodificación de Punycode, la cadena xn--se antepone a las secuencias de Punycode en los nombres de dominio internacionalizados. Esto se llama ACE (codificación compatible con ASCII). [2]

Por tanto, el nombre de dominio "bücher.tld" se representaría en ASCII como "xn--bcher-kva.tld".

el decodificador

El decodificador es una máquina de estados finitos con dos variables de estado i y n .

i es un índice en la cadena, que va desde cero (que representa una posible inserción al principio) hasta la longitud actual de la cadena extendida (que representa una posible inserción al final). Empiezo desde cero.

n comienza en 128 (el primer punto de código no ASCII).

La progresión de estados es una función monótona . Una transición de estado incrementa i o, si i está en su máximo, restablece i a cero e incrementa n . En la siguiente transición de estado, reanudamos el incremento de i . En cada estado, el punto de código indicado por n se inserta o no.

Los números generados por el codificador representan cuántas posibilidades se deben omitir antes de realizar una inserción.

Hay seis lugares posibles para insertar un carácter en la cadena "bcher" (incluso antes del primer carácter y después del último). Hay 124 puntos de código entre el último punto de código ASCII (127 = 0x7F, el final de ASCII) y "ü" (punto de código 252 = 0xFC, consulte el Suplemento Latin-1 de Unicode ). Hay una posición de inserción para la "ü" que debe omitirse (posición cero: antes de la "b").

Así, el decodificador omitirá un total de (6 × 124) + 1 = 745 posibles inserciones antes de llegar a la requerida. Una vez insertado el carácter, ahora hay siete lugares posibles para insertar otro carácter.

Recodificación de números de código como secuencias ASCII

Punycode utiliza enteros generalizados de longitud variable para representar estos valores. Por ejemplo, así es como se utiliza "kva" para representar el número de código 745:

Se utiliza un sistema numérico con ordenamiento little-endian que permite códigos de longitud variable sin delimitadores separados: un dígito inferior a un valor umbral marca que es el dígito más significativo y, por tanto, el final del número. El valor umbral depende de la posición en el número y también de inserciones anteriores, para aumentar la eficiencia. En consecuencia, los pesos de los dígitos varían.

En este caso se utiliza un sistema numérico con 36 símbolos, donde la 'a' a la 'z' no distingue entre mayúsculas y minúsculas y son iguales a los números decimales del 0 al 25, y del '0' al '9' son iguales a los números decimales del 26 al 35. Por tanto, "kva", corresponde a la cadena numérica decimal "10 21 0".

Para decodificar esta cadena de símbolos, será necesaria una secuencia de umbrales, en este caso es (1, 1, 26, 26,...). [3] El peso (o valor posicional ) del dígito menos significativo es siempre 1: 'k' (=10) con un peso de 1 es igual a 10. Después de esto, el peso del siguiente dígito depende del primer umbral: generalmente, para cualquier n , el peso del ( n +1) -ésimo dígito es el peso del anterior veces (36 - umbral del n -ésimo dígito). Entonces, el segundo símbolo tiene un valor posicional de 36 menos el valor umbral anterior, en este caso, 35. Por lo tanto, la suma de los dos primeros símbolos 'k' (=10) y 'v' (=21) es 10 × 1 + 21 × 35. Dado que el segundo símbolo no es menor que su valor umbral de 1, hay más por venir. Sin embargo, dado que el tercer símbolo en este ejemplo es 'a' (=0), podemos ignorar el cálculo de su peso. Por lo tanto, "kva" representa el número decimal (10 × 1) + (21 × 35) = 745. Los propios umbrales se determinan para cada carácter codificado sucesivo mediante un algoritmo que los mantiene entre 1 y 26 inclusive. [4] El caso se puede utilizar para proporcionar información sobre el caso original de la cadena. [5] Debido a que los caracteres especiales se clasifican por sus puntos de código mediante un algoritmo de codificación, para la inserción de un segundo carácter especial en "bücher", la primera posibilidad es "büücher" con el código "bcher-kvaa", la segunda "bücüher" con código "bcher-kvab", etc. Después de "bücherü" con el código "bcher-kvae" vienen los códigos que representan la inserción de ý, el carácter Unicode después de ü, comenzando con "ýbücher" con el código "bcher-kvaf" (diferente de "übücher " codificado "bcher-jvab"), etc.

Para simplificar los algoritmos de codificación y decodificación, no se ha intentado evitar que algunos valores codificados codifiquen valores Unicode inadmisibles: sin embargo, estos deben verificarse y detectarse durante la decodificación.

Punycode está diseñado para funcionar en todos los scripts y para optimizarse automáticamente al intentar adaptarse a los rangos del conjunto de caracteres dentro de la cadena mientras opera. Está optimizado para el caso en el que la cadena se compone de cero o más caracteres ASCII y además caracteres de otro solo sistema de script, pero puede funcionar con cualquier cadena Unicode arbitraria. Tenga en cuenta que para el uso de DNS, se supone que la cadena de nombre de dominio se ha normalizado mediante nameprep y (para dominios de nivel superior ) se ha filtrado según una tabla de idiomas registrada oficialmente antes de codificarla, y que el protocolo DNS establece límites en las longitudes aceptables de la cadena. salida de la cadena Punycode.

Ejemplos

La siguiente tabla muestra ejemplos de codificaciones Punycode para diferentes tipos de entrada. [6]

Ver también

Referencias

  1. ^ RFC 3492, Punycode: una codificación Bootstring de Unicode para nombres de dominio internacionalizados en aplicaciones (IDN) , A. Costello, The Internet Society (marzo de 2003)
  2. ^ Autoridad de números asignados de Internet (14 de febrero de 2003). "Finalización de la selección de la IANA del prefijo IDNA". www.atm.tut.fi. _ Archivado desde el original el 27 de abril de 2010 . Consultado el 22 de septiembre de 2017 .
  3. ^ Esto es cierto para el primer carácter codificado (o, en términos de RFC 3492, el primer "delta"): consulte RFC 3492, Sec. 6.
  4. ^ RFC 3492, secs. 3.4, 5.
  5. ^ RFC 3492, aplicación. A.
  6. ^ El Punycode de esta tabla se creó utilizando el códec integrado "punycode" del lenguaje de programación Python versión 3.8 ( s.encode("punycode")). Ver página de discusión .

enlaces externos