Entendiendo Unicode (Facundo Batista)

1,473
-1

Published on

Facundo Batista presentation explaining how Unicode works (in Python).

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,473
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
21
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Entendiendo Unicode (Facundo Batista)

  1. 1. EntendiendoUnicodeFacundo Batistafacundo@taniquetil.com.arhttp://www.taniquetil.com.ar
  2. 2. ¿Qué es Unicode?Un estándar¿Pero en qué consiste?Un repertorio de más de 100 mil caracteresPlanillas de códigos para referencia visualMetodologías de codificaciónCodificaciones estándaresEnumeración de propiedades de los caracteresEtc... 2
  3. 3. ¿Pero esto cómo se come? 3
  4. 4. Masticando un Code ChartUna planilla de códigos es una tabla con eldibujo de cada caracterEl mapa completo de caracteres de Unicodeestá divido en varios codechartsPor ejemplo:Basic LatinLatin-1GreekRunic 4
  5. 5. Un estándar con carácterPor cada caracter tenemos:Un glifo (de referencia, no prescriptivo)Un nombreUn númeroMás infoEjemplo:03C0GREEK SMALL LETTER PImath constant 3.141592... 5
  6. 6. ¿Y en Python?Definimos el caracter según su código >>> pi = u"u03c0" >>> len(pi) 1¿Y cómo se ve? >>> print pi π >>> pi uu03c0 >>> pi == u"π" True 6
  7. 7. BititosUnicode es muy lindo... ¿pero como lopersistimos o transmitimos?Tenemos que traducir los caracteresUnicode a bits.Codificar o EncodePasar de un caracter Unicode a una secuencia de bytesDecodificar o DecodePasar de una secuencia de bytes a un caracter Unicode 7
  8. 8. Vamos de nuevo 8
  9. 9. ¿No es directo?Necesitamos codificar la información de unaforma estándarNo es exclusivo de Unicode, nos pasa conlos números tambiénEjemplo: NúmerosNegativos: Complemento a 1 o a 2 -3 puede ser (bin) 1100 o 1101Punto flotante: Precisión simple y cuádruple 1.0 puede ser (hex) 3F80 0000 o 3FFF 0000 0000 0000 0000 0000 0000 0000 9
  10. 10. Codificando Unicode¿Cómo representamos en bits un caracterUnicode?Tenemos que inventar un códigoDefinir cuantos bits usaráDefinir las reglas de conversiónYa tenemos muchos códigos estándaresASCIILatin-1 (ISO-8859-1)UTF-8, -16, -32etc 10
  11. 11. Distintas formas de lo mismoDistintos encodings, distintos bytes: >>> enie = u"ñ" >>> enie.encode("latin1") xf1 >>> enie.encode("utf8") xc3xb1 >>> enie.encode("utf16") xffxfexf1x00¿Pero cómo hacemos la decodificación?Necesitamos sí o sí saber el código usado 11
  12. 12. ¿Pero cuál uso? Latin1Está muy extendidoNo se mantiene desde 2004No representa todos los caracteres: >>> print pi π >>> pi.encode("latin1") ... UnicodeEncodeError: latin-1 codec cant encode character uu03c0...Se utiliza un bytePrimeros 128 caracteres: ASCIISegundos 128: para lenguajes de Europa occidental 12
  13. 13. ¿Pero cuál uso? UTF-16Soporta todos los caracteresPero tenemos que perder dos bytes por caracter (más elBOM!)Incluso si utilizamos caracteres simples, como en estalinea. >>> u"esta".encode("utf16") xffxfeex00sx00tx00ax00 >>> # FFFE 6500 7300 7400 6100Utiliza desde 2 bytesUsa dos bytes para el BMP, pero puede usar 4 bytesSe justifica si siempre tengo caracteres rarosNo es UCS-2 (el cual usa 2 bytes fijos) 13
  14. 14. ¿Pero cuál uso? UTF-8Es el estándar en LinuxSoporta todo el espacio UnicodeUtiliza uno, dos, tres y cuatro bytes, según necesite >>> u"k".encode("utf8") k >>> u"ñ".encode("utf8") xc3xb1 >>> u" 쏔 ".encode("utf8") xecx8fx94Nunca se desactualizaría 14
  15. 15. uteefe-ocho8 bits para los 128 caracteres ASCII 0-7F: 0zzzzzzz16 bits para letras latinas y de otros idiomas 80-7FF: 110yyyyy 10zzzzzz24 bits para el resto del BMP 800-D7FF y E000-FFFF: 1110xxxx 10yyyyyy 10zzzzzz32 bits para el resto de Unicode 10000–10FFFF: 11110www 10xxxxxx 10yyyyyy 10zzzzzz 15
  16. 16. Encoding & Decoding >>> pi uu03c0 >>> d = pi.encode("utf8") >>> d xcfx80 >>> d.decode("utf8") uu03c0Python guarda las cadenas Unicode como bitsUsa una codificación interna en particularSe decide al compilar Python: UCS-2 o UCS-4 16
  17. 17. Y dale...¡Hasta que lo sepan de memoria! 17
  18. 18. Reglas de oroInternamente siempre utilizar Unicode >>> dato = mxc3xa1scara # máscara en UTF8 >>> len(dato) 8 >>> print dato[:4] más >>> print dato.upper() MáSCARACodificar y decodificar en los bordesencode/decodecodecs.open() 18
  19. 19. Siempre en los bordes>>> nomapell = MiBDDWrapper(foo, bar) 1. Leemos de una>>> nomapellxc5mal xd6fwerman fuente externa >>> completo = nomapell.decode("latin1") >>> completo 3. Procesamos uxc5mal xd6fwerman internamente >>> print completo >>> n, a = completo.split() Åmal Öfwerman >>> tit = "%s, %s" % (a, n) >>> print tit Öfwerman, Åmal 2. Pasamos a Unicode (decode) >>> titok = tit.encode("utf8") 4. Pasamos a bytes >>> titok xc3x96fwerman, xc3x85mal (encode)Ejemplo! 5. Dejamos el resultado >>> alHTML(titok) 19
  20. 20. Código fuente UnicodeCaracteres Unicode en nuestro códigoEl editor también debe traducir a bytes ¡Lo codifica!El intérprete de Python debe saber leerlo ¡Lo decodifica!Tiene que saber qué encoding se usó #-*- coding: X -*- 20
  21. 21. Cosas piolas>>> unicodedata.name(pi)GREEK SMALL LETTER PI>>> print unicodedata.lookup("GREEK SMALL LETTER THETA")θ>>> print u"caño de desagüe".upper()CAÑO DE DESAGÜE>>> print pi, pi.upper()πΠ>>> unicodedata.decomposition(u"ñ")006E 0303>>> print u"u006e u0303"ñ 21
  22. 22. ¡Muchas gracias! ¿Preguntas? ¿Sugerencias? Facundo Batista facundo@taniquetil.com.ar http://www.taniquetil.com.ar Licencia: Creative Commons Atribución-NoComercial-CompartirDerivadasIgual 2.5 Argentina http://creativecommons.org/licenses/by-nc-sa/2.5/deed.es_AR 22

×