¿Por qué usamos Base64?


Wikipedia dice:

Los esquemas de codificación Base64 se utilizan comúnmente cuando hay una necesidad de codificar datos binarios que necesitan ser almacenados y transferidos a través de medios que están diseñados para tratar con datos textuales. Esto es para garantizar que los datos permanezcan intactos sin modificaciones durante el transporte.

Pero ¿no es que los datos siempre se almacenan/transmiten en binario porque la memoria que nuestras máquinas tienen almacena binario y solo depende de cómo lo interpretes? Por lo tanto, ya sea que codifique el patrón de bits 010011010110000101101110 como Man en ASCII o como TWFu en Base64, eventualmente almacenará el mismo patrón de bits.

Si la codificación definitiva es en términos de ceros y unos y cada máquina y medio puede lidiar con ellos, ¿qué importa si los datos se representan como ASCII o Base64?

¿Qué significa "medios que están diseñados para tratar con datos textuales"? Pueden tratar con binario = > pueden tratar con cualquier cosa.


Gracias todo el mundo, creo que ahora entiendo.

Cuando enviamos datos, no podemos estar seguros de que los datos se interpretarán en el mismo formato que pretendíamos que fuera. Por lo tanto, enviamos datos codificados en algún formato (como Base64) que ambas partes entiendan. De esa manera, incluso si el remitente y el receptor interpretan las mismas cosas de manera diferente, pero debido a que están de acuerdo en el formato codificado, los datos no se interpretarán incorrectamente.

De Ejemplo de Mark Byers

Si quiero enviar

Hello
world!

Una forma es enviarlo en ASCII como

72 101 108 108 111 10 119 111 114 108 100 33

Pero el byte 10 podría no ser interpretado correctamente como una nueva línea en el otro extremo. Por lo tanto, utilizamos un subconjunto de ASCII para codificarlo así

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

Que a costa de más datos transferidos por la misma cantidad de información asegura que el receptor pueda decodificar los datos de la manera prevista, incluso si el receptor tiene diferentes interpretaciones para el resto del conjunto de caracteres.

Author: mega6382, 2010-08-21

12 answers

Su primer error es pensar que la codificación ASCII y la codificación Base64 son intercambiables. No lo son. Se utilizan para diferentes propósitos.

  • Cuando codifica texto en ASCII, comienza con una cadena de texto y la convierte en una secuencia de bytes.
  • Cuando codifica datos en Base64, comienza con una secuencia de bytes y la convierte en una cadena de texto.

Para entender por qué Base64 era necesario en primer lugar necesitamos un poco de historia de computación.


Las computadoras se comunican en binarios - 0s y 1s - pero las personas generalmente desean comunicarse con datos de formularios más enriquecidos, como texto o imágenes. Para transferir estos datos entre computadoras primero tiene que ser codificado en 0s y 1s, enviado, luego decodificado de nuevo. Para tomar el texto como ejemplo, hay muchas formas diferentes de realizar esta codificación. Sería mucho más sencillo si todos pudiéramos ponernos de acuerdo sobre una única codificación, pero lamentablemente este no es el caso.

Originalmente mucho se crearon diferentes codificaciones (por ejemplo, Código Baudot) que usaron un número diferente de bits por carácter hasta que finalmente ASCII se convirtió en un estándar con 7 bits por carácter. Sin embargo, la mayoría de las computadoras almacenan datos binarios en bytes que consisten en 8 bits cada uno, por lo que ASCII no es adecuado para transferir este tipo de datos. Algunos sistemas incluso borrarían la parte más significativa. Además, la diferencia en las codificaciones de terminación de línea entre sistemas significa que los caracteres ASCII 10 y 13 también se modificaron a veces.

Para resolver estos problemas se introdujo la codificación Base64. Esto le permite codificar bytes aribtrarios a bytes que se sabe que son seguros para enviar sin corromperse (caracteres alfanuméricos ASCII y un par de símbolos). La desventaja es que codificar el mensaje usando Base64 aumenta su longitud-cada 3 bytes de datos se codifica a 4 caracteres ASCII.

Para enviar texto de forma fiable se puede primero codificar en bytes utilizando un codificación de texto de su elección (por ejemplo UTF-8) y luego después Base64 codifica los datos binarios resultantes en una cadena de texto que es seguro enviar codificada como ASCII. El receptor tendrá que revertir este proceso para recuperar el mensaje original. Esto, por supuesto, requiere que el receptor sepa qué codificaciones se utilizaron, y esta información a menudo debe enviarse por separado.

Históricamente se ha utilizado para codificar datos binarios en mensajes de correo electrónico donde el servidor de correo electrónico podría modificar los finales de línea. Un ejemplo más moderno es el uso de la codificación Base64 para incrustar datos de imagen directamente en el código fuente HTML. Aquí es necesario codificar los datos para evitar que caracteres como ' ' sean interpretados como etiquetas.


Aquí hay un ejemplo trabajado:

, deseo enviar un mensaje de texto con dos líneas

Hello
world!

Si lo envío como ASCII (o UTF-8) se verá así:

72 101 108 108 111 10 119 111 114 108 100 33

El byte 10 está dañado en algunos sistemas por lo que podemos basar 64 codifica estos bytes como una cadena Base64:

SGVsbG8sCndvcmxkIQ==

Que cuando se codifica usando ASCII se ve así:

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

Todos los bytes aquí son bytes seguros conocidos, por lo que hay muy pocas posibilidades de que cualquier sistema corrompa este mensaje. Puedo enviar esto en lugar de mi mensaje original y dejar que el receptor invierta el proceso para recuperar el mensaje original.

 201
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 18:02:29

Codificación de datos binarios en XML

Supongamos que desea incrustar un par de imágenes dentro de un documento XML. Las imágenes son datos binarios, mientras que el documento XML es texto. Pero XML no puede manejar datos binarios incrustados. Entonces, ¿cómo lo haces?

Una opción es codificar las imágenes en base64, convirtiendo los datos binarios en texto que XML puede manejar.

En Lugar de:

<images>
  <image name="Sally">{binary gibberish that breaks XML parsers}</image>
  <image name="Bobby">{binary gibberish that breaks XML parsers}</image>
</images>

Lo haces:

<images>
  <image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
  <image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
</images>

Y el analizador XML podrá analizar el documento XML correctamente y extraer los datos de la imagen.

 39
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-19 21:24:13

¿Por qué no mirar a el RFC que actualmente define Base64?

La codificación base de datos se utiliza en muchas situaciones para almacenar o transferir
datos en entornos que, tal vez para razones heredadas, están restringidas a Datos US-ASCII [1].La codificación base puede también se puede utilizar en nuevas aplicaciones que no tienen restricciones heredadas, simplemente porque lo hace posible para manipular objetos con texto Editor.

En el pasado, diferentes aplicaciones tener tenía diversos requisitos y por lo tanto, a veces se implementa la base codificaciones en ligeramente diferentes formas. Hoy en día, las especificaciones del protocolo a veces utilice codificaciones base en general, y "base64" en particular, sin una descripción precisa o referencia. Correo Multipropósito por Internet Extensions (MIME) [4] se utiliza a menudo como referencia para base64 sin considerando las consecuencias para envoltura de líneas o sin alfabeto caracter. El propósito de esto especificación es establecer común alfabeto y codificación consideración. Esto esperanzadamente reducir la ambigüedad en otros documentos, lo que conduce a una mejor interoperabilidad.

Base64 fue originalmente ideado como una forma de permitir que los datos binarios se adjunten a los correos electrónicos como parte de las Extensiones de Correo Multipropósito de Internet.

 31
Author: Billy ONeal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 15:39:00

Los medios que están diseñados para datos textuales también son, por supuesto, binarios, pero los medios textuales a menudo usan ciertos valores binarios para los caracteres de control. Además, los medios textuales pueden rechazar ciertos valores binarios como no texto.

Base64 encoding codifica los datos binarios como valores que solo pueden interpretarse como texto en medios textuales, y está libre de caracteres especiales y/o caracteres de control, de modo que los datos también se conservarán en los medios textuales.

 21
Author: Håvard S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 15:25:22

Es más que el medio valida la codificación de cadena, por lo que queremos asegurarnos de que los datos sean aceptables para una aplicación de manejo (y no contengan una secuencia binaria que represente EOL, por ejemplo)

Imagine que desea enviar datos binarios en un correo electrónico con codificación UTF-8 The El correo electrónico puede no mostrarse correctamente si el flujo de unos y ceros crea una secuencia que no es válida Unicode en la codificación UTF-8.

El mismo tipo de cosas sucede en las URL cuando queremos codificar caracteres no válidos para una URL en la propia URL:

Http://www.foo.com/hello mi amigo -> http://www.foo.com/hello%20my%20friend

Esto se debe a que queremos enviar un espacio a través de un sistema que pensará que el espacio es apestoso.

Todo lo que estamos haciendo es asegurar que haya un mapeo 1-a-1 entre una secuencia de bits bien conocida, aceptable y no perjudicial a otra secuencia literal de bits, y que el manejo aplicación no distingue la codificación.

En su ejemplo, man puede ser ASCII válido en primera forma; pero a menudo es posible que desee transmitir valores que son binarios aleatorios (es decir, enviar una imagen en un correo electrónico):

MIME-Version: 1.0
Contenido-Descripción: "Base64 encode of a.gif"
Content-Type: image / gif; name="a.gif"
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename="a.gif"

Aquí vemos que una imagen GIF está codificada en base64 como un trozo de un correo electrónico. El cliente de correo electrónico lee los encabezados y los decodifica. Debido a la codificación, podemos estar seguros de que el GIF no contiene nada que pueda interpretarse como protocolo y evitamos insertar datos que SMTP o POP puedan encontrar significativos.

 15
Author: Aiden Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 15:35:07

Un ejemplo de cuando me pareció conveniente fue cuando intentaba incrustar datos binarios en XML. Algunos de los datos binarios estaban siendo malinterpretados por el analizador SAX porque esos datos podrían ser literalmente cualquier cosa, incluyendo caracteres especiales XML. Base64 codificando los datos en el extremo transmisor y decodificándolos en el extremo receptor solucionó ese problema.

 11
Author: Bill the Lizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

La mayoría de las computadoras almacenan datos en formato binario de 8 bits, pero esto no es un requisito. Algunas máquinas y medios de transmisión solo pueden manejar 7 bits (o tal vez incluso menos) a la vez. Tal medio interpretaría el flujo en múltiplos de 7 bits, por lo que si enviara datos de 8 bits, no recibirá lo que espera del otro lado. Base-64 es solo una forma de resolver este problema: codificar la entrada en un formato de 6 bits, enviarla a través de su medio y decodificarla de nuevo al formato de 8 bits en el recepción.

 8
Author: casablanca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 15:32:17

Base64 en lugar de escapar caracteres especiales

Les daré un ejemplo muy diferente pero real: escribo código javascript para ser ejecutado en un navegador. Las etiquetas HTML tienen valores ID, pero hay restricciones sobre qué caracteres son válidos en un ID.

Pero quiero que mi ID se refiera sin pérdidas a los archivos de mi sistema de archivos. Los archivos en realidad pueden tener todo tipo de personajes extraños y maravillosos en ellos desde signos de exclamación, caracteres acentuados, tilde, incluso emoji! No puedo hacer esto:

<div id="/path/to/my_strangely_named_file!@().jpg">
    <img src="http://myserver.com/path/to/my_strangely_named_file!@().jpg">
    Here's a pic I took in Moscow.
</div>

Supongamos que quiero ejecutar un código como este:

# ERROR
document.getElementById("/path/to/my_strangely_named_file!@().jpg");

Creo que este código fallará cuando se ejecute.

Con Base64 puedo hacer referencia a algo complicado sin preocuparme por qué idioma permite qué caracteres especiales y cuáles necesitan escapar:

document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");

A diferencia del uso de una MD5 o alguna otra función de hash, puede invertir la codificación para averiguar qué datos eran exactamente tan útiles.

Desearía saber sobre Base64 hace años. Lo haría he evitado arrancarme el pelo con 'encodeURIComponent ' y str.replace(‘\n’,’\\n’)

 6
Author: Sridhar-Sarnobat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 06:19:58

¿Qué significa " medios que son diseñado para tratar con datos textuales"?

Que esos protocolos fueron diseñados para manejar texto (a menudo, solo texto en inglés) en lugar de datos binarios (como .png y .imágenes jpg).

Pueden tratar con binary = > pueden lidia con cualquier cosa.

Pero lo contrario no es cierto. Un protocolo diseñado para representar texto puede tratar incorrectamente los datos binarios que contienen:

  • Los bytes 0x0A y 0x0D, utilizados para finales de línea, que difieren según la plataforma.
  • Otros caracteres de control como 0x00 (NULL = C string terminator), 0x03 (END OF TEXT), 0x04 (END OF TRANSMISSION), o 0x1A (DOS end-of-file) que pueden señalar prematuramente el final de los datos.
  • Bytes por encima de 0x7F (si el protocolo que fue diseñado para ASCII).
  • Secuencias de bytes que no son válidas UTF-8.

Así que no puedes enviar datos binarios a través de un protocolo basado en texto. Estás limitado a los bytes que representan los caracteres ASCII no-espacio no-control, de los cuales hay 94. La razón por la que se eligió Base 64 fue que es más rápido trabajar con poderes de dos, y 64 es el más grande que funciona.

Una pregunta sin embargo. ¿Cómo es eso sistemas todavía no están de acuerdo en un común técnica de codificación como la tan común ¿UTF-8?

En la Web, al menos, en su mayoría tienen. La mayoría de los sitios utilizan UTF-8.

El problema en Occidente es que hay un mucho software viejo que ass-u-me-s que 1 byte = 1 carácter y no puede trabajar con UTF-8.

El problema en el Este es su apego a codificaciones como GB2312 y Shift_JIS.

Y el hecho de que Microsoft parece todavía no ha superado haber elegido la codificación UTF incorrecta. Si desea utilizar la API de Windows o la biblioteca de tiempo de ejecución de Microsoft C, está limitado a UTF-16 o la codificación "ANSI" de la configuración regional. Esto hace que sea doloroso usar UTF-8 porque tienes que convertir todos los tiempo.

 4
Author: dan04,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 18:24:34

Además de las otras respuestas (algo largas): incluso ignorando sistemas antiguos que solo admiten ASCII de 7 bits, los problemas básicos con el suministro de datos binarios en modo texto son:

  • Las nuevas líneas se transforman típicamente en modo texto.
  • Uno debe tener cuidado de no tratar un byte NUL como el final de una cadena de texto, lo cual es demasiado fácil de hacer en cualquier programa con linaje C.
 3
Author: jamesdlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 17:27:58

¿Qué significa "medios que están diseñados para tratar con datos textuales"?

En los días en que ASCII gobernaba el mundo, lidiar con valores no ASCII era un dolor de cabeza. La gente saltó a través de todo tipo de aros para obtener estos transferidos a través del cable sin perder información.

 2
Author: dirkgently,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 15:24:34

¿Por qué/ Cómo usamos la codificación Base64?

Base64 es uno de los esquemas de codificación binario a texto que tiene una eficiencia del 75%. Se utiliza para que los datos binarios típicos (como las imágenes) puedan enviarse de forma segura a través de canales heredados "no limpios de 8 bits". En las redes de correo electrónico anteriores (hasta principios de la década de 1990), la mayoría de los mensajes de correo electrónico eran de texto plano en el conjunto de caracteres US-ASCII de 7 bits. Muchos de los primeros estándares del protocolo comm fueron diseñados para trabajar sobre enlaces comm de "7 bits" "no limpios de 8 bits". La eficiencia del esquema es la proporción entre el número de bits en la entrada y el número de bits en la salida codificada. Hexadecimal (Base16) es también uno de los esquemas de codificación binario a texto con un 50% de eficiencia.

Pasos de codificación Base64 (Simplificado):

  1. Los datos binarios se organizan en trozos continuos de 24 bits (3 bytes) cada uno.
  2. Cada trozo de 24 bits se agrupa en cuatro partes de 6 bits cada una.
  3. Cada grupo de 6 bits se convierte en sus valores de caracteres Base64 correspondientes, es decir, codificación Base64 convierte tres octetos en cuatro caracteres codificados. La relación entre los bytes de salida y los bytes de entrada es de 4:3 (33% de sobrecarga).
  4. Curiosamente, los mismos caracteres se codificarán de manera diferente dependiendo de su posición dentro del grupo de tres octetos que se codifica para producir los cuatro caracteres.
  5. El receptor tendrá que revertir este proceso para recuperar el mensaje original.
 1
Author: Mushtaq Hussain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-17 19:01:16