¿Cuál es la diferencia entre UTF-8 y UTF-8 sin BOM?


818

¿Qué es diferente entre UTF-8 y UTF-8 sin una lista de materiales ? ¿Cual es mejor?


77
UTF-8 se puede detectar automáticamente mejor por contenido que por BOM. El método es simple: intente leer el archivo (o una cadena) como UTF-8 y, si tiene éxito, suponga que los datos son UTF-8. De lo contrario, suponga que es CP1252 (o alguna otra codificación de 8 bits). Cualquier codificación de ocho bits que no sea UTF-8 seguramente contendrá secuencias que no están permitidas por UTF-8. El ASCII puro (7 bits) se interpreta como UTF-8, pero el resultado también es correcto de esa manera.
Tronic

39
El escaneo de archivos grandes para contenido UTF-8 lleva tiempo. Una lista de materiales hace que este proceso sea mucho más rápido. En la práctica, a menudo necesitas hacer ambas cosas. El culpable hoy en día es que todavía mucho contenido de texto no es Unicode, y todavía me encuentro con herramientas que dicen que sí lo hacen Unicode (por ejemplo, UTF-8) pero emiten su contenido en una página de códigos diferente.
Jeroen Wiert Pluimers

10
@Tronic Realmente no creo que "mejor" encaje en este caso. Depende del medio ambiente. Si está seguro de que todos los archivos UTF-8 están marcados con una lista de materiales, entonces comprobar la lista de materiales es la "mejor" manera, porque es más rápido y más confiable.
mg30rg

32
UTF-8 no tiene una lista de materiales. Cuando coloca un punto de código U + FEFF al comienzo de un archivo UTF-8, se debe tener especial cuidado al tratarlo. Esta es solo una de esas mentiras de nombres de Microsoft, como llamar a una codificación "Unicode" cuando no existe tal cosa.
tchrist 01 de

77
"El Mainframe moderno (y AIX) es poco endian UTF-8 consciente" UTF-8 no tiene un final ! ¡no hay que mezclar bytes para colocar pares o grupos de cuatro en el "orden" correcto para un sistema en particular! Para detectar una secuencia de bytes UTF-8, puede ser útil tener en cuenta que el primer byte de un "punto de código" de secuencia de varios bytes (los bytes que NO son ASCII "simples") tiene el bit MS establecido y todos de uno a tres más bits sucesivamente menos significativos seguidos de un bit de reinicio. El número total de esos bits establecidos es uno menos bytes que están en ese punto de código y TODOS tendrán el conjunto MSB ...
SlySven

Respuestas:


773

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.


114
Puede que no sea recomendable, pero desde mi experiencia en conversiones hebreas, la lista de materiales es a veces crucial para el reconocimiento UTF-8 en Excel, y puede marcar la diferencia entre el jibrish y el hebreo
Matanya

26
Puede que no se recomiende, pero hizo maravillas con mi script de PowerShell al intentar generar "æøå"
Marius

63
Independientemente de que el estándar no lo recomiende, está permitido, y prefiero tener algo que actúe como una firma UTF-8 en lugar de las alternativas de asumir o adivinar. El software compatible con Unicode debe / debe ser capaz de manejar su presencia, por lo que personalmente animo su uso.
Martineau

30
@ bames53: Sí, en un mundo ideal almacenar la codificación de archivos de texto como metadatos del sistema de archivos sería una mejor manera de preservarlo. Pero la mayoría de nosotros que vivimos en el mundo real no podemos cambiar el sistema de archivos de los sistemas operativos en los que se ejecutan nuestros programas, por lo que usar la firma BOM independiente de la plataforma del estándar Unicode parece la mejor y más práctica alternativa en mi humilde opinión.
Martineau

34
@martineau Ayer me encontré con un archivo con una lista de materiales UTF-8 que no era UTF-8 (era CP936). Lo lamentable es que los responsables de la inmensa cantidad de dolor causado por la lista de materiales UTF-8 son en gran parte ajenos a ella.
bames53

243

Las otras excelentes respuestas ya respondieron que:

  • No hay diferencia oficial entre UTF-8 y BOM-ed UTF-8
  • Una cadena BOM-ed UTF-8 comenzará con los tres bytes siguientes. EF BB BF
  • Esos bytes, si están presentes, deben ignorarse al extraer la cadena del archivo / secuencia.

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:

  • La cadena legítima ISO-8859-1 "ï» ¿ABC "
  • La legítima cadena UTF-8 "ABC"

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.


6060
@Alcott: Entendiste correctamente. La cadena [EF BB BF 41 42 43] es solo un montón de bytes. Necesita información externa para elegir cómo interpretarla. Si cree que esos bytes se codificaron utilizando ISO-8859-1, entonces la cadena es "ï» ¿ABC ". Si cree que esos bytes se codificaron con UTF-8, entonces es "ABC". Si no lo sabe, debe intentar averiguarlo. La lista de materiales podría ser una pista. La ausencia de caracteres no válidos cuando se decodifica como UTF-8 podría ser otra ... Al final, a menos que pueda memorizar / encontrar la codificación de alguna manera, una matriz de bytes es solo una matriz de bytes.
paercebal

19
@paercebal Si bien "ï» ¿"es válido latin-1, es muy poco probable que un archivo de texto comience con esa combinación. Lo mismo vale para los marcadores ucs2-le / be ÿþ y þÿ. Además nunca se puede saber.
user877329

16
@deceze Probablemente sea lingüísticamente inválido: Primero ï (que está bien), luego algunas comillas sin espacio intermedio (no está bien). ¿Indica que es español pero ï no se usa en español. Conclusión: no es latin-1 con una certeza muy por encima de la certeza sin ella.
user877329

20
@user Claro, no necesariamente tiene sentido. Pero si su sistema se basa en adivinar , ahí es donde entran las incertidumbres. Algunos usuarios malintencionados envían un texto que comienza con estas 3 letras a propósito, y su sistema de repente asume que está mirando UTF-8 con una lista de materiales, trata el texto como UTF-8 donde debería usar Latin-1, y se realiza una inyección Unicode. Solo un ejemplo hipotético, pero ciertamente posible. No puede juzgar una codificación de texto por su contenido, punto.
deceze

40
"Las codificaciones deben ser conocidas, no adivinadas". El corazón y el alma del problema. +1, buen señor. En otras palabras: estandarice su contenido y diga: "Siempre usamos esta codificación. Punto. Escríbalo de esa manera. Léalo de esa manera", o desarrolle un formato extendido que permita almacenar la codificación como metadatos. (Este último probablemente también necesita "codificación estándar de arranque" también. Como decir "La parte que le dice que la codificación es siempre ASCII").
jpmc26

135

Existen al menos tres problemas al colocar una lista de materiales en archivos codificados UTF-8.

  1. Los archivos que no contienen texto ya no están vacíos porque siempre contienen la lista de materiales.
  2. Los archivos que contienen texto que está dentro del subconjunto ASCII de UTF-8 ya no son ASCII porque la lista de materiales no es ASCII, lo que hace que algunas herramientas existentes se descompongan, y puede ser imposible para los usuarios reemplazar tales herramientas heredadas.
  3. No es posible concatenar varios archivos juntos porque cada archivo ahora tiene una lista de materiales al principio.

Y, como otros han mencionado, no es suficiente ni necesario tener una lista de materiales para detectar que algo es UTF-8:

  • No es suficiente porque una secuencia de bytes arbitraria puede comenzar con la secuencia exacta que constituye la lista de materiales.
  • No es necesario porque puede leer los bytes como si fueran UTF-8; si eso tiene éxito, es, por definición, UTF-8 válido.

8
En cuanto al punto 1 "Los archivos que no contienen texto ya no están vacíos porque siempre contienen la lista de materiales", esto (1) combina el nivel del sistema de archivos del sistema operativo con el nivel de contenido interpretado, más (2) supone incorrectamente que al usar la lista de materiales se debe poner un Lista de materiales también en todos los archivos vacíos. La solución práctica para (1) es no hacer (2). Esencialmente, la queja se reduce a "es posible colocar de manera poco práctica una lista de materiales en un archivo vacío, evitando así la detección más fácil de un archivo lógicamente vacío (al verificar el tamaño del archivo)". Aún así, un buen software debería ser capaz de manejarlo, ya que tiene un propósito.
Saludos y hth. - Alf

77
En cuanto al punto 2, "Los archivos que contienen texto ASCII ya no son ASCII", esto combina ASCII con UTF-8. Un archivo UTF-8 que contiene texto ASCII no es ASCII, es UTF-8. Del mismo modo, un archivo UTF-16 que contiene texto ASCII no es ASCII, es UTF-16. Y así. ASCII es un código de un solo byte de 7 bits. UTF-8 es una extensión de longitud variable de 8 bits de ASCII. Si las "herramientas se descomponen" debido a valores> 127, entonces no son aptas para un mundo de 8 bits. Una solución práctica simple es usar solo archivos ASCII con herramientas que se desglosan para valores de bytes no ASCII. Una solución probablemente mejor es deshacerse de esas herramientas malas.
Saludos y hth. - Alf

8
El punto 3, "No es posible concatenar varios archivos juntos porque cada archivo ahora tiene una lista de materiales al principio" es simplemente incorrecto. No tengo problemas para concatenar archivos UTF-8 con BOM, por lo que es claramente posible. Creo que tal vez quisiste decir que Unix-land catno te dará un resultado limpio , un resultado que solo tenga BOM al principio. Si quisiste decir eso, entonces es porque catfunciona en el nivel de byte, no en el nivel de contenido interpretado, y de manera similar catno 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.
Saludos y hth. - Alf

20
@ Cheersandhth.-Alf Esta respuesta es correcta. Simplemente estás señalando errores de Microsoft.
tchrist 01 de

99
@brighty: Sin embargo, la situación no mejora si se agrega un bom.
Deduplicador

84

Aquí hay ejemplos del uso de BOM que en realidad causan problemas reales y, sin embargo, muchas personas no lo saben.

BOM rompe scripts

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]

BOM es ilegal en JSON

Ver RFC 7159, Sección 8.1 :

Las implementaciones NO DEBEN agregar una marca de orden de bytes al comienzo de un texto JSON.

BOM es redundante en 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).

BOM rompe los analizadores JSON

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:

  1. UTF-32BE no comienza con tres NUL, por lo que no será reconocido
  2. UTF-32LE el primer byte no es seguido por tres NUL, por lo que no será reconocido
  3. UTF-16BE tiene solo un NUL en los primeros cuatro bytes, por lo que no será reconocido
  4. UTF-16LE tiene solo un NUL en los primeros cuatro bytes, por lo que no será reconocido

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.

Otros formatos de datos

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.

Otros usos de la lista de materiales

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.


55
rfc7159 que reemplaza a rfc4627 en realidad sugiere que apoyar BOM puede no ser tan malo. Básicamente, no tener una lista de materiales es solo un error ambiguo para que el viejo software de Windows y Unix que no sea compatible con Unicode pueda procesar utf-8.
Eric Grange

2
Parece que JSON necesita actualizarse para admitirlo, lo mismo con los scripts de Perl, Python, Ruby, Node.js. Solo porque estas plataformas optaron por no incluir soporte, no necesariamente mata el uso de BOM. Apple ha estado tratando de matar a Adobe durante algunos años, y Adobe todavía está presente. Pero una publicación esclarecedora.
htm11h

13
@EricGrange, parece que estás apoyando mucho la lista de materiales, ¡pero no te das cuenta de que esto haría que el formato de "texto plano" omnipresente, universalmente útil y con un mínimo óptimo sea una reliquia del pasado anterior a UTF8! Agregar cualquier tipo de encabezado (en banda) a la secuencia de texto sin formato impondría , por definición, un protocolo obligatorio a los archivos de texto más simples, ¡convirtiéndolo nunca más en el "más simple"! ¿Y para qué ganar? Para apoyar todas las otras , antiguas codificaciones CP que también no tienen firmas, por lo que podría confundir con UTF-8? (Por cierto, ASCII también es UTF-8. Entonces, ¿una lista de materiales para esos también?;) Vamos.)
Sz.

2
¡Esta respuesta es la razón por la que llegué a esta pregunta! ¡Creé mis scripts de bash en Windows y experimento muchos problemas al publicar esos scripts en Linux! Lo mismo con los archivos de Jason.
Tono Nam

2
Desearía poder votar esta respuesta unas cincuenta veces. También quiero agregar que en este punto, UTF-8 ha ganado la guerra de estándares, y casi todo el texto que se produce en Internet es UTF-8. Algunos de los lenguajes de programación más populares (como C # y Java) usan UTF-16 internamente, pero cuando los programadores que usan esos lenguajes escriben archivos para transmitir secuencias, casi siempre los codifican como UTF-8. Por lo tanto, ya no tiene sentido tener una lista de materiales para marcar un archivo UTF-8; UTF-8 debe ser el valor predeterminado que usa al leer, y solo intente otras codificaciones si falla la decodificación UTF-8.
rmunn

51

¿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 BFal 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.


8
Sin embargo, esto también invalidaría el UTF-8 válido con un solo byte erróneo: /
endolith

8
-1 re "Causa problemas con el software no compatible con BOM", eso nunca ha sido un problema para mí, pero por el contrario, la ausencia de BOM causa problemas con el software compatible con BOM (en particular Visual C ++) ha sido un problema problema. Por lo tanto, esta declaración es muy específica de la plataforma , un punto de vista estrecho de Unix-land, pero se presenta engañosamente como si se aplicara en general. Que no lo hace.
Saludos y hth. - Alf

66
No, UTF-8 no tiene BOM. Esta respuesta es incorrecta. Ver el estándar Unicode.
tchrist 01 de

2
Incluso puede pensar que tiene un archivo ASCII puro cuando solo mira los bytes. Pero también podría ser un archivo utf-16 donde tendría que mirar las palabras y no los bytes. El software moderno debe tener en cuenta las listas de materiales. Seguir leyendo utf-8 puede fallar si detecta secuencias inválidas, puntos de código que pueden usar una secuencia más pequeña o puntos de código que son sustitutos. Para utf-16 la lectura también puede fallar cuando hay sustitutos huérfanos.
brillante

1
@Alf, no estoy de acuerdo con su interpretación de una actitud que no es BOM como " específica de la plataforma , un punto de vista estrecho de Unix-land". Para mí, la única forma en que la mente estrecha podría estar en "Unix land" era si MS y Visual C ++ aparecieran antes de * NIX, lo que no sucedió. El hecho de que la EM (supongo que a sabiendas) comenzó a usar una lista de materiales en UTF-8 en lugar de UTF-16 me sugiere que promovieron romper 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.
bballdave025

30

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 )


66
Gracias por este excelente consejo en caso de que uno esté creando archivos UTF-8 para que Excel los use. Sin embargo, en otras circunstancias, seguiría las otras respuestas y me saltaría la lista de materiales.
barfuin

55
También es útil si crea archivos que contienen solo ASCII y más tarde pueden tener no ascii agregados. Acabo de encontrarme con un problema de este tipo: el software que espera utf8 crea un archivo con algunos datos para la edición del usuario. Si el archivo inicial contiene solo ASCII, se abre en algunos editores y luego se guarda, termina en latin-1 y todo se rompe. Si agrego la lista de materiales, el editor la detectará como UTF8 y todo funciona.
Roberto Alsina

1
He encontrado varias herramientas relacionadas con la programación que requieren que la BOM reconozca correctamente los archivos UTF-8 correctamente. Visual Studio, SSMS, SoureTree ....
kjbartel

55
¿Dónde lees una recomendación para usar una lista de materiales en ese RFC? A lo sumo, hay una fuerte recomendación de no prohibirlo en ciertas circunstancias donde hacerlo es difícil.
Deduplicador

8
Excel piensa que es ANSI y muestra galimatías, entonces el problema está en Excel.
Isaac

17

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.


Sí, solo pasé horas identificando un problema causado por un archivo codificado como UTF-8 en lugar de UTF-8 sin BOM. (El problema solo apareció en IE7, así que me llevó a una persecución
inútil

Futuros lectores: Tenga en cuenta que el problema del tweet que mencioné anteriormente no estaba estrictamente relacionado con la lista de materiales, pero si lo fuera, entonces el tweet sería confuso de una manera similar, pero al comienzo del tweet.
Halil Özgür

12
@ user984003 No, el problema es que Microsoft lo ha engañado. Lo que llama UTF-8 no es UTF-8. Lo que llama UTF-8 sin BOM es lo que realmente es UTF-8.
tchrist

lo que hace el complemento "sic" a su "sin juego de palabras"
JoelFan

2
@JoelFan No puedo recordar más, pero supongo que el juego de palabras podría haber sido intencionado a pesar del reclamo del autor :)
Halil Özgür

17

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 typey moreno 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 chcpcomando ofrece soporte para UTF-8 ( sin BOM) a través de la página de códigos 65001 .


55
Será mejor que me limite a SIN BOM . Descubrí que .htaccessy gzip compressionen 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
Chetabahana

1
'Otra motivación para no usar una lista de materiales es alentar a UTF-8 como la codificación "predeterminada". - ¡Lo cual es un argumento tan fuerte y válido, que podría haber detenido la respuesta allí! ...; -o A menos que tenga una mejor idea para la representación de texto universal, eso es. ;) (No sé cuántos años tienes, cuántos años tuviste que sufrir en la era anterior a la UTF8 (cuando los lingüistas consideraron desesperadamente incluso cambiar sus alfabetos), pero puedo decirte que cada segundo nos acercamos a librarnos el desorden de todas las antiguas codificaciones de un solo byte sin metadatos, en lugar de tener "el" es pura alegría.)
Sz.

Vea también este comentario acerca de cómo agregar una lista de materiales (¡o cualquier otra cosa!) Al más simple de los formatos de archivo de texto, "texto plano", significaría evitar que el mejor formato de codificación de texto universal sea ​​"simple" y "simple" (es decir, "sin gastos generales")! ...
Sz.

BOM es principalmente problemático en Linux porque, para empezar, muchas utilidades realmente no son compatibles con Unicode (por ejemplo, se truncarán felizmente en medio de los puntos de código). Para la mayoría de los demás entornos de software modernos, use BOM siempre que la codificación no sea inequívoca (a través de especificaciones o metadatos).
Eric Grange

9

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.

¿Por qué no se recomienda una lista de materiales?

  1. El software que no es compatible con Unicode o que no cumple con las normas puede asumir que es latin-1 o ANSI y no eliminará la lista de materiales de la cadena, lo que obviamente puede causar problemas.
  2. Realmente no es necesario (solo verifique si el contenido es compatible y siempre use UTF-8 como respaldo cuando no se pueda encontrar una codificación compatible)

¿Cuándo debe codificar con una lista de materiales?

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.


2
La última sección de su respuesta es 100% correcta: la única razón para usar una lista de materiales es cuando tiene que interactuar con un software defectuoso que no utiliza UTF-8 como predeterminado para analizar archivos desconocidos.
rmunn

8

Cabe señalar que para algunos archivos no debe tener la lista de materiales, incluso en Windows. Los ejemplos son SQL*pluso VBScriptarchivos. En caso de que dichos archivos contengan una lista de materiales, obtendrá un error cuando intente ejecutarlos.


8

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.


7

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"


2
¿Tiene algún ejemplo en el que el software decida si usar UTF-8 con / sin BOM, en función de si la codificación anterior de la que está codificando, tenía una BOM o no? Parece una afirmación absurda
barlop el

7

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.


2
"que no tiene uso para UTF-8 ya que de todos modos es de 8 bits por glifo". Er ... no, solo los glifos ASCII-7 son de 8 bits en UTF-8. Cualquier cosa más allá de eso será de 16, 24 o 32 bits.
Powerlord

3
"La lista de materiales suele ser útil para determinar la endianness de la codificación, que no es necesaria para la mayoría de los casos de uso". ... endianness simplemente no se aplica a UTF-8, independientemente del caso de uso
JoelFan

6

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 .


44
Gracias por el excelente consejo sobre el Bloc de notas clásico de Windows. Ya pasé algún tiempo descubriendo exactamente lo mismo. Mi consecuencia fue usar siempre Notepad ++ en lugar de Windows Classic Notepad. :-)
barfuin

Será mejor que uses madedit. Es el único editor que, en modo hexadecimal, muestra un carácter si selecciona una secuencia de bytes utf-8 en lugar de una base 1: 1 entre byte y carácter. ¡Un editor hexadecimal que conoce un archivo UTF-8 debería funcionar como lo hace madedit!
brillante

@brighty No creo que necesites uno a uno por el bien de la lista de materiales. no importa, no lleva mucho tiempo reconocer que una lista de materiales utf-8 es efbbbf o fffe (de fffe si se lee mal). Uno simplemente puede eliminar esos bytes. Sin embargo, no está mal tener un mapeo para el resto del archivo, pero también poder eliminar byte a byte también
barlop el

@barlop ¿Por qué querría eliminar una lista de materiales utf-8 si el contenido del archivo está codificado en utf-8? La lista de materiales es reconocida por los visores de texto modernos, los controles de texto y los editores de texto. Una vista uno a uno de una secuencia utf-8 no tiene sentido, ya que n bytes dan como resultado un carácter. Por supuesto, un editor de texto o un editor hexadecimal debería permitir eliminar cualquier byte, pero esto puede conducir a secuencias utf-8 no válidas.
brighty

@brighty utf-8 con bom es una codificación, y utf-8 sin bom es una codificación. El indicador de cmd usa utf8 sin bom .. así que si tiene un archivo utf8, ejecuta el comando chcp 65001para 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.ao echo אאא>a.a para generar los caracteres para archivar aa, y tiene chcp 65001, se generará sin BOM.
barlop

6

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.


1
FTM, en XML, creo que debería mantener el archivo como ASCII y utilizar entidades en su lugar.
Alois Mahdal

44
Sé que esta es una vieja respuesta, pero solo quiero mencionar que está mal. Los archivos de texto en Linux (no pueden hablar por otros Unixes) usualmente / son / UTF-8.
Functino

6

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.


8
Esto se debe a que Microsoft ha cambiado el significado de lo que dice el estándar. UTF-8 no tiene BOM: han creado Microsoft UTF-8 que inserta una BOM espuria frente a la secuencia de datos y luego le dijo que no, esto en realidad es UTF-8. No lo es. Solo se está extendiendo y corrompiendo.
tchrist

4

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.


4

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.


1

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.


99
Asegúrese de que aparezcan bytes espurios al comienzo de un software que no sea compatible con BOM. Hurra.
Romain

1
@Romain Muller: por ejemplo, PHP 5 arrojará errores "imposibles" cuando intente enviar encabezados después de la lista de materiales.
Piskvor salió del edificio

55
αβγ no es ascii, pero puede aparecer en codificaciones basadas en 8bit-ascii. El uso de una lista de materiales deshabilita un beneficio de utf-8, su compatibilidad con ascii (capacidad de trabajar con aplicaciones heredadas donde se usa ascii puro).
ctrl-alt-delor

1
Esta es la respuesta incorrecta. Una cadena con una lista de materiales en frente es algo completamente diferente. No se supone que esté allí y simplemente arruina todo.
Tchrist

Sin BOM, esto se abre como ANSI en la mayoría de los editores. Estoy totalmente de acuerdo Si esto sucede, tienes suerte si manejas la página de códigos correcta, pero de hecho es solo una suposición, porque la página de códigos no es parte del archivo. Una lista de materiales es.
Brighty

1

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).

Ingrese la descripción de la imagen aquí

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í:

Marcador de puntos rojos BitBucket diff view


-4

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).


1
Creo que esto también es cierto. Si utiliza caracteres fuera del primer conjunto ASCII 255 y omite la lista de materiales, los navegadores lo interpretan como ISO-8859-1 y obtiene caracteres confusos. Dadas las respuestas anteriores, esto aparentemente está en los vendedores de navegador que hacen lo incorrecto cuando no detectan una lista de materiales. Pero a menos que trabaje en Microsoft Edge / Mozilla / Webkit / Blink, no tiene más remedio que trabajar con los defectos que tienen estas aplicaciones.
asontu

UTF qué? UTF-8? UTF-16? ¿Algo más?
Peter Mortensen
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.