¿Por qué los caracteres en inglés requieren menos bytes para representar que otros alfabetos?

31

Cuando pongo 'a' en un archivo de texto, tiene 2 bytes, pero cuando pongo, digamos 'ա', que es una letra del alfabeto armenio, tiene 3 bytes.

¿Cuál es la diferencia entre alfabetos para una computadora?
¿Por qué el inglés ocupa menos espacio?

khajvah
fuente
22
Debería leer este artículo del fundador de StackExchange: joelonsoftware.com/articles/Unicode.html
Eric Lippert
22
No creo que existan los "caracteres ingleses". Son romanos
Raphael
55
@Raphael, sin embargo, todos saben a qué se refiere. Pero buen complemento.
Mathias Lykkegaard Lorenzen
1
@Raphael En realidad, hay muchas letras romanas que no se usan en inglés y, por lo tanto, no se incluyen en el conjunto de caracteres ASCII. La mayoría de ellos incluyen modificadores, pero aún son necesarios para representar correctamente el texto en varios idiomas derivados del latín además del inglés.
Wutaz
77
@Raphael No creo que existan los "caracteres romanos". Son latinos
Blacklight Shining

Respuestas:

41

Uno de los primeros esquemas de codificación que se desarrollará para usar en computadoras convencionales es el estándar ASCII ( American Standard Code for Information Interchange ). Fue desarrollado en la década de 1960 en los Estados Unidos.

El alfabeto inglés usa parte del alfabeto latino (por ejemplo, hay pocas palabras acentuadas en inglés). Hay 26 letras individuales en ese alfabeto, sin considerar el caso. Y también tendría que existir los números individuales y los signos de puntuación en cualquier esquema que pretenda codificar el alfabeto inglés.

La década de 1960 también fue una época en que las computadoras no tenían la cantidad de memoria o espacio en disco que tenemos ahora. ASCII fue desarrollado para ser una representación estándar de un alfabeto funcional en todas las computadoras estadounidenses. En ese momento, la decisión de hacer que cada carácter ASCII tuviera 8 bits (1 byte) de largo se tomó debido a los detalles técnicos de la época (el artículo de Wikipedia menciona el hecho de que la cinta perforada contenía 8 bits en una posición a la vez). De hecho, el esquema ASCII original puede transmitirse usando 7 bits, los ocho podrían usarse para verificaciones de paridad. Desarrollos posteriores ampliaron el esquema ASCII original para incluir varios caracteres acentuados, matemáticos y terminales.

Con el reciente aumento del uso de computadoras en todo el mundo, más y más personas de diferentes idiomas tuvieron acceso a una computadora. Eso significaba que, para cada idioma, se tenían que desarrollar nuevos esquemas de codificación, independientemente de otros esquemas, que entrarían en conflicto si se leían desde diferentes terminales de idiomas.

Unicode surgió como una solución a la existencia de diferentes terminales, fusionando todos los posibles caracteres significativos en un único conjunto de caracteres abstractos.

UTF-8 es una forma de codificar el juego de caracteres Unicode. Es una codificación de ancho variable (por ejemplo, diferentes caracteres pueden tener diferentes tamaños) y fue diseñada para ser compatible con versiones anteriores del esquema ASCII anterior. Como tal, el conjunto de caracteres ASCII seguirá siendo un byte grande, mientras que cualquier otro carácter tendrá dos o más bytes. UTF-16 es otra forma de codificar el juego de caracteres Unicode. En comparación con UTF-8, los caracteres se codifican como un conjunto de una o dos unidades de código de 16 bits.

Como se indicó en los comentarios, el carácter 'a' ocupa un solo byte mientras que 'ա' ocupa dos bytes, lo que denota una codificación UTF-8. El byte adicional en su pregunta se debió a la existencia de un carácter de nueva línea al final (que el OP descubrió).

Doktoro Reichard
fuente
26
No hay un último byte que codifique el final del archivo, en cualquier codificación o formato de archivo normal. Cuando un programa lee un archivo, el sistema operativo puede indicar el final del archivo de una manera especial, pero ese es un problema diferente.
Jukka K. Korpela
2
El carácter is es de 2 bytes (0xD5A1) en la versión UTF-8 de unicode; el carácter extra (lo que sea que esté) está presente en ambos archivos. marathon-studios.com/unicode/U0561/Armenian_Small_Letter_Ayb
Dan Neely
66
@khajvah Si lo haces echo 'ա' > file.txt, o editas el archivo usando algunos editores, automáticamente agregan una nueva línea después de él. Si ejecuta xxd file.txt, el último byte probablemente sea un 0a, o avance de línea.
Daniel Beck
77
@DoktoroReichard: Por favor aclare en la respuesta que Unicode no es una codificación; más bien, es un juego de caracteres abstracto, y UTF-16 y UTF-8 son codificaciones de puntos de código Unicode. Los últimos párrafos de su respuesta hablan principalmente de UTF-8. Pero si un archivo usa UTF-16, entonces cualquier punto de código, incluso el de a, usará dos bytes (o un múltiplo de dos).
Grawity
66
Probablemente también valga la pena enfatizar que los conjuntos de caracteres "ASCII extendido" en realidad no son ASCII en absoluto, y la cantidad de formas diferentes de utilizar el octavo bit hace que todo sea un gran desastre. Simplemente use UTF-8 en su lugar.
ntoskrnl
17

1 byte es de 8 bits y, por lo tanto, puede representar hasta 256 (2 ^ 8) valores diferentes.

Para los idiomas que requieren más posibilidades que esto, no se puede mantener una asignación simple 1 a 1, por lo que se necesitan más datos para almacenar un carácter.

Tenga en cuenta que, en general, la mayoría de las codificaciones utilizan los primeros 7 bits (128 valores) para los caracteres ASCII . Eso deja el octavo bit, o 128 valores más para más caracteres. . . agregue caracteres acentuados, idiomas asiáticos, cirílico, etc., y podrá ver fácilmente por qué 1 byte no es suficiente para mantener todos los caracteres.

ernie
fuente
así que aquí está la única respuesta que realmente explica por qué se usa más espacio
Félix Gagnon-Grenier
10

En UTF-8, los caracteres ASCII usan un byte, otros caracteres usan dos, tres o cuatro bytes.

Jason
fuente
1
¿Puedes explicar por qué es esto? notar dos métodos de codificación no responde la pregunta.
MaQleod
@MaQleod Unicode fue creado para reemplazar ASCII. Para compatibilidad con versiones anteriores, los primeros 128 caracteres son iguales. Estos 128 caracteres se pueden expresar con un byte. Se agregan bytes adicionales para caracteres adicionales.
Jason
Soy consciente, pero eso es parte de la respuesta a la pregunta sobre qué hace que los caracteres ASCII sean diferentes. Debe explicarse al OP.
MaQleod
@MaQleod También se podría decir que el Consorcio Unicode estaba compuesto principalmente por corporaciones estadounidenses y se inclinaba hacia los caracteres en inglés. Pensé que una respuesta simple era mejor que una subjetiva.
Jason
15
No "en Unicode", en UTF8, que es solo una de varias codificaciones del juego de caracteres Unicode.
Sebastian Negraszus
3

La cantidad de bytes necesarios para un carácter (de lo que aparentemente se trata la pregunta) depende de la codificación de caracteres. Si usa la codificación ArmSCII, cada letra armenia ocupa solo un byte. Sin embargo, no es una buena opción en estos días.

En la codificación de transferencia UTF-8 para Unicode, los caracteres necesitan un número diferente de bytes. En él, "a" toma solo un byte (la idea de dos bytes es una especie de confusión), "á" toma dos bytes y la letra armenia ayb "ա" también toma dos bytes. Tres bytes deben ser una especie de confusión. En contraste, por ejemplo, la letra bengalí a “অ” toma tres bytes en UTF-8.

El trasfondo es simplemente que UTF-8 fue diseñado para ser muy eficiente para los caracteres Ascii, bastante eficiente para los sistemas de escritura en Europa y sus alrededores, y todo lo demás es menos eficiente. Esto significa que las letras latinas básicas (que es en lo que consiste principalmente el texto en inglés), solo se necesita un byte para un carácter; para griego, cirílico, armenio y algunos otros, se necesitan dos bytes; todo lo demás necesita más.

UTF-8 tiene (como se señala en un comentario) también la propiedad útil de que los datos Ascii (cuando se representan como unidades de 8 bits, que ha sido casi la única forma durante mucho tiempo) también están trivialmente codificados en UTF-8.

Jukka K. Korpela
fuente
Gracias por la respuesta. Los bytes adicionales se deben a que el programa que usé agregó automáticamente un nuevo carácter de línea al final.
Khajvah
1
No creo que UTF-8 haya sido diseñado tanto para la eficiencia con los datos ASCII como para la compatibilidad . UTF-8 tiene la propiedad muy agradable de que el contenido ASCII de 7 bits (con el bit alto establecido en cero) es idéntico al mismo contenido codificado que UTF-8, por lo que para las herramientas que normalmente tratan con ASCII, es un reemplazo directo . Ningún otro esquema de codificación Unicode tiene esa propiedad, que yo sepa. UTF-8 también es razonablemente compacto para la mayoría de los datos, especialmente si permanece dentro del ámbito de Unicode BMP .
un CVn
1
@ MichaelKjörling, agregué una referencia a esa característica. Sin embargo, una de las principales objeciones a Unicode en los primeros días fue la ineficiencia, y UTF-16 duplica el tamaño de los datos que es predominantemente Ascii. UTF-8 significa, por ejemplo, para texto en inglés, que solo "paga" por los caracteres que no son Ascii que usa.
Jukka K. Korpela
3

Los códigos de caracteres en la década de 1960 (y mucho más allá) eran específicos de la máquina. En la década de 1980 utilicé brevemente una máquina DEC 2020, que tenía palabras de 36 bits y codificaciones de 5, 6 y 8 bits ( IIRC ) por carácter. Antes de eso, usé una serie IBM 370 con EBCDIC. ASCII con 7 bits ordenó, pero se confundió con las "páginas de códigos" de IBM PC que usaban los 8 bits para representar caracteres adicionales, como todo tipo de dibujos de cuadros para pintar menús primitivos, y luego extensiones ASCII como Latin-1 (8 bits codificaciones, con los primeros 7 bits como ASCII y la otra mitad para los "caracteres nacionales", como ñ, Çu otros. Probablemente el más popular fue América-1, adaptado a la mayoría de las lenguas europeas Inglés y el uso de caracteres latinos (y acentos y variantes).

Escribir texto mezclando, por ejemplo, inglés y español funcionó bien (solo use latín-1, superconjunto de ambos), pero mezclar cualquier cosa que usara codificaciones diferentes (por ejemplo, incluir un fragmento de griego o ruso, sin mencionar un idioma asiático como el japonés) Una verdadera pesadilla. Lo peor fue que los rusos y particularmente los japoneses y chinos tenían varias codificaciones populares, completamente incompatibles.

Hoy usamos Unicode, que se combina con codificaciones eficientes como UTF-8 que favorecen los caracteres en inglés (sorprendentemente, la codificación de letras en inglés solo corresponde a ASCII), lo que hace que muchos caracteres no ingleses usen codificaciones más largas.

vonbrand
fuente
2

Windows 8.1 US / English File con una sola 'a' guardada con el bloc de notas.

  • Guardar como ANSI 1 byte
  • Guardar como Unicode 4 bytes
  • Guardar como UTF-8 4 bytes

Archivo con un solo 'ա' guardado con el bloc de notas

  • Guardar como ANSI no es posible
  • Guardar como Unicode 4 bytes
  • Guardar como UTF-8 5 bytes

Una sola 'a' está codificada como un solo byte en ANSI, en Unicode cada carácter suele ser de 2 bytes, también hay una BOM de 2 bytes (Marcador de orden de bytes) al comienzo del archivo. UTF-8 tiene una lista de materiales de 3 bytes y el carácter de un solo byte.

Para la 'ա', ese carácter no existe en el juego de caracteres ANSI y no se puede guardar en mi máquina. El archivo Unicode es el mismo que antes, y el archivo UTF-8 es 1 byte más grande ya que el carácter toma 2 bytes.

Si su máquina es de una región diferente, es posible que tenga instalada una página de códigos OEM diferente que tiene diferentes glifos para los 255 caracteres posibles en el rango ASCII. Como @ntoskrnl mencionó, la página de códigos OEM para mi máquina sería Windows-1252, que es el valor predeterminado para inglés de EE. UU.

Darryl Braaten
fuente
44
El Bloc de notas (y Windows en general) usa una terminología confusa aquí. "ANSI" es una codificación de byte único dependiente de la configuración regional (Windows-1252 en versiones en inglés), y "Unicode" es UTF-16.
ntoskrnl
@ntoskrnl Eso es correcto, pero si está buscando codificación en el cuadro desplegable, dice ANSI, por eso mencioné que si tiene una página de códigos OEM diferente, puede obtener resultados diferentes.
Darryl Braaten el
2

Si está interesado en cómo se almacenan los caracteres, puede ir a www.unicode.org y mirar a su alrededor. En la parte superior de su página principal hay un enlace "Gráficos de códigos" que muestra todos los códigos de caracteres que están disponibles en Unicode.

Con todo, hay un poco más de un millón de códigos disponibles en Unicode (no se usan todos). Un byte puede contener 256 valores diferentes, por lo que necesitaría tres bytes si desea almacenar todos los códigos Unicode posibles.

En cambio, Unicode generalmente se almacena en la codificación "UTF-8" que usa menos bytes para algunos caracteres y más para otros. Los primeros 128 valores de código se almacenan en un solo byte, hasta los primeros 2048 valores de código se almacenan en dos bytes, hasta 65536 se almacenan en tres bytes y el resto ocupa cuatro bytes. Esto se ha organizado para que los valores de código que se usan con más frecuencia ocupen menos espacio. AZ, az, 0-9 y! @ $% ^ & * () - [} {}; ': "|,. / <>? Y algunos que olvidé toman un byte; casi todo inglés, 98% de El alemán y el francés (solo adivinando) se pueden almacenar en un byte por carácter, y estos son los caracteres que más se utilizan. Cirílico, griego, hebreo, árabe y algunos otros usan dos bytes por carácter. Idiomas indios, la mayoría de chino, japonés , Coreano, tailandés, toneladas de símbolos matemáticos, Se puede escribir en tres bytes por carácter. Las cosas raras (si alguna vez quieres escribir texto en Lineal A o Linear B, Emojis) toman cuatro bytes.

Otra codificación es UTF-16. Todo lo que toma 1, 2 o 3 bytes en UTF-8 toma dos bytes en UTF-16. Esa es una ventaja si tiene texto en chino o japonés con muy pocos caracteres latinos en el medio.

Acerca de los motivos del diseño UTF-8: tiene varias ventajas sobre otros diseños. Son:

Compatibilidad con caracteres ASCII de EE. UU.

Compactabilidad razonable

Sincronización automática: esto significa que si se le da parte de una secuencia de bytes que son caracteres en la codificación UTF-8, puede averiguar dónde comienza el carácter. En algunas codificaciones, tanto xy como yx pueden ser codificaciones válidas de caracteres, por lo que si se le da parte de una secuencia ... xyxyxyxyxyxy ... no puede saber qué caracteres tiene.

Corrección de la clasificación: si clasifica las cadenas que contienen caracteres codificados UTF-8 por sus valores de byte, se ordenan automáticamente de acuerdo con sus valores Unicode.

Compatible con código de un solo byte: la mayoría de los códigos que asumen valores de un solo byte funcionan automáticamente correctamente con caracteres codificados UTF-8.

Además de las razones que olvide.

gnasher729
fuente