"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Unicode, Emojis y un poco de Golang

Unicode, Emojis y un poco de Golang

Publicado el 2024-11-01
Navegar:697

Unicode, Emojis, and a bit of Golang

Últimamente, he tenido un problema con mi instalación de Fedora Linux que muestra emojis en la interfaz de usuario del sistema operativo y en los navegadores. Este problema me llevó a investigar un poco sobre el proyecto de configuración de fuentes, pero para probar mis configuraciones y fuentes, necesitaba producir emojis de todas las versiones Unicode, lo que finalmente me llevó a escribir un "script" de Golang para imprimir todos los emojis y algunos información sobre sus partes internas.

A lo largo de este viaje, profundicé en los aspectos internos de los emojis, sus representaciones binarias y algunas de las decisiones raras/lindas tomadas por el estándar Unicode con respecto a los emojis.

Pero primero, retrocedamos rápidamente y resumamos algo del glosario.

Codificación (o codificación de caracteres)

Podríamos describir la codificación como el "mapeo" o "traducción" entre una letra de un idioma y la representación binaria de esta letra. Por ejemplo, la codificación ASCII tradicional asigna la letra a a 0x61 hexadecimal (0b01100001 binario). Ejemplos de codificaciones son las páginas de códigos de 8 bits de Microsoft (Windows 125x) o ISO (ISO/IEC 8859).

En estas páginas de códigos fijos de 8 bits, la "cantidad" mínima de información utilizada es de 8 bits (1 byte), lo que significa que pueden contener 256 letras/caracteres diferentes. Se crearon diferentes páginas de códigos reutilizando los 256 códigos binarios para admitir muchos idiomas. Entonces, tener un archivo de texto con estos 3 bytes escritos [0xD0, 0xE5, 0xF2] se lee como "Πες" usando la ISO 8859-7 griega, o "Ðåò" usando la ISO 8859-7 occidental (los mismos bytes, interpretados de manera diferente basado en la página de códigos).

En algún momento, tener muchas páginas de códigos diferentes no escalaba bien a medida que avanzaba la tecnología. Entonces, necesitábamos algo que pudiera adaptarse a todos los idiomas (y más) y estar unificado en todos los sistemas.

[ avance rápido, dejando de lado mucha historia y estándares, hasta el presente ]

Estándar Unicode

El estándar Unicode fue diseñado para admitir todos los sistemas de escritura del mundo que se pueden digitalizar. Entonces, usando el ejemplo anterior, en los estándares Unicode, la letra griega "Π" tiene el código 0x03A0 mientras que la letra latina mayúscula eth "Ð" tiene el código 0x00D0 y ya no chocan. El estándar Unicode tiene versiones y, en el momento de escribir este artículo, la última versión es 16.0 (especificación).

Pero espera un minuto, ¿qué es este "punto de código"?

Puntos de código Unicode

En el estándar Unicode, cada "letra", carácter de control, emoji y cada elemento definido en general tiene un valor binario único llamado "punto de código". El estándar define todos los puntos de código y cada punto de código contiene código puro/información binaria. El formato hexadecimal para cada punto de código suele escribirse con un prefijo U. Por ejemplo, el punto de código griego minúscula Omega (ω) es U 03C9.

Entonces, ¿a quién codificamos realmente esos puntos de código?

Formularios de codificación Unicode y esquemas de codificación

La primera parte de codificar puntos de código en bytes son las formas de codificación. Según la norma:

los formularios de codificación especifican cómo se expresará cada número entero (punto de código) de un carácter Unicode como una secuencia de una o más unidades de código.

Los formularios de codificación utilizan el término "unidad de código" para referirse a la unidad más pequeña de datos utilizada para representar un punto de código Unicode dentro de una codificación particular.

El estándar Unicode define tres formas de codificación diferentes:

  • UTF-32. Unidad de código de longitud fija por punto de código. Tamaño por punto de código: una unidad de código de 32 bits (4 bytes).
  • UTF-16. Unidades de código de longitud variable por punto de código. Tamaño por punto de código: una o dos unidades de código de 16 bits (2~4 bytes).
  • UTF-8. Unidades de código de longitud variable por punto de código. Tamaño por punto de código: de una a cuatro unidades de código de 8 bits (1~4 bytes).

Esto significa que un único punto de código o una secuencia de puntos de código pueden codificarse de manera diferente según la forma de codificación utilizada.

La capa que se encarga de la serialización binaria real en Unicode se llama Esquemas de codificación y se encarga de todos los detalles de bajo nivel (como el endianismo). Tabla 2-4 de la especificación Unicode:


|Encoding Scheme| Endian Order                | BOM Allowed? |
| ------------- | ----------------------------| ------------ |
| UTF-8         | N/A                         | yes          |
| UTF-16        | Big-endian or little-endian | yes          |
| UTF-16BE      | Big-endian                  | no           |
| UTF-16LE      | Little-endian               | no           |
| UTF-32        | Big-endian or little-endian | yes          |
| UTF-32BE      | Big-endian                  | no           |
| UTF-32LE      | Little-endian               | no           |


Nota: Casi todos los lenguajes de programación, sistemas operativos y sistemas de archivos modernos utilizan Unicode (con uno de sus esquemas de codificación) como codificación nativa. Java y .NET usan UTF-16, mientras que Golang usa UTF-8 como codificación de cadena interna (es decir, cuando creamos cualquier cadena en la memoria, se codifica en Unicode con la forma de codificación mencionada)

emojis

El estándar Unicode también define puntos de código para emojis (muchos de ellos) y (después de cierta confusión con el número de versión), la versión del "estándar" Emoji progresa en paralelo con el estándar Unicode. Al momento de escribir este artículo, tenemos Emoji "16.0" y el estándar Unicode "16.0".

Ejemplos:
⛄ Muñeco de nieve sin nieve (U 26C4)
? Cara sonriente con ojos sonrientes y tres corazones (U 1F970)

Modificadores de emoji y unirse

Unicode define modificadores que podrían seguir el punto de código base de un emoji, como la variación y el tono de piel (no exploraremos la parte de variación).

Tenemos seis modificadores de tono de piel (siguiendo la escala de Fitzpatrick) llamados EMOJI MODIFIER FITZPATRICK TYPE-X (donde x es de 1 a 6), y afectan a todos los emojis humanos.

Tono de piel claro (Fitzpatrick tipo 1-2) (U 1F3FB)
Tono de piel claro medio (Fitzpatrick tipo 3) (U 1F3FC)
Tono de piel medio (Fitzpatrick tipo 4) (U 1F3FD)
Tono de piel oscuro medio (Fitzpatrick tipo 5) (U 1F3FE)
Tono de piel oscuro (Fitzpatrick tipo 6) (U 1F3FF)

Entonces, por ejemplo, como todos los emojis humanos, ¿el emoji de bebé? (U 1F476), cuando no va seguido de un modificador de piel, aparece en un color amarillo neutro. Por el contrario, cuando le sigue un modificador de color de piel, cambia en consecuencia.
? U 1F476
?? U 1F476 U 1F3FF
?? U 1F476 U 1F3FE
?? U 1F476 U 1F3FD
?? U 1F476 U 1F3FC
?? U 1F476 U 1F3FB

Uniendo emojis

La decisión más extraña pero linda del estándar Emoji/Unicode es que algunos emojis se han definido uniendo otros usando Zero Width Joiner sin un punto de código independiente.

Entonces, por ejemplo, cuando combinamos:
Bandera Blanca ?️ (U 1F3F3 U FE0F)
Carpintero de ancho cero (U 200D)
Arcoíris ? (U 1F308)

¿Aparece como Bandera del Arco Iris?️‍? (U 1F3F3 U FE0F U 200D U 1F308)

O, ?? ? => ??‍?
O incluso, ?? ❤️? ?? => ??‍❤️‍?‍??

Es como apretar emojis juntos y luego, ¿puf?, aparece un nuevo emoji. ¿Qué lindo es eso?


Quería crear una tabla Markdown con todos los emojis, y las tablas de secuencia de emoji Unicode son la fuente de verdad para eso.

https://unicode.org/Public/emoji/16.0/emoji-sequences.txt
https://unicode.org/Public/emoji/16.0/emoji-zwj-sequences.txt

Así que creé un analizador Golang (aquí) que busca y analiza esos archivos de secuencia, genera cada emoji cuando se describe un rango en el archivo de secuencia e imprime una tabla de rebajas con información interna para cada uno (como el partes en caso de que se uniera, o la base tono de piel, etc.).

Puedes encontrar la tabla de rebajas aquí.

La última columna de esta tabla tiene este formato :.

Golang, Unicode y Runa


str := "⌚"
len([]rune(str)) // 1
len([]byte(str)) // 3


Como comentamos, la codificación de cadena interna de Golang es UTF-8, lo que significa que, por ejemplo, para el emoji de reloj ⌚ la longitud de bytes es 3 (porque UTF-8 produce 3 bytes para "escribir" este punto de código), y la longitud del punto de código es 1.

Runa Golang == Punto de código Unicode

Pero en el caso de los emoji unidos -incluso si "aparece" como uno- tenemos muchos puntos de código (runas) e incluso más bytes.


str := "??‍❤️‍?‍??"
len([]rune(str)) // 10
len([]byte(str)) // 35


Y la razón es que:


??‍❤️‍?‍?? : ??   ZWJ   ❤️   ZWJ   ?   ZWJ   ??

??  : 1F469 1F3FC // ?   skin tone modifier [2 code points]
ZWJ : 200D // [1 code points] * 3
❤️  : 2764 FE0F // ❤   VS16 for emoji-style [2 code points]
?  : 1F48B // [1 code point]
??  : 1F468 1F3FE // ?   skin tone modifier [2 code points]


?


Vale la pena mencionar que la forma en que vemos los emojis depende de la fuente de nuestro sistema y de las versiones de emoji que admite esta fuente.

No conozco los aspectos internos exactos de la representación de fuentes y cómo se pueden representar correctamente las fuentes unidas. Quizás sea un post futuro.

Hasta entonces, ¿salud?

Declaración de liberación Este artículo se reproduce en: https://dev.to/moukoublen/unicode-emojis-and-a-bit-of-golang-3ced?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3