¿Para qué se usa la codificación base 64?


782

He escuchado a personas hablar sobre "codificación base 64" aquí y allá. ¿Para qué se usa esto?


1
Del manual para base64_encode () : "Esta codificación está diseñada para hacer que los datos binarios sobrevivan al transporte a través de capas de transporte que no están limpias de 8 bits, como los cuerpos de correo".
still_dreaming_1

Respuestas:


941

Cuando tiene algunos datos binarios que desea enviar a través de una red, generalmente no lo hace simplemente transmitiendo los bits y bytes a través del cable en un formato sin formato. ¿Por qué? porque algunos medios están hechos para transmitir texto. Nunca se sabe: algunos protocolos pueden interpretar sus datos binarios como caracteres de control (como un módem), o sus datos binarios se pueden arruinar porque el protocolo subyacente podría pensar que ha ingresado una combinación de caracteres especial (como la forma en que FTP traduce la línea terminaciones).

Para evitar esto, las personas codifican los datos binarios en caracteres. Base64 es uno de estos tipos de codificaciones.

¿Por qué 64?
Debido a que generalmente puede confiar en que los mismos 64 caracteres están presentes en muchos conjuntos de caracteres, y puede estar razonablemente seguro de que sus datos terminarán sin corrupción en el otro lado del cable.


104
(En teoría, podría hacer una codificación de base 80 o algo similar, pero sería significativamente más difícil. Las potencias de dos son bases naturales para el binario)
Jon Skeet

13
@yokees: No hay garantía, son solo personajes que casi siempre son seguros. Es por eso que hay múltiples formas de Base-64 ( en.wikipedia.org/wiki/Base-64 ).

8
¿Eso significa que todo el paso de datos de tipo de red debería usar algún tipo de codificación?
Tanner Summers

66
Pero, ¿por qué se utiliza el método base64 para codificar datos de cadena? por ejemplo, en la función atob de javascript ¿Hay algún significado para que el servidor codifique un archivo json en formato base64? Los caracteres especiales podrían ser un caso de uso, pero ¿por qué no utf8 en ese caso, son equivalentes? Cualquier otro recurso relacionado con eso sería muy apreciado, gracias.
partizanos

44
Sería bueno tener una lista de al menos algunos protocolos que fallarían si alguien lo sabe.
Tadej

202

Básicamente es una forma de codificar datos binarios arbitrarios en texto ASCII. Toma 4 caracteres por 3 bytes de datos, más potencialmente un poco de relleno al final.

Esencialmente, cada 6 bits de la entrada está codificada en un alfabeto de 64 caracteres. El alfabeto "estándar" usa AZ, az, 0-9 y + y /, con = como carácter de relleno. Hay variantes seguras para URL.

Wikipedia es una fuente razonablemente buena de más información.


En un lenguaje como php, de dónde vendrán los datos binarios. Casi siempre trabajamos con datos de cadena que son texto.
Cholthi Paul Ttiopic

3
@CholthiPaulTtiopic: Los resultados de cifrado o compresión, o sonido / imágenes / video.
Jon Skeet

1
@CholthiPaulTtiopic: Me temo que no tengo idea de lo que quieres decir con "qué pasa con el almacenamiento", pero en este punto creo que estamos un poco fuera de tema.
Jon Skeet

2
@CholthiPaulTtiopic: Evitaría pensar en términos de "cadena binaria". Los datos binarios deben tratarse como datos binarios, y no como texto. He visto literalmente cientos, posiblemente miles, de preguntas sobre SO que básicamente se reducen a personas que no se preocupan demasiado por esta distinción.
Jon Skeet

1
@ still_dreaming_1 PHP los llama binary strings. (fuente) php.net/manual/en/function.pack.php
Cholthi Paul Ttiopic


116

Es una codificación textual de datos binarios donde el texto resultante no tiene más que letras, números y los símbolos "+", "/" y "=". Es una forma conveniente de almacenar / transmitir datos binarios a través de medios que se utilizan específicamente para datos textuales.

¿Pero por qué Base-64? Las dos alternativas para convertir datos binarios en texto que se me ocurren de inmediato son:

  1. Decimal: almacena el valor decimal de cada byte como tres números: 045 112 101 037 etc. donde cada byte está representado por 3 bytes. Los datos se hinchan tres veces.
  2. Hexadecimal: almacena los bytes como pares hexadecimales: AC 47 0D 1A, etc., donde cada byte está representado por 2 bytes. Los datos se hinchan dos veces.

Base-64 asigna 3 bytes (8 x 3 = 24 bits) en 4 caracteres que abarcan 6 bits (6 x 4 = 24 bits). El resultado se parece a "TWFuIGlzIGRpc3Rpb ...". Por lo tanto, la hinchazón es solo 4/3 = 1.3333333 veces la original.


10
¿Entiendo correctamente, que 64 es la mejor opción ya que es la potencia más alta de dos que es convertible a un carácter ASCII imprimible (hay 95 de ellas)?
voho

Si en ambos casos son 24 bits, ¿no es la hinchazón 1: 1? O cuando dice 4 caracteres que abarcan 6 bits, ¿quiere decir que en realidad hay 8 bits por carácter pero los dos primeros son 0s rellenados?
David Klempfner

1
@Backwards_Dave Cada 6 bits se expresan en 8 bits. Entonces la hinchazón es de 8: 6 o 4: 3.
Ates Goral

82

Aparte de lo que ya se ha dicho, dos usos muy comunes que no se han enumerado son

Hashes:

Los hashes son funciones unidireccionales que transforman un bloque de bytes en otro bloque de bytes de un tamaño fijo, como 128 bits o 256 bits (SHA / MD5). La conversión de los bytes resultantes en Base64 hace que sea mucho más fácil mostrar el hash, especialmente cuando se compara una suma de comprobación para la integridad. Los hashes se ven tan a menudo en Base64 que muchas personas confunden a Base64 con un hash.

Criptografía:

Dado que una clave de cifrado no tiene que ser texto sino bytes sin formato, a veces es necesario almacenarla en un archivo o base de datos, lo que Base64 es útil para. Lo mismo con los bytes cifrados resultantes.

Tenga en cuenta que aunque Base64 se usa a menudo en criptografía no es un mecanismo de seguridad. Cualquiera puede convertir la cadena Base64 nuevamente a sus bytes originales, por lo que no debe usarse como un medio para proteger los datos, solo como un formato para mostrar o almacenar bytes sin procesar con mayor facilidad.

Certificados

Los certificados x509 en formato PEM están codificados en base 64. http://how2ssl.com/articles/working_with_pem_files/


44
En realidad, es más fácil, procesando, almacenar bytes como bytes en muchos casos. Incluso en una base de datos, y especialmente en un archivo (si se usan registros de longitud fija, o los bytes son el único contenido). Base64 se usa típicamente cuando esos bytes están destinados a ser transmitidos en algún lugar, particularmente a través de un canal que podría cortar bits o interpretar algunos de los bytes como códigos de control.
cHao

Nunca he visto un hash escrito como enteros de 8 bits sin signo, 0,1,255,36 ... y mostrarlo con UTF-8 o cualquier otra codificación no tendría sentido, ¿de qué otra manera lo mostrarías más que con base64? Las claves de cifrado y los datos cifrados a menudo se almacenan en archivos de configuración y XML donde no puede almacenar los bytes sin formato. Estoy de acuerdo si puede almacenarlo como bytes sin procesar, por todos los medios, pero base64 es para esas situaciones en las que no puede. Hay muchos usos de base64 más allá de la transmisión. Estos son simplemente dos escenarios comunes donde lo verá.
Despertar

1
Mostraría el hash como hexadecimal, no decimal. Para los hashes, de hecho es mucho más común que base64.
cHao

@ cHao Sí, esto también es común. Los dígitos hexadecimales pueden representar cualquier dato binario, pero la base 64 tiene la ventaja de ocupar mucho menos espacio ya que usa más caracteres.
Despertar

45

Hace años, cuando se introdujo la funcionalidad de envío de correos, de modo que estaba completamente basada en texto, a medida que pasaba el tiempo, surgió la necesidad de adjuntos como imágenes y medios (audio, video, etc.). Cuando estos archivos adjuntos se envían a través de Internet (que es básicamente en forma de datos binarios), la probabilidad de que los datos binarios se corrompan es alta en su forma cruda. Entonces, para abordar este problema, apareció BASE64.

El problema con los datos binarios es que contiene caracteres nulos que en algunos lenguajes como C, C ++ representan el final de la cadena de caracteres, por lo que el envío de datos binarios en forma cruda que contenga bytes NULL evitará que un archivo se lea completamente y genere datos corruptos.

Por ejemplo :

En C y C ++, este carácter "nulo" muestra el final de una cadena. Entonces "HOLA" se almacena así:

HOLA

72 69 76 76 79 00

El 00 dice "detente aquí".

Ahora veamos cómo funciona la codificación BASE64.

Punto a tener en cuenta: la longitud de la cadena debe ser múltiplo de 3.

Ejemplo 1 :

Cadena a codificar: "as", Longitud = 3

1) Convierta cada carácter a decimal.

a = 97, c = 99, e = 101

ingrese la descripción de la imagen aquí

2) Cambie cada decimal a una representación binaria de 8 bits.

97 = 01100001, 99 = 01100011, 101 = 01100101

Combinado: 01100001 01100011 01100101

3) Separar en un grupo de 6 bits.

011000 010110 001101 100101

4) Calcular binario a decimal

011000 = 24, 010110 = 22, 001101 = 13, 100101 = 37

5) Caracteres decimales encubiertos a base64 usando el gráfico base64.

24 = Y, 22 = W, 13 = N, 37 = l

"As" => "YWNl"

ingrese la descripción de la imagen aquí

Ejemplo 2

Cadena a codificar: "abcd" Longitud = 4, no es múltiplo de 3. Por lo tanto, para que la longitud de la cadena sea múltiplo de 3, debemos agregar un relleno de 2 bits para hacer una longitud = 6. El bit de relleno se representa con el signo "=".

Punto a tener en cuenta: un bit de relleno equivale a dos ceros 00, por lo que dos bits de relleno equivalen a cuatro ceros 0000.

Entonces, comencemos el proceso: -

1) Convierta cada carácter a decimal.

a = 97, b = 98, c = 99, d = 100

2) Cambie cada decimal a una representación binaria de 8 bits.

97 = 01100001, 98 = 01100010, 99 = 01100011, 100 = 01100100

3) Separar en un grupo de 6 bits.

011000, 010110, 001001, 100011, 011001, 00

así que el último 6 bits no está completo, por lo que insertamos dos bits de relleno que equivalen a cuatro ceros "0000".

011000, 010110, 001001, 100011, 011001, 000000 ==

Ahora es igual. Dos signos iguales al final muestran que se agregaron 4 ceros (ayuda en la decodificación).

4) Calcular binario a decimal.

011000 = 24, 010110 = 22, 001001 = 9, 100011 = 35, 011001 = 25, 000000 = 0 ==

5) Caracteres decimales encubiertos a base64 usando el gráfico base64.

24 = Y, 22 = W, 9 = j, 35 = j, 25 = Z, 0 = A ==

“Abcd” => “YWJjZA ==”


55
esta es realmente una gran explicación
maheshmnj

28

En los primeros días de las computadoras, cuando la comunicación entre sistemas de la línea telefónica no era particularmente confiable, se usaba un método rápido y sucio para verificar la integridad de los datos: "paridad de bits". En este método, cada byte transmitido tendría 7 bits de datos, y el octavo sería 1 o 0, para forzar que el número total de 1 bits en el byte sea par.

Por lo tanto, 0x01 se transmitiría como 0x81; 0x02 sería 0x82; 0x03 seguiría siendo 0x03, etc.

Para promover este sistema, cuando se definió el conjunto de caracteres ASCII, solo se asignaron caracteres 00-7F. (Todavía hoy, todos los caracteres establecidos en el rango 80-FF no son estándar)

Muchos enrutadores del día ponen la verificación de paridad y la traducción de bytes en hardware, lo que obliga a las computadoras conectadas a ellos a tratar estrictamente con datos de 7 bits. Esto obliga a que los archivos adjuntos de correo electrónico (y todos los demás datos, por eso los protocolos HTTP y SMTP están basados ​​en texto), se conviertan a un formato de solo texto.

Pocos de los enrutadores sobrevivieron en los años 90. Dudo mucho que alguno de ellos esté en uso hoy.


2
Este es un excelente punto de discusión y una interesante lección de historia, gracias.
Dan Bechard

26

De http://en.wikipedia.org/wiki/Base64

El término Base64 se refiere a una codificación de transferencia de contenido MIME específica. También se usa como un término genérico para cualquier esquema de codificación similar que codifique datos binarios tratándolos numéricamente y traduciéndolos en una representación de base 64. La elección particular de la base se debe al historial de codificación del conjunto de caracteres: se puede elegir un conjunto de 64 caracteres que es parte del subconjunto común a la mayoría de las codificaciones y también imprimible. Esta combinación hace que sea improbable que los datos se modifiquen en tránsito a través de sistemas, como el correo electrónico, que tradicionalmente no estaban limpios en 8 bits.

Base64 se puede usar en una variedad de contextos:

  • Evolution y Thunderbird utilizan Base64 para ofuscar contraseñas de correo electrónico [1]
  • Base64 se puede usar para transmitir y almacenar texto que de otro modo podría causar colisión del delimitador
  • Base64 a menudo se usa como un acceso directo rápido pero inseguro para ocultar secretos sin incurrir en la sobrecarga de la administración de claves criptográficas

  • Los spammers usan Base64 para evadir las herramientas básicas antispam, que a menudo no decodifican Base64 y, por lo tanto, no pueden detectar palabras clave en mensajes codificados.

  • Base64 se usa para codificar cadenas de caracteres en archivos LDIF
  • Base64 a veces se usa para incrustar datos binarios en un archivo XML, usando una sintaxis similar a ...... por ejemplo, bookmarks.html de Firefox.
  • Base64 también se utiliza cuando se comunica con los dispositivos de impresión de Firma Fiscal del gobierno (generalmente, a través de puertos seriales o paralelos) para minimizar el retraso al transferir caracteres de recibo para la firma.
  • Base64 se utiliza para codificar archivos binarios, como imágenes dentro de scripts, para evitar depender de archivos externos.
  • Se puede utilizar para incrustar datos de imagen sin procesar en una propiedad CSS como background-image.

11

Algunos protocolos de transporte solo permiten la transmisión de caracteres alfanuméricos. Imagine una situación en la que los caracteres de control se utilizan para activar acciones especiales y / o que solo admite un ancho de bits limitado por carácter. Base64 transforma cualquier entrada en una codificación que solo usa caracteres alfanuméricos +, /y =como un carácter de relleno.


9

El uso de Base64 que voy a describir aquí es un truco. Entonces, si no te gustan los hacks, no continúes.

Me metí en problemas cuando descubrí que utf8 de MySQL no admite caracteres unicode de 4 bytes, ya que usa una versión de 3 bytes de utf8. Entonces, ¿qué hice para admitir unicode completo de 4 bytes sobre utf8 de MySQL? Bueno, las cadenas de codificación base64 cuando se almacenan en la base de datos y la decodificación base64 cuando se recuperan.

Dado que la codificación y decodificación base64 es muy rápida, lo anterior funcionó perfectamente.

Tiene los siguientes puntos a tener en cuenta:

  • La codificación Base64 utiliza un 33% más de almacenamiento

  • Las cadenas almacenadas en la base de datos no podrán ser leídas por los humanos (podría venderlo como una característica de que las cadenas de la base de datos usan una forma básica de cifrado).

Puede usar el método anterior para cualquier motor de almacenamiento que no sea compatible con Unicode.


66
"Podrías vender eso como una característica de que las cadenas de bases de datos usan una forma básica de encriptación" Me gusta tu estilo: D
Ercan

8
"Podrías vender eso como una característica de que las cadenas de bases de datos usan una forma básica de encriptación" qué cosa más horrible decir: D
Alex

1
forma básica de encriptación contra cualquiera que no tenga el algoritmo de decodificación base64 rofl: D
Eladian

1
@Alex No es para nada una "cosa horrible que decir". Los datos confidenciales de segundo grado pueden codificarse en base64 para que los administradores de db no puedan leerlos. No siempre es necesario tener el nivel más alto de encriptación para cada pieza de datos. Por ejemplo, si desea ocultar "comentarios" de un administrador de base de datos, entonces base64 es adecuado para el trabajo. Gratcias!
Basil Musa

1
Vale la pena mencionar que MySQL ahora tiene soporte para todo Unicode, aunque para propósitos de compatibilidad con versiones anteriores, su utf8tipo todavía es de solo tres bytes; si quieres lo real, úsalo utf8mb4. Bonito truco, pero ya no es necesario.
TRiG

7

Se utiliza para convertir datos binarios arbitrarios a texto ASCII.

Por ejemplo, los archivos adjuntos de correo electrónico se envían de esta manera.


7

Lo uso en un sentido práctico cuando transferimos objetos binarios grandes (imágenes) a través de servicios web. Entonces, cuando estoy probando un servicio web C # usando un script python, el objeto binario se puede recrear con un poco de magia.

[En python]

import base64
imageAsBytes = base64.b64decode( dataFromWS )

1
¿Los datos viajan más rápido?
FelipeM

1
@FelipeM más lento, no más rápido. Base64 tiene un 33% de gastos generales (por el precio de la seguridad).
Juraj

6

“Los esquemas de codificación Base64 se usan comúnmente cuando existe la necesidad de codificar datos binarios que deben almacenarse y transferirse a través de medios diseñados para manejar datos textuales. Esto es para garantizar que los datos permanezcan intactos sin modificaciones durante el transporte ”(Wiki, 2017)

Un ejemplo podría ser el siguiente: tiene un servicio web que acepta solo caracteres ASCII. Desea guardar y luego transferir los datos del usuario a otra ubicación (API), pero el destinatario desea recibir datos intactos. Base64 es para eso. . . El único inconveniente es que la codificación base64 requerirá alrededor de un 33% más de espacio que las cadenas normales.

Otro ejemplo :: uenc = codificado en url = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.querytip.com/asics-men-s-gel-k.htm-ii-kl-k-----x-----x-ii-kl .

Como puede ver, no podemos poner char "/" en la URL si queremos enviar la última URL visitada como parámetro porque romperíamos la regla de atributo / valor para "MOD rewrite" - parámetro GET.

Un ejemplo completo sería: " http://loc.querytip.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product / 93 / "


4

Principalmente, he visto que se usa para codificar datos binarios en contextos que solo pueden manejar conjuntos de caracteres ascii o simples.


3

Para ampliar un poco lo que Brad está diciendo: muchos mecanismos de transporte para correo electrónico y Usenet y otras formas de mover datos no están "limpios en 8 bits", lo que significa que los caracteres que están fuera del conjunto de caracteres ASCII estándar pueden ser destrozados en tránsito, por ejemplo, 0x0D puede verse como un retorno de carro y convertirse en un retorno de carro y avance de línea. Base 64 mapea todos los caracteres binarios en varias letras y números ascii estándar y signos de puntuación para que no se rompan de esta manera.


2

Base64

Base64 es un término genérico para varios esquemas de codificación similares que codifican datos binarios tratándolos numéricamente y traduciéndolos en una representación de base 64. El término Base64 se origina a partir de una codificación de transferencia de contenido MIME específica.

Los esquemas de codificación Base64 se usan comúnmente cuando existe la necesidad de codificar datos binarios que deben almacenarse y transferirse a través de medios diseñados para manejar datos textuales. Esto es para garantizar que los datos permanezcan intactos sin modificaciones durante el transporte. Base64 se usa comúnmente en varias aplicaciones, incluido el correo electrónico a través de MIME y el almacenamiento de datos complejos en XML.


0

Base64 se puede usar para muchos propósitos.

La razón principal es convertir los datos binarios en algo pasable.

A veces lo uso para pasar datos JSON de un sitio a otro, almacenar información en cookies sobre un usuario.

Nota: "puede" usarlo para el cifrado: no veo por qué la gente dice que no puede, y que no es cifrado, aunque sería fácilmente rompible y está mal visto. El cifrado no significa nada más que convertir una cadena de datos en otra cadena de datos que luego se puede descifrar o no, y eso es lo que hace base64.



2
Estás interpretación de la definición de "cifrado" lejos demasiado literalmente. La palabra se ha convertido en algo bastante más específico que sus orígenes.
Dan Bechard

0

Un dígito hexadecimal es de un mordisco (4 bits). Dos mordiscos hacen 8 bits que también se llaman 1 byte.

MD5 genera una salida de 128 bits que se representa utilizando una secuencia de 32 dígitos hexadecimales, que a su vez son 32 * 4 = 128 bits. 128 bits hacen 16 bytes (ya que 1 byte es 8 bits).

Cada carácter Base64 codifica 6 bits (excepto el último carácter que no es de relleno que puede codificar 2, 4 o 6 bits; y los caracteres de relleno finales, si los hay). Por lo tanto, según la codificación Base64, un hash de 128 bits requiere al menos ⌈128 / 6⌉ = 22 caracteres, más el pad si lo hay.

Usando base64, podemos producir la salida codificada de nuestra longitud deseada (6, 8 o 10). Si elegimos decidir la salida de 8 caracteres de longitud, ocupa solo 8 bytes, mientras que ocupaba 16 bytes para la salida hash de 128 bits.

Entonces, además de la seguridad, la codificación base64 también se usa para reducir el espacio consumido.

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.