La marca de orden de bytes ( BOM ) es un uso particular del código de carácter especial Unicode , U+FEFF ANCHO CERO SIN ESPACIO DE INTERRUPCIÓN , cuya aparición como un número mágico al comienzo de un flujo de texto puede indicar varias cosas a un programa que lee el texto: [1]
El uso de BOM es opcional. Su presencia interfiere con el uso de UTF-8 por parte de software que no espera bytes que no sean ASCII al comienzo de un archivo, pero que de otro modo podría manejar el flujo de texto.
Unicode se puede codificar en unidades de números enteros de 8, 16 o 32 bits. Para las representaciones de 16 y 32 bits, un ordenador que recibe texto de fuentes arbitrarias necesita saber en qué orden de bytes están codificados los números enteros. El BOM se codifica en el mismo esquema que el resto del documento y se convierte en un punto de código Unicode no caracter si se intercambian sus bytes. Por lo tanto, el proceso que accede al texto puede examinar estos primeros bytes para determinar el orden de bytes, sin necesidad de ningún contrato o metadatos fuera del flujo de texto en sí. Por lo general, el ordenador receptor intercambiará los bytes a su propio orden de bytes, si es necesario, y ya no necesitará el BOM para el procesamiento.
La secuencia de bytes de la BOM difiere según la codificación Unicode (incluidas las que no pertenecen al estándar Unicode, como UTF-7 ; consulte la tabla siguiente) y es probable que ninguna de las secuencias aparezca al comienzo de secuencias de texto almacenadas en otras codificaciones. Por lo tanto, colocar una BOM codificada al comienzo de una secuencia de texto puede indicar que el texto es Unicode e identificar el esquema de codificación utilizado. Este uso de la BOM se denomina "firma Unicode". [2]
El BOM es, simplemente, el punto de código Unicode U+FEFF ZERO WIDTH NO-BREAK SPACE
, codificado en la codificación actual. Un archivo de texto que comienza con bytes FE FF
sugiere que el archivo está codificado en UTF-16 big-endian.
El nombre ZWNBSP debe utilizarse si la lista de materiales aparece en medio de un flujo de datos. Unicode indica que debe interpretarse como un punto de código normal (es decir, un conector de palabras ), no como una lista de materiales. Desde Unicode 3.2, este uso ha quedado obsoleto en favor de . [1]U+2060 WORD JOINER
El nombre Unicode 1.0 para este punto de código también es BYTE ORDER MARK
[3]
La representación UTF-8 de la lista de materiales es la secuencia de bytes ( hexadecimal ) EF BB BF
.
El estándar Unicode permite el BOM en UTF-8 , [4] pero no exige ni recomienda su uso. [5] UTF-8 siempre tiene el mismo orden de bytes, [6] por lo que su único uso en UTF-8 es señalar al inicio que el flujo de texto está codificado en UTF-8, o que se convirtió a UTF-8 desde un flujo que contenía un BOM opcional. El estándar tampoco recomienda eliminar un BOM cuando está allí, de modo que el viaje de ida y vuelta entre codificaciones no pierda información, y para que el código que depende de él siga funcionando. [7] [8] El IETF recomienda que si un protocolo (a) siempre utiliza UTF-8, o (b) tiene alguna otra forma de indicar qué codificación se está utilizando, entonces "DEBERÍA prohibir el uso de U+FEFF como firma". [9] Un ejemplo de no seguir esta recomendación es el protocolo IETF Syslog que requiere que el texto esté en UTF-8 y también requiere el BOM. [10]
Al no utilizar una lista de materiales, el texto puede ser compatible con versiones anteriores del software diseñado para ASCII extendido . Por ejemplo, muchos lenguajes de programación permiten bytes que no son ASCII en literales de cadena , pero no al comienzo del archivo.
No es necesario un BOM para detectar la codificación UTF-8. [ cita requerida ] UTF-8 es una codificación dispersa: una gran fracción de las posibles combinaciones de bytes no dan como resultado un texto UTF-8 válido. Es probable que los datos binarios y el texto en cualquier otra codificación contengan secuencias de bytes que no sean válidas como UTF-8, por lo que la existencia de dichas secuencias no válidas indica que el archivo no es UTF-8, mientras que la falta de secuencias no válidas es una indicación muy fuerte de que el texto es UTF-8. Prácticamente la única excepción es el texto que contiene solo bytes de rango ASCII, ya que puede ser una codificación de 7 bits que no sea ASCII, pero esto es poco probable en cualquier dato moderno e incluso entonces la diferencia con ASCII es menor (como cambiar '\' a '¥').
Los compiladores [11] e intérpretes de Microsoft , y muchos programas de software de Microsoft Windows como el Bloc de notas (anterior a Windows 10 Build 1903 [12] ) tratan la lista de materiales como un número mágico obligatorio en lugar de utilizar heurísticas. Estas herramientas añaden una lista de materiales al guardar texto como UTF-8 y no pueden interpretar UTF-8 a menos que la lista de materiales esté presente o el archivo contenga solo ASCII. Windows PowerShell (hasta 5.1) añadirá una lista de materiales cuando guarde documentos XML en formato UTF-8. Sin embargo, PowerShell Core 6 ha añadido un -Encoding
modificador en algunos cmdlets llamado utf8NoBOM para que el documento se pueda guardar sin lista de materiales. Google Docs también añade una lista de materiales al convertir un documento en un archivo de texto sin formato para su descarga.
En UTF-16U+FEFF
, se puede colocar un BOM ( ) como los primeros bytes de un archivo o secuencia de caracteres para indicar el orden de bytes de todas las unidades de código de 16 bits del archivo o secuencia. Si se intenta leer esta secuencia con el orden de bytes incorrecto, se intercambiarán los bytes, lo que generará el carácter U+FFFE
, que Unicode define como un " no carácter " que nunca debería aparecer en el texto.
FE FF
FF FE
Para los conjuntos de caracteres UTF-16BE y UTF-16LE registrados por IANA , no se debe utilizar una marca de orden de bytes porque los nombres de estos conjuntos de caracteres ya determinan el orden de bytes.
Si no hay una lista de materiales, es posible adivinar si el texto es UTF-16 y su orden de bytes buscando caracteres ASCII (es decir, un byte 0 adyacente a un byte en el rango 0x20-0x7E, también 0x0A y 0x0D para CR y LF). Un número grande (es decir, mucho mayor que el azar) en el mismo orden es una muy buena indicación de UTF-16 y si el 0 está en los bytes pares o impares indica el orden de bytes. Sin embargo, esto puede dar como resultado tanto falsos positivos como falsos negativos.
La cláusula D98 de conformidad (sección 3.10) del estándar Unicode establece que "el esquema de codificación UTF-16 puede o no comenzar con una BOM. Sin embargo, cuando no hay BOM y en ausencia de un protocolo de nivel superior, el orden de bytes del esquema de codificación UTF-16 es big-endian". Está abierto a interpretación si está en vigor o no un protocolo de nivel superior. Por ejemplo, se podría argumentar que los archivos locales de un ordenador para los que el orden de bytes nativo es little-endian están codificados como UTF-16LE de forma implícita. Por lo tanto, la presunción de big-endian se ignora ampliamente. El estándar de codificación W3C /WHATWG utilizado en HTML5 especifica que el contenido etiquetado como "utf-16" o "utf-16le" debe interpretarse como little-endian "para tratar con el contenido implementado". [13] Sin embargo, si hay una marca de orden de bytes, entonces esa BOM debe tratarse como "más autoritativa que cualquier otra cosa". [14]
Aunque se puede utilizar una BOM con UTF-32 , esta codificación rara vez se utiliza para la transmisión. De lo contrario, se aplican las mismas reglas que para UTF-16 .
El BOM para UTF-32 little-endian es el mismo patrón que el BOM de UTF-16 little-endian seguido de un carácter NUL de UTF-16, un ejemplo inusual de que el BOM es el mismo patrón en dos codificaciones diferentes. Los programadores que utilicen el BOM para identificar la codificación tendrán que decidir si es más probable que sea UTF-32 o UTF-16 con un primer carácter NUL.
Esta tabla ilustra cómo se representa la lista de materiales como una secuencia de bytes en varias codificaciones y cómo esas secuencias pueden aparecer en un editor de texto que interpreta cada byte como una codificación heredada ( Windows-1252 y notación de cursor para los controles C0 ):
38
, 39
, 2B
, o 2F
(ASCII 8
, 9
, +
o /
), dependiendo de cuál sea el siguiente carácter.U+FEFF
pertenece el punto de códigoTabla 2-4. Los siete esquemas de codificación Unicode
El uso de una BOM no es obligatorio ni recomendable para UTF-8, pero puede encontrarse en contextos en los que los datos UTF-8 se convierten a partir de otras formas de codificación que utilizan una BOM o en los que la BOM se utiliza como una firma UTF-8.
Sin embargo, dado que el código fuente de C++ se codificó como UTF-8 sin BOM (como es habitual en Linux), el compilador de Visual C++ asumió erróneamente que el código fuente se codificó como ANSI de Windows.