¿Qué es diferente entre UTF-8 y UTF-8 sin una lista de materiales ? ¿Cual es mejor?
¿Qué es diferente entre UTF-8 y UTF-8 sin una lista de materiales ? ¿Cual es mejor?
Respuestas:
La lista de materiales UTF-8 es una secuencia de bytes al comienzo de una secuencia de texto ( 0xEF, 0xBB, 0xBF
) que permite al lector adivinar de manera más confiable un archivo codificado en UTF-8.
Normalmente, la lista de materiales se utiliza para señalar la endianidad de una codificación, pero dado que la endianidad es irrelevante para UTF-8, la lista de materiales es innecesaria.
Según el estándar Unicode , no se recomienda la lista de materiales para archivos UTF-8 :
2.6 Esquemas de codificación
... El uso de una lista de materiales no es obligatorio ni recomendado para UTF-8, pero puede encontrarse en contextos donde los datos de UTF-8 se convierten de otras formas de codificación que usan una lista de materiales o donde la lista de materiales se usa como firma UTF-8 . Consulte la subsección "Marca de orden de bytes" en la Sección 16.8, Especiales , para obtener más información.
Las otras excelentes respuestas ya respondieron que:
EF BB BF
Pero, como información adicional a esto, la lista de materiales para UTF-8 podría ser una buena manera de "oler" si una cadena estaba codificada en UTF-8 ... O podría ser una cadena legítima en cualquier otra codificación ...
Por ejemplo, los datos [EF BB BF 41 42 43] podrían ser:
Entonces, aunque puede ser genial reconocer la codificación del contenido de un archivo mirando los primeros bytes, no debe confiar en esto, como se muestra en el ejemplo anterior
Las codificaciones deben ser conocidas, no adivinadas.
Existen al menos tres problemas al colocar una lista de materiales en archivos codificados UTF-8.
Y, como otros han mencionado, no es suficiente ni necesario tener una lista de materiales para detectar que algo es UTF-8:
cat
no te dará un resultado limpio , un resultado que solo tenga BOM al principio. Si quisiste decir eso, entonces es porque cat
funciona en el nivel de byte, no en el nivel de contenido interpretado, y de manera similar cat
no puede manejar fotografías, por ejemplo. Aún así no hace mucho daño. Esto se debe a que la lista de materiales codifica un espacio sin interrupción de ancho cero.
Aquí hay ejemplos del uso de BOM que en realidad causan problemas reales y, sin embargo, muchas personas no lo saben.
Scripts de shell, scripts de Perl, scripts de Python, scripts de Ruby, scripts de Node.js o cualquier otro ejecutable que deba ser ejecutado por un intérprete; todo comienza con una línea shebang que se parece a una de esas:
#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node
Le dice al sistema qué intérprete debe ejecutarse al invocar dicho script. Si el script está codificado en UTF-8, uno puede verse tentado a incluir una lista de materiales al principio. Pero en realidad el "#!" los personajes no son solo personajes. De hecho, son un número mágico que está compuesto de dos caracteres ASCII. Si coloca algo (como una lista de materiales) antes de esos caracteres, entonces el archivo tendrá un número mágico diferente y eso puede generar problemas.
Ver Wikipedia, artículo: Shebang, sección: Número mágico :
Los caracteres shebang están representados por los mismos dos bytes en codificaciones ASCII extendidas, incluido UTF-8, que se usa comúnmente para scripts y otros archivos de texto en sistemas actuales tipo Unix. Sin embargo, los archivos UTF-8 pueden comenzar con la marca de orden de bytes opcional (BOM); si la función "exec" detecta específicamente los bytes 0x23 y 0x21, entonces la presencia de la lista de materiales (0xEF 0xBB 0xBF) antes del shebang evitará que se ejecute el intérprete de script.Algunas autoridades recomiendan no usar la marca de orden de bytes en scripts POSIX (similares a Unix), [14] por este motivo y por una interoperabilidad más amplia y preocupaciones filosóficas. Además, una marca de orden de bytes no es necesaria en UTF-8, ya que esa codificación no tiene problemas de endianness; solo sirve para identificar la codificación como UTF-8. [énfasis añadido]
Ver RFC 7159, Sección 8.1 :
Las implementaciones NO DEBEN agregar una marca de orden de bytes al comienzo de un texto JSON.
No solo es ilegal en JSON, tampoco es necesario determinar la codificación de caracteres porque hay formas más confiables de determinar sin ambigüedades tanto la codificación de caracteres como la endianness utilizada en cualquier flujo JSON (consulte esta respuesta para obtener más detalles).
No solo es ilegal en JSON y no es necesario , en realidad rompe todo el software que determina la codificación utilizando el método presentado en RFC 4627 :
Determinación de la codificación y endianness de JSON, examinando los primeros cuatro bytes para el byte NUL:
00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8
Ahora, si el archivo comienza con BOM se verá así:
00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8
Tenga en cuenta que:
Dependiendo de la implementación, todos estos pueden ser interpretados incorrectamente como UTF-8 y luego malinterpretados o rechazados como UTF-8 inválidos, o no reconocidos en absoluto.
Además, si la implementación prueba JSON válido como lo recomiendo, rechazará incluso la entrada que de hecho está codificada como UTF-8, porque no comienza con un carácter ASCII <128 como debería según el RFC.
BOM en JSON no es necesario, es ilegal y rompe el software que funciona correctamente de acuerdo con el RFC. Debería ser un nobrainer simplemente no usarlo en ese momento y, sin embargo, siempre hay personas que insisten en romper JSON mediante BOM, comentarios, diferentes reglas de citas o diferentes tipos de datos. Por supuesto, cualquiera es libre de usar cosas como listas de materiales o cualquier otra cosa si lo necesita, simplemente no lo llame JSON.
Para otros formatos de datos que no sean JSON, eche un vistazo a cómo se ve realmente. Si las únicas codificaciones son UTF- * y el primer carácter debe ser un carácter ASCII inferior a 128, entonces ya tiene toda la información necesaria para determinar tanto la codificación como la endianness de sus datos. Agregar BOM incluso como una característica opcional solo lo haría más complicado y propenso a errores.
En cuanto a los usos fuera de JSON o scripts, creo que ya hay muy buenas respuestas aquí. Quería agregar información más detallada específicamente sobre secuencias de comandos y serialización, porque es un ejemplo de caracteres BOM que causan problemas reales.
¿Qué es diferente entre UTF-8 y UTF-8 sin BOM?
Respuesta corta: en UTF-8, una lista de materiales se codifica como bytes EF BB BF
al comienzo del archivo.
Respuesta larga:
Originalmente, se esperaba que Unicode se codificara en UTF-16 / UCS-2. La lista de materiales se diseñó para esta forma de codificación. Cuando tiene unidades de código de 2 bytes, es necesario indicar en qué orden están esos dos bytes, y una convención común para hacer esto es incluir el carácter U + FEFF como una "Marca de orden de bytes" al comienzo de los datos. El carácter U + FFFE está permanentemente sin asignar, de modo que su presencia se puede utilizar para detectar el orden de bytes incorrecto.
UTF-8 tiene el mismo orden de bytes independientemente de la capacidad de la plataforma, por lo que no se necesita una marca de orden de bytes. Sin embargo, puede ocurrir (como la secuencia de bytes EF BB FF
) en los datos que se convirtieron a UTF-8 desde UTF-16, o como una "firma" para indicar que los datos son UTF-8.
¿Cual es mejor?
Sin. Como Martin Cote respondió, el estándar Unicode no lo recomienda. Causa problemas con el software no compatible con BOM.
Una mejor manera de detectar si un archivo es UTF-8 es realizar una verificación de validez. UTF-8 tiene reglas estrictas sobre qué secuencias de bytes son válidas, por lo que la probabilidad de un falso positivo es insignificante. Si una secuencia de bytes se parece a UTF-8, probablemente lo sea.
sh
, perl
, g++
, y muchas otras herramientas libres y poderosos. ¿Quieres que las cosas funcionen? Solo compre las versiones de MS. MS creó el problema específico de la plataforma, al igual que el desastre de su rango \ x80- \ x95.
UTF-8 con BOM está mejor identificado. Llegué a esta conclusión por el camino difícil. Estoy trabajando en un proyecto donde uno de los resultados es un archivo CSV , que incluye caracteres Unicode.
Si el archivo CSV se guarda sin una lista de materiales, Excel piensa que es ANSI y muestra galimatías. Una vez que agregue "EF BB BF" en el frente (por ejemplo, volviendo a guardarlo usando el Bloc de notas con UTF-8; o Notepad ++ con UTF-8 con BOM), Excel lo abre bien.
El RFC 3629 recomienda anteponer el carácter BOM a los archivos de texto Unicode: "UTF-8, un formato de transformación de ISO 10646", noviembre de 2003 en http://tools.ietf.org/html/rfc3629 (esta última información se encuentra en: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html )
BOM tiende a explotar (sin juego de palabras (sic)) en algún lugar, en algún lugar. Y cuando se dispara (por ejemplo, no es reconocido por los navegadores, editores, etc.), aparece como los caracteres extraños 
al comienzo del documento (por ejemplo, archivo HTML, respuesta JSON , RSS , etc.) y causa el tipo de vergüenzas como el reciente problema de codificación experimentado durante la conversación de Obama en Twitter .
Es muy molesto cuando aparece en lugares difíciles de depurar o cuando se descuidan las pruebas. Por lo tanto, es mejor evitarlo a menos que deba usarlo.
Pregunta: ¿Qué es diferente entre UTF-8 y UTF-8 sin una lista de materiales? ¿Cual es mejor?
Aquí hay algunos extractos del artículo de Wikipedia sobre la marca de orden de bytes (BOM) que creo que ofrecen una respuesta sólida a esta pregunta.
Sobre el significado de la lista de materiales y UTF-8:
El estándar Unicode permite la lista de materiales en UTF-8 , pero no requiere ni recomienda su uso. El orden de bytes no tiene significado en UTF-8, por lo que su único uso en UTF-8 es indicar al principio que el flujo de texto está codificado en UTF-8.
Argumento para NO usar una lista de materiales:
La motivación principal para no usar una lista de materiales es la compatibilidad con el software que no es compatible con Unicode ... Otra motivación para no usar una lista de materiales es fomentar UTF-8 como la codificación "predeterminada".
Argumento PARA usando una lista de materiales:
El argumento para usar una lista de materiales es que sin ella, se requiere un análisis heurístico para determinar qué caracteres codifica un archivo. Históricamente, dicho análisis, para distinguir varias codificaciones de 8 bits, es complicado, propenso a errores y, a veces, lento. Hay varias bibliotecas disponibles para facilitar la tarea, como Mozilla Universal Charset Detector y International Components for Unicode.
Los programadores suponen erróneamente que la detección de UTF-8 es igualmente difícil (no se debe a que la gran mayoría de las secuencias de bytes son UTF-8 no válidas, mientras que las codificaciones que estas bibliotecas intentan distinguir permiten todas las secuencias de bytes posibles). Por lo tanto, no todos los programas compatibles con Unicode realizan dicho análisis y, en cambio, dependen de la lista de materiales.
En particular, los compiladores e intérpretes de Microsoft , y muchas piezas de software en Microsoft Windows, como el Bloc de notas, no leerán correctamente el texto UTF-8 a menos que solo tenga caracteres ASCII o comience con la lista de materiales, y agregarán una lista de materiales al inicio al guardar texto como UTF-8. Google Docs agregará una lista de materiales cuando se descargue un documento de Microsoft Word como un archivo de texto sin formato.
En cuál es mejor, CON o SIN BOM:
El IETF recomienda que si un protocolo (a) siempre usa UTF-8, o (b) tiene alguna otra forma de indicar qué codificación se está utilizando, entonces "DEBE prohibir el uso de U + FEFF como firma".
Mi conclusión:
Use la lista de materiales solo si la compatibilidad con una aplicación de software es absolutamente esencial.
También tenga en cuenta que si bien el artículo de Wikipedia al que se hace referencia indica que muchas aplicaciones de Microsoft dependen de la lista de materiales para detectar correctamente UTF-8, este no es el caso para todas las aplicaciones de Microsoft. Por ejemplo, como lo señala @barlop , cuando se usa el símbolo del sistema de Windows con UTF-8 † , los comandos type
y more
no esperan que la lista de materiales esté presente. Si la lista de materiales está presente, puede ser problemática como lo es para otras aplicaciones.
† El chcp
comando ofrece soporte para UTF-8 ( sin BOM) a través de la página de códigos 65001 .
.htaccess
y gzip compression
en combinación con UTF-8 BOM da un error de codificación. Cambiar a Codificación en UTF-8 sin BOM sigue una sugerencia como se explica aquí para resolver los problemas
Esta pregunta ya tiene un millón de respuestas y muchas de ellas son bastante buenas, pero quería intentar aclarar cuándo una lista de materiales debe o no debe usarse.
Como se mencionó, cualquier uso de la UTF BOM (Marca de orden de bytes) para determinar si una cadena es UTF-8 o no es una conjetura educada. Si hay metadatos adecuados disponibles (como charset="utf-8"
), entonces ya sabe lo que se supone que debe usar, pero de lo contrario tendrá que probar y hacer algunas suposiciones. Esto implica verificar si el archivo del que proviene una cadena comienza con el código de byte hexadecimal, EF BB BF.
Si se encuentra un código de bytes correspondiente a la lista de materiales UTF-8, la probabilidad es lo suficientemente alta como para suponer que es UTF-8 y puede continuar desde allí. Sin embargo, cuando se ve obligado a hacer esta suposición, la comprobación adicional de errores durante la lectura aún sería una buena idea en caso de que algo salga mal. Solo debe suponer que una BOM no es UTF-8 (es decir, latin-1 o ANSI) si la entrada definitivamente no debe ser UTF-8 en función de su fuente. Sin embargo, si no hay una lista de materiales, simplemente puede determinar si se supone que es UTF-8 al validar contra la codificación.
Si no puede grabar los metadatos de otra manera (a través de una etiqueta de conjunto de caracteres o meta del sistema de archivos), y los programas que se usan como BOM, debe codificar con una BOM. Esto es especialmente cierto en Windows donde cualquier cosa sin una lista de materiales generalmente se supone que está usando una página de códigos heredada. La lista de materiales le dice a programas como Office que sí, el texto en este archivo es Unicode; Aquí está la codificación utilizada.
Cuando se trata de eso, los únicos archivos con los que realmente tengo problemas son CSV. Dependiendo del programa, debe o no debe tener una lista de materiales. Por ejemplo, si está utilizando Excel 2007+ en Windows, debe estar codificado con una lista de materiales si desea abrirlo sin problemas y no tener que recurrir a la importación de datos.
Cabe señalar que para algunos archivos no debe tener la lista de materiales, incluso en Windows. Los ejemplos son SQL*plus
o VBScript
archivos. En caso de que dichos archivos contengan una lista de materiales, obtendrá un error cuando intente ejecutarlos.
UTF-8 con BOM solo ayuda si el archivo realmente contiene algunos caracteres no ASCII. Si está incluido y no hay ninguno, posiblemente romperá las aplicaciones más antiguas que de otro modo habrían interpretado el archivo como ASCII simple. Estas aplicaciones definitivamente fallarán cuando se encuentren con un carácter que no sea ASCII, por lo que, en mi opinión, la lista de materiales solo debe agregarse cuando el archivo puede y ya no debe interpretarse como ASCII simple.
Quiero dejar en claro que prefiero no tener la lista de materiales. Agréguelo si alguna basura vieja se rompe sin él, y reemplazar esa aplicación heredada no es factible.
No haga nada, espere una lista de materiales para UTF-8.
Citado en la parte inferior de la página de Wikipedia en BOM: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
"El uso de una lista de materiales no es obligatorio ni recomendado para UTF-8, pero puede encontrarse en contextos donde los datos de UTF-8 se convierten de otras formas de codificación que usan una lista de materiales o donde la lista de materiales se usa como firma UTF-8"
UTF-8 sin BOM no tiene BOM, lo que no lo hace mejor que UTF-8 con BOM, excepto cuando el consumidor del archivo necesita saber (o se beneficiaría de saber) si el archivo está codificado con UTF-8 o no.
La lista de materiales suele ser útil para determinar la endianidad de la codificación, que no es necesaria para la mayoría de los casos de uso.
Además, la lista de materiales puede ser un ruido / dolor innecesario para aquellos consumidores que no lo conocen o no se preocupan por él, y puede generar confusión en el usuario.
Miro esto desde una perspectiva diferente. Creo que UTF-8 con BOM es mejor ya que proporciona más información sobre el archivo. Uso UTF-8 sin BOM solo si tengo problemas.
Estoy usando varios idiomas (incluso cirílico ) en mis páginas durante mucho tiempo y cuando los archivos se guardan sin BOM y los vuelvo a abrir para editarlos con un editor (como también notó Cherouvim ), algunos caracteres están dañados.
Tenga en cuenta que el Bloc de notas clásico de Windows guarda automáticamente los archivos con una BOM cuando intenta guardar un archivo recién creado con codificación UTF-8.
Personalmente guardo los archivos de secuencias de comandos del lado del servidor (.asp, .ini, .aspx) con BOM y archivos .html sin BOM .
chcp 65001
para el soporte de utf8, es utf8 sin bom. Si lo hace type myfile
, solo se mostrará correctamente si no hay bom. Si lo hace echo aaa>a.a
o echo אאא>a.a
para generar los caracteres para archivar aa, y tiene chcp 65001, se generará sin BOM.
Cuando desee mostrar información codificada en UTF-8, es posible que no tenga problemas. Declare, por ejemplo, un documento HTML como UTF-8 y tendrá todo lo que se muestra en su navegador que está contenido en el cuerpo del documento.
Pero este no es el caso cuando tenemos archivos de texto, CSV y XML, ya sea en Windows o Linux.
Por ejemplo, un archivo de texto en Windows o Linux, una de las cosas más fáciles imaginables, no es (generalmente) UTF-8.
Guárdelo como XML y declare como UTF-8:
<?xml version="1.0" encoding="UTF-8"?>
No se mostrará (no se leerá) correctamente, incluso si se declara como UTF-8.
Tenía una cadena de datos que contenía letras francesas, que debía guardarse como XML para la sindicación. Sin crear un archivo UTF-8 desde el principio (cambiando las opciones en IDE y "Crear nuevo archivo") o agregando la lista de materiales al comienzo del archivo
$file="\xEF\xBB\xBF".$string;
No pude guardar las letras francesas en un archivo XML.
Una diferencia práctica es que si escribe un script de shell para Mac OS X y lo guarda como UTF-8, obtendrá la respuesta:
#!/bin/bash: No such file or directory
en respuesta a la línea shebang que especifica qué shell desea usar:
#!/bin/bash
Si guarda como UTF-8, no BOM (digamos en BBEdit ) todo estará bien.
Como se mencionó anteriormente, UTF-8 con BOM puede causar problemas con software no compatible con BOM (o compatible). Una vez edité archivos HTML codificados como UTF-8 + BOM con el KompoZer basado en Mozilla , ya que un cliente requería ese programa WYSIWYG .
Invariablemente, el diseño se destruiría al guardar. Me tomó algo de tiempo dar vueltas a esto. Estos archivos funcionaron bien en Firefox, pero mostraron una peculiaridad CSS en Internet Explorer destruyendo el diseño, nuevamente. Después de jugar con los archivos CSS vinculados durante horas en vano, descubrí que a Internet Explorer no le gustaba el archivo HTML BOMfed. Nunca más.
Además, acabo de encontrar esto en Wikipedia:
Los caracteres shebang están representados por los mismos dos bytes en codificaciones ASCII extendidas, incluido UTF-8, que se usa comúnmente para scripts y otros archivos de texto en sistemas actuales tipo Unix. Sin embargo, los archivos UTF-8 pueden comenzar con la marca de orden de bytes opcional (BOM); si la función "exec" detecta específicamente los bytes 0x23 0x21, entonces la presencia de la lista de materiales (0xEF 0xBB 0xBF) antes del shebang evitará que se ejecute el intérprete de script. Algunas autoridades recomiendan no usar la marca de orden de bytes en scripts POSIX (similares a Unix), [15] por este motivo y para una mayor interoperabilidad y preocupaciones filosóficas.
Las Preguntas frecuentes sobre la marca de orden de bytes (BOM) de Unicode proporcionan una respuesta concisa:
P: ¿Cómo debo tratar con las listas de materiales?
A: Aquí hay algunas pautas a seguir:
Un protocolo particular (por ejemplo, las convenciones de Microsoft para archivos .txt) puede requerir el uso de la lista de materiales en ciertos flujos de datos Unicode, como archivos. Cuando necesite cumplir con dicho protocolo, use una lista de materiales.
Algunos protocolos permiten listas de materiales opcionales en el caso de texto sin etiquetar. En esos casos
Cuando se sabe que un flujo de datos de texto es texto sin formato, pero de codificación desconocida, BOM se puede usar como firma. Si no hay una lista de materiales, la codificación podría ser cualquier cosa.
Cuando se sabe que una secuencia de datos de texto es texto Unicode simple (pero no qué endian), entonces se puede usar BOM como firma. Si no hay una lista de materiales, el texto debe interpretarse como big-endian.
Algunos protocolos orientados a bytes esperan caracteres ASCII al comienzo de un archivo. Si se utiliza UTF-8 con estos protocolos, se debe evitar el uso de la lista de materiales como codificación de firma de formulario.
Cuando se conoce el tipo preciso del flujo de datos (por ejemplo, Unicode big-endian o Unicode little-endian), no se debe usar la lista de materiales. En particular, siempre que un flujo de datos se declare como UTF-16BE, UTF-16LE, UTF-32BE o UTF-32LE, no se debe utilizar una lista de materiales.
De http://en.wikipedia.org/wiki/Byte-order_mark :
La marca de orden de bytes (BOM) es un carácter Unicode que se utiliza para indicar la resistencia (orden de bytes) de un archivo o secuencia de texto. Su punto de código es U + FEFF. El uso de la lista de materiales es opcional y, si se usa, debe aparecer al comienzo de la secuencia de texto. Más allá de su uso específico como indicador de orden de bytes, el carácter BOM también puede indicar en cuál de las varias representaciones Unicode está codificado el texto.
Usar siempre una lista de materiales en su archivo garantizará que siempre se abra correctamente en un editor que admita UTF-8 y BOM.
Mi verdadero problema con la ausencia de BOM es el siguiente. Supongamos que tenemos un archivo que contiene:
abc
Sin BOM, esto se abre como ANSI en la mayoría de los editores. Entonces, otro usuario de este archivo lo abre y agrega algunos caracteres nativos, por ejemplo:
abg-αβγ
Vaya ... Ahora el archivo todavía está en ANSI y adivina qué, "αβγ" no ocupa 6 bytes, sino 3. Esto no es UTF-8 y esto causa otros problemas más adelante en la cadena de desarrollo.
Aquí está mi experiencia con Visual Studio, Sourcetree y Bitbucket, que me ha dado algunos problemas:
Por lo tanto, resulta que BOM con una firma incluirá un carácter de punto rojo en cada archivo al revisar una solicitud de extracción (puede ser bastante molesto).
Si se desplaza sobre él, mostrará un carácter como "ufeff", pero resulta que Sourcetree no muestra este tipo de marcas de byte, por lo que probablemente terminará en sus solicitudes de extracción, lo que debería estar bien porque así es como Visual Studio 2017 codifica nuevos archivos ahora, por lo que quizás Bitbucket debería ignorar esto o hacer que se muestre de otra manera, más información aquí:
UTF con una lista de materiales es mejor si usa UTF-8 en archivos HTML y si usa serbio cirílico, serbio latino, alemán, húngaro o algún idioma exótico en la misma página.
Esa es mi opinión (30 años de industria informática y de TI).