Para que é usada a codificação base 64?


782

Eu ouvi pessoas falando sobre "codificação base 64" aqui e ali. Para que isso é usado?


1
No manual de base64_encode () : "Essa codificação foi projetada para fazer com que os dados binários sobrevivam ao transporte através de camadas de transporte que não são limpas em 8 bits, como corpos de correio".
still_dreaming_1 28/02/19

Respostas:


941

Quando você tem alguns dados binários que deseja enviar através de uma rede, geralmente não o faz apenas transmitindo os bits e bytes pela conexão em um formato bruto. Por quê? porque algumas mídias são feitas para transmitir texto. Você nunca sabe - alguns protocolos podem interpretar seus dados binários como caracteres de controle (como um modem) ou podem ser danificados porque o protocolo subjacente pode pensar que você inseriu uma combinação de caracteres especial (como a forma como o FTP traduz a linha) terminações).

Então, para contornar isso, as pessoas codificam os dados binários em caracteres. Base64 é um desses tipos de codificações.

Por que 64?
Como você geralmente pode confiar nos mesmos 64 caracteres presentes em muitos conjuntos de caracteres e pode estar razoavelmente confiante de que seus dados acabarão do outro lado do fio incorretamente.


104
(Em teoria, você poderia fazer base-80 codificação ou algo semelhante, mas seria significativamente mais difícil potências de dois são bases naturais para binário..)
Jon Skeet

13
@yokees: Não há garantia, são apenas personagens quase sempre seguros. É por isso que existem várias formas de Base-64 ( en.wikipedia.org/wiki/Base-64 ).

8
Isso significa que toda passagem de dados do tipo rede deve usar algum tipo de codificação?
Tanner Summers

6
Mas por que o método base64 é usado para codificar dados de string? por exemplo, na função atob javascript Existe algum significado para o servidor codificar um arquivo json no formato base64? Caracteres especiais podem ser um caso de uso, mas por que não usar utf8 nesse caso, eles são equivalentes? Qualquer outro recurso sobre isso seria muito apreciado, obrigado.
Partizanos #

4
Uma lista de pelo menos alguns protocolos que falhariam seria bom ter se alguém souber.
Tadej

202

É basicamente uma maneira de codificar dados binários arbitrários no texto ASCII. São necessários 4 caracteres por 3 bytes de dados, além de um pouco de preenchimento no final.

Essencialmente, cada 6 bits da entrada é codificado em um alfabeto de 64 caracteres. O alfabeto "padrão" usa AZ, az, 0-9 e + e /, com = como caractere de preenchimento. Existem variantes seguras para URL.

A Wikipedia é uma fonte razoavelmente boa de mais informações.


Em um idioma como o php, foram obtidos dados binários. Quase sempre trabalhamos com dados de string que são texto.
Cholthi Paul Ttiopic 5/16

3
@CholthiPaulTtiopic: os resultados de criptografia ou compactação ou som / imagens / vídeo.
Jon Skeet

1
@CholthiPaulTtiopic: Receio não ter idéia do que você quer dizer com "e quanto ao armazenamento", mas neste momento acho que estamos um pouco fora do assunto.
Jon Skeet

2
@CholthiPaulTtiopic: Eu evitaria fortemente pensar em termos de "string binário". Os dados binários devem ser tratados como dados binários e não como texto. Eu já vi literalmente centenas - possivelmente milhares - de perguntas sobre SO, que basicamente se resumem a pessoas que não se importam o suficiente com essa distinção.
Jon Skeet

1
@ still_dreaming_1 O PHP os chama binary strings. (source) php.net/manual/pt/function.pack.php
Cholthi Paul Ttiopic


116

É uma codificação textual de dados binários em que o texto resultante não possui nada além de letras, números e os símbolos "+", "/" e "=". É uma maneira conveniente de armazenar / transmitir dados binários em mídia usada especificamente para dados textuais.

Mas por que Base-64? As duas alternativas para converter dados binários em texto que vêm à mente imediatamente são:

  1. Decimal: armazene o valor decimal de cada byte como três números: 045 112 101 037 etc. onde cada byte é representado por 3 bytes. Os dados aumentam três vezes.
  2. Hexadecimal: armazene os bytes como pares hexadecimais: AC 47 0D 1A etc. onde cada byte é representado por 2 bytes. Os dados aumentam duas vezes.

A Base-64 mapeia 3 bytes (8 x 3 = 24 bits) em 4 caracteres que abrangem 6 bits (6 x 4 = 24 bits). O resultado parece algo como "TWFuIGlzIGRpc3Rpb ...". Portanto, o inchaço é apenas meros 4/3 = 1.3333333 vezes o original.


10
Entendo corretamente que 64 é a melhor escolha, pois é a potência mais alta de dois que é convertível em um caractere ASCII imprimível (existem 95 deles)?
voho 18/01

Se em ambos os casos são 24 bits, então não é o inchaço 1: 1? Ou, quando você diz 4 caracteres que abrangem 6 bits, quer dizer que na verdade existem 8 bits por caractere, mas os dois primeiros são 0s preenchidos?
David Klempfner 27/02/19

1
@Backwards_Dave Cada 6 bits são expressos em 8 bits. Portanto, o inchaço é 8: 6 ou 4: 3.
Ates Goral

82

Além do que já foi dito, dois usos muito comuns que não foram listados são

Hashes:

Hashes são funções unidirecionais que transformam um bloco de bytes em outro bloco de bytes de tamanho fixo, como 128 bits ou 256 bits (SHA / MD5). A conversão dos bytes resultantes em Base64 facilita muito a exibição do hash, especialmente quando você está comparando uma soma de verificação para integridade. Os hashes são vistos com tanta frequência no Base64 que muitas pessoas confundem o próprio Base64 com um hash.

Criptografia:

Como uma chave de criptografia não precisa ser texto, mas bytes brutos, às vezes é necessário armazená-la em um arquivo ou banco de dados, para o qual o Base64 é útil. O mesmo com os bytes criptografados resultantes.

Observe que, embora o Base64 seja frequentemente usado em criptografia, não é um mecanismo de segurança. Qualquer um pode converter a string Base64 de volta aos bytes originais, portanto, não deve ser usada como um meio para proteger os dados, apenas como um formato para exibir ou armazenar bytes brutos com mais facilidade.

Certificados

Os certificados x509 no formato PEM são codificados na base 64. http://how2ssl.com/articles/working_with_pem_files/


4
Na verdade, é mais fácil, em termos de processamento, armazenar bytes como bytes em muitos casos. Mesmo em um banco de dados e especialmente em um arquivo (se forem usados ​​registros de comprimento fixo ou se o único conteúdo for bytes). Normalmente, o Base64 é usado quando esses bytes devem ser transmitidos em algum lugar, principalmente em um canal que pode cortar bits ou interpretar alguns dos bytes como códigos de controle.
cHao

Eu nunca vi um hash escrito como números inteiros de 8 bits não assinados, 0,1255,36 ... e exibi-lo com UTF-8 ou qualquer outra codificação não faria sentido; As chaves de criptografia e os dados criptografados geralmente são armazenados em arquivos XML de configuração e onde você não pode armazenar os bytes brutos. Concordo se você pode armazená-lo como bytes brutos, por todos os meios, mas base64 é para aquelas situações em que você não pode. Existem muitos usos do base64 além da transmissão. Estes são simplesmente dois cenários comuns em que você o verá.
Despertar

1
Você exibia o hash como hexadecimal, não decimal. Para hashes, isso é de fato muito mais comum que base64.
cHao 23/02

@cHao Sim, isso também é comum. Dígitos hexadecimais podem representar qualquer dado binário, mas a base 64 tem a vantagem de ocupar muito menos espaço, pois usa mais caracteres.
Despertar 23/02

45

Anos atrás, quando a funcionalidade de correspondência foi introduzida, foi totalmente baseado em texto, com o passar do tempo, a necessidade de anexos como imagem e mídia (áudio, vídeo etc.). Quando esses anexos são enviados pela Internet (que é basicamente na forma de dados binários), a probabilidade de os dados binários ficarem corrompidos é alta em sua forma bruta. Então, para resolver esse problema, surgiu o BASE64.

O problema com os dados binários é que ele contém caracteres nulos que, em algumas linguagens como C, C ++, representam o final da cadeia de caracteres, portanto, o envio de dados binários em formato bruto, contendo bytes NULL, impedirá que um arquivo seja totalmente lido e conduza a dados corrompidos.

Por exemplo :

Em C e C ++, esse caractere "nulo" mostra o final de uma seqüência de caracteres. Então "OLÁ!" É armazenado assim:

OLÁ

72 69 76 76 79 00

O 00 diz "pare aqui".

Agora vamos mergulhar em como a codificação BASE64 funciona.

Ponto a ser observado: o comprimento da string deve ser múltiplo de 3.

Exemplo 1 :

String a ser codificada: “ace”, Length = 3

1) Converta cada caractere em decimal.

a = 97, c = 99, e = 101

insira a descrição da imagem aqui

2) Altere cada decimal para representação binária de 8 bits.

97 = 01100001, 99 = 01100011, 101 = 01100101

Combinado: 01100001 01100011 01100101

3) Separe em um grupo de 6 bits.

011000 010110 001101 100101

4) Calcular binário para decimal

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

5) Encobrir caracteres decimais para base64 usando o gráfico base64.

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

"Ace" => "YWNl"

insira a descrição da imagem aqui

Exemplo 2:

String a ser codificada: “abcd” Length = 4, não é múltiplo de 3. Portanto, para tornar o comprimento da string múltiplo de 3, devemos adicionar um preenchimento de 2 bits para obter o comprimento = 6. O bit de preenchimento é representado pelo sinal “=”.

Ponto a ser observado: Um bit de preenchimento é igual a dois zeros 00 e, portanto, dois bits de preenchimento são iguais a quatro zeros 0000.

Então, vamos iniciar o processo: -

1) Converta cada caractere em decimal.

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

2) Altere cada decimal para representação binária de 8 bits.

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

3) Separe em um grupo de 6 bits.

011000, 010110, 001001, 100011, 011001, 00

então os últimos 6 bits não estão completos, então inserimos dois bits de preenchimento que são iguais a quatro zeros "0000".

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

Agora é igual. Dois sinais de igual no final mostram que foram adicionados 4 zeros (ajuda na decodificação).

4) Calcule binário para decimal.

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

5) Encobrir caracteres decimais para base64 usando o gráfico base64.

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

"Abcd" => "YWJjZA =="


5
este é realmente um grande explicação
maheshmnj

28

Nos primeiros dias dos computadores, quando a comunicação entre sistemas da linha telefônica não era particularmente confiável, era usado um método rápido e sujo de verificação da integridade dos dados: "paridade de bits". Nesse método, cada byte transmitido teria 7 bits de dados e o oitavo seria 1 ou 0, para forçar o número total de 1 bits no byte a ser par.

Portanto, 0x01 seria transmitido como 0x81; 0x02 seria 0x82; 0x03 permaneceria 0x03 etc.

Para promover esse sistema, quando o conjunto de caracteres ASCII foi definido, apenas 00-7F receberam caracteres. (Ainda hoje, todos os caracteres definidos no intervalo 80-FF não são padrão)

Muitos roteadores do dia colocam a verificação de paridade e a tradução de bytes no hardware, forçando os computadores conectados a eles a lidar estritamente com dados de 7 bits. Isso força os anexos de email (e todos os outros dados, e é por isso que os protocolos HTTP e SMTP são baseados em texto), a serem convertidos em um formato somente texto.

Poucos roteadores sobreviveram até os anos 90. Duvido seriamente que algum deles esteja em uso hoje.


2
Este é um excelente ponto de discussão e uma interessante lição de história, obrigado.
precisa

26

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

O termo Base64 refere-se a uma codificação de transferência de conteúdo MIME específica. Também é usado como um termo genérico para qualquer esquema de codificação semelhante que codifique dados binários, tratando-os numericamente e convertendo-os em uma representação de base 64. A escolha específica da base se deve ao histórico de codificação do conjunto de caracteres: é possível escolher um conjunto de 64 caracteres que faz parte do subconjunto comum à maioria das codificações e também pode ser impresso. Essa combinação deixa os dados improváveis ​​de serem modificados em trânsito por sistemas, como email, que tradicionalmente não eram limpos em 8 bits.

Base64 pode ser usado em uma variedade de contextos:

  • O Evolution e o Thunderbird usam o Base64 para ofuscar senhas de email [1]
  • Base64 pode ser usado para transmitir e armazenar texto que poderia causar colisão com delimitadores
  • O Base64 é frequentemente usado como um atalho rápido, mas inseguro, para ocultar segredos sem incorrer na sobrecarga do gerenciamento de chaves criptográficas

  • Os spammers usam o Base64 para evitar ferramentas básicas anti-spam, que geralmente não decodificam o Base64 e, portanto, não conseguem detectar palavras-chave em mensagens codificadas.

  • Base64 é usado para codificar cadeias de caracteres em arquivos LDIF
  • Às vezes, o Base64 é usado para incorporar dados binários em um arquivo XML, usando uma sintaxe semelhante a ...... por exemplo, bookmarks.html do Firefox.
  • O Base64 também é usado ao se comunicar com dispositivos de impressão de Assinatura Fiscal do governo (geralmente, através de portas seriais ou paralelas) para minimizar o atraso na transferência de caracteres de recibo para assinatura.
  • Base64 é usado para codificar arquivos binários, como imagens em scripts, para evitar a dependência de arquivos externos.
  • Pode ser usado para incorporar dados de imagem brutos em uma propriedade CSS, como background-image.

11

Alguns protocolos de transporte permitem apenas a transmissão de caracteres alfanuméricos. Imagine uma situação em que caracteres de controle sejam usados ​​para acionar ações especiais e / ou que suportem apenas uma largura de bit limitada por caractere. Base64 transforma qualquer entrada em uma codificação que usa apenas caracteres alfanuméricos +, /e =como caractere de preenchimento.


9

O uso do Base64 que vou descrever aqui é um pouco complicado. Portanto, se você não gosta de hacks, por favor, não continue.

Eu tive problemas quando descobri que o utf8 do MySQL não suporta caracteres unicode de 4 bytes, pois ele usa uma versão de 3 bytes do utf8. Então, o que eu fiz para oferecer suporte ao unicode completo de 4 bytes no utf8 do MySQL? Bem, a base64 codifica seqüências de caracteres ao armazenar no banco de dados e a base64 decodifica ao recuperar.

Como a codificação e decodificação base64 é muito rápida, as opções acima funcionaram perfeitamente.

Você tem os seguintes pontos para anotar:

  • A codificação Base64 usa 33% mais armazenamento

  • As strings armazenadas no banco de dados não podem ser legíveis por humanos (você pode vendê-las como um recurso que as strings do banco de dados usam uma forma básica de criptografia).

Você pode usar o método acima para qualquer mecanismo de armazenamento que não suporte unicode.


6
"Você pode vender isso como um recurso que as seqüências de caracteres do banco de dados usam uma forma básica de criptografia" Eu gosto do seu estilo: D
Ercan

8
"Você pode vender isso como um recurso que as cadeias de banco de dados usam uma forma básica de criptografia", que coisa horrível de se dizer: D
Alex

1
forma básica de criptografia contra qualquer pessoa que não tem a Base64 decodificação algoritmo rofl: D
Eladian

1
@ Alex Nem uma coisa "horrível de se dizer". Dados sensíveis de segundo grau podem ser codificados em base64 para torná-los ilegíveis pelos administradores de banco de dados. Nem sempre é necessário ter o mais alto nível de criptografia para todos os dados. Por exemplo, se você deseja ocultar "comentários" de um administrador de banco de dados, base64 é adequado para o trabalho. Gratcias!
Basil Musa

1
Vale ressaltar que o MySQL agora tem suporte para todo o Unicode, embora para fins de compatibilidade com versões anteriores, seu utf8tipo ainda seja apenas de três bytes; se você quiser a coisa real, use utf8mb4. Bom hack, mas não é mais necessário.
TRiG 03/04/19

7

É usado para converter dados binários arbitrários em texto ASCII.

Por exemplo, anexos de email são enviados dessa maneira.


7

Eu o uso no sentido prático quando transferimos grandes objetos binários (imagens) via serviços da web. Portanto, quando estou testando um serviço web C # usando um script python, o objeto binário pode ser recriado com um pouco de mágica.

[Em python]

import base64
imageAsBytes = base64.b64decode( dataFromWS )

1
Os dados viajam mais rápido?
FelipeM

1
@FelipeM mais lento, não mais rápido. Base64 tem 33% de sobrecarga (pelo preço da segurança.)
Juraj

6

“Os esquemas de codificação Base64 são comumente usados ​​quando há necessidade de codificar dados binários que precisam ser armazenados e transferidos por mídia projetada para lidar com dados de texto. Isso é para garantir que os dados permaneçam intactos sem modificação durante o transporte ”(Wiki, 2017)

Exemplo poderia ser o seguinte: você possui um serviço da web que aceita apenas caracteres ASCII. Você deseja salvar e transferir os dados do usuário para outro local (API), mas o destinatário deseja receber dados intocados. Base64 é para isso. . . A única desvantagem é que a codificação base64 exigirá cerca de 33% mais espaço do que as seqüências regulares.

Outro exemplo :: uenc = url codificado = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.querytip.com/asics-men-s-gelgel-mli.html .

Como você pode ver, não podemos colocar char “/” na URL se quisermos enviar a última URL visitada como parâmetro, porque quebraríamos a regra de atributo / valor do parâmetro “MOD rewrite” - GET.

Um exemplo completo seria: “ http://loc.querytip.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product / 93 / "


4

Eu já vi isso principalmente para codificar dados binários em contextos que podem lidar apenas com conjuntos de caracteres ascii - ou simples -.


3

Para expandir um pouco o que Brad está dizendo: muitos mecanismos de transporte para email e Usenet e outras maneiras de mover dados não são "8 bits limpos", o que significa que caracteres fora do conjunto de caracteres ascii padrão podem ser mutilados em trânsito - por exemplo, 0x0D pode ser visto como um retorno de carro e transformado em um retorno de carro e avanço de linha. A Base 64 mapeia todos os caracteres binários em várias letras e números ASCII padrão e pontuação, para que não sejam mutilados dessa maneira.


2

Base64

Base64 é um termo genérico para vários esquemas de codificação semelhantes que codificam dados binários, tratando-os numericamente e convertendo-os em uma representação de base 64. O termo Base64 se origina de uma codificação de transferência de conteúdo MIME específica.

Os esquemas de codificação Base64 são comumente usados ​​quando há a necessidade de codificar dados binários que precisam ser armazenados e transferidos por mídia projetada para lidar com dados de texto. Isso é para garantir que os dados permaneçam intactos sem modificação durante o transporte. O Base64 é usado normalmente em vários aplicativos, incluindo email via MIME e armazenamento de dados complexos em XML.


0

Base64 pode ser usado para muitos propósitos.

O principal motivo é converter dados binários em algo aceitável.

Às vezes, eu o uso para passar dados JSON de um site para outro, armazenar informações em cookies sobre um usuário.

Nota: Você "pode" usá-lo para criptografia - não vejo por que as pessoas dizem que você não pode, e que não é criptografia, embora seja facilmente quebrável e seja mal visto. Criptografia significa nada mais do que converter uma sequência de dados em outra que pode ser descriptografada posteriormente ou não, e é isso que a base64 faz.



2
Você está interpretando a definição de "criptografia" muito muito literalmente. A palavra evoluiu para algo um pouco mais específico do que suas origens.
precisa

0

Um dígito hexadecimal é de uma mordidela (4 bits). Dois nibbles produzem 8 bits, também chamados de 1 byte.

O MD5 gera uma saída de 128 bits que é representada usando uma sequência de 32 dígitos hexadecimais, que por sua vez são 32 * 4 = 128 bits. 128 bits produzem 16 bytes (já que 1 byte é 8 bits).

Cada caractere Base64 codifica 6 bits (exceto o último caractere sem bloco que pode codificar 2, 4 ou 6 bits; e os caracteres finais do bloco, se houver). Portanto, por codificação Base64, um hash de 128 bits requer pelo menos 8128 / 6⌉ = 22 caracteres, mais pad, se houver.

Usando base64, podemos produzir a saída codificada com o comprimento desejado (6, 8 ou 10). Se optarmos por decidir a saída de 8 caracteres, ela ocupa apenas 8 bytes, enquanto ocupava 16 bytes para a saída de hash de 128 bits.

Portanto, além da segurança, a codificação base64 também é usada para reduzir o espaço consumido.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.