Sua conclusão de que o preenchimento é desnecessário está certa. Sempre é possível determinar o comprimento da entrada sem ambigüidade a partir do comprimento da sequência codificada.
No entanto, o preenchimento é útil em situações em que strings codificadas em base64 são concatenadas de forma que os comprimentos das sequências individuais sejam perdidos, como pode acontecer, por exemplo, em um protocolo de rede muito simples.
Se strings não preenchidas forem concatenadas, é impossível recuperar os dados originais porque as informações sobre o número de bytes ímpares no final de cada sequência individual são perdidas. No entanto, se sequências preenchidas forem usadas, não haverá ambigüidade e a sequência como um todo poderá ser decodificada corretamente.
Editar: Uma Ilustração
Suponha que tenhamos um programa que codifica palavras em base64, concatena-as e as envia pela rede. Ele codifica "I", "AM" e "TJM", junta os resultados sem preenchimento e os transmite.
I
codifica para SQ
( SQ==
com preenchimento)
AM
codifica para QU0
( QU0=
com preenchimento)
TJM
codifica para VEpN
( VEpN
com preenchimento)
Portanto, os dados transmitidos são SQQU0VEpN
. O receptor base64 decodifica isso como em I\x04\x14\xd1Q)
vez do pretendido IAMTJM
. O resultado é um absurdo porque o remetente destruiu informações sobre onde cada palavra termina na sequência codificada. Se o remetente tivesse enviado SQ==QU0=VEpN
, o receptor poderia ter decodificado isso como três sequências de base64 separadas que se concatenariam para dar IAMTJM
.
Por que se preocupar com acolchoamento?
Por que não apenas projetar o protocolo para prefixar cada palavra com um comprimento inteiro? Em seguida, o receptor poderia decodificar o fluxo corretamente e não haveria necessidade de preenchimento.
Essa é uma ótima ideia, contanto que saibamos o comprimento dos dados que estamos codificando antes de começar a codificá-los. Mas e se, em vez de palavras, estivéssemos codificando pedaços de vídeo de uma câmera ao vivo? Podemos não saber o comprimento de cada pedaço com antecedência.
Se o protocolo usasse preenchimento, não haveria necessidade de transmitir um comprimento. Os dados poderiam ser codificados conforme vinham da câmera, cada pedaço terminado com preenchimento e o receptor seria capaz de decodificar o fluxo corretamente.
Obviamente, esse é um exemplo muito artificial, mas talvez ilustre por que o preenchimento pode ser útil em algumas situações.
Em uma nota relacionada, aqui está um conversor de base para conversão de base arbitrária que criei para você. Aproveitar! https://convert.zamicol.com/
O que são caracteres de preenchimento?
Os caracteres de preenchimento ajudam a satisfazer os requisitos de comprimento e não têm significado.
Exemplo de Decimal de Preenchimento: Dado o requisito arbitrário de todas as strings terem 8 caracteres de comprimento, o número 640 pode atender a esse requisito usando os 0s anteriores como caracteres de preenchimento, pois eles não têm significado, "00000640".
Codificação Binária
O Paradigma do Byte: O byte é a unidade de medida padrão de fato e qualquer esquema de codificação deve estar relacionado aos bytes.
Base256 se encaixa exatamente neste paradigma. Um byte é igual a um caractere em base256.
Base16 , hexadecimal ou hex, usa 4 bits para cada caractere. Um byte pode representar dois caracteres de base16.
Base64 não se encaixa uniformemente no paradigma de byte (nem base32), ao contrário de base256 e base16. Todos os caracteres de base64 podem ser representados em 6 bits, 2 bits menos que um byte completo.
Podemos representar a codificação base64 versus o paradigma do byte como uma fração: 6 bits por caractere em 8 bits por byte . Esta fração reduzida é de 3 bytes em 4 caracteres.
Essa proporção, 3 bytes para cada 4 caracteres base64, é a regra que desejamos seguir ao codificar base64. A codificação Base64 só pode prometer medição com pacotes de 3 bytes, ao contrário de base16 e base256, onde cada byte pode estar sozinho.
Então, por que o preenchimento é encorajado, embora a codificação pudesse funcionar bem sem os caracteres de preenchimento?
Se o comprimento de um fluxo for desconhecido ou se puder ser útil saber exatamente quando um fluxo de dados termina, use preenchimento. Os caracteres de preenchimento comunicam explicitamente que esses pontos extras devem estar vazios e elimina qualquer ambigüidade. Mesmo que o comprimento seja desconhecido com o preenchimento, você saberá onde termina o seu fluxo de dados.
Como contra-exemplo, alguns padrões como JOSE não permitem caracteres de preenchimento. Neste caso, se houver algo faltando, uma assinatura criptográfica não funcionará ou outros caracteres não base64 estarão faltando (como o "."). Embora suposições sobre o comprimento não sejam feitas, o preenchimento não é necessário porque se houver algo errado, ele simplesmente não funcionará.
E isso é exatamente o que diz o RFC de base64 ,
O preenchimento nos permite decodificar a codificação base64 com a promessa de que não haverá perda de bits. Sem preenchimento, não há mais o reconhecimento explícito da medição em pacotes de três bytes. Sem preenchimento, você pode não ser capaz de garantir a reprodução exata da codificação original sem informações adicionais geralmente de algum outro lugar em sua pilha, como TCP, somas de verificação ou outros métodos.
Exemplos
Aqui está o formulário de exemplo RFC 4648 ( http://tools.ietf.org/html/rfc4648#section-8 )
Cada caractere dentro da função "BASE64" usa um byte (base256). Em seguida, traduzimos isso para base64.
Este é um codificador com o qual você pode brincar: http://www.motobit.com/util/base64-decoder-encoder.asp
fonte
char*
, você precisa do tamanho da string ou de um terminador nulo. O preenchimento é redundante. Daí a pergunta de OP.Não há muito benefício nisso nos dias modernos. Portanto, vamos examinar isso como uma questão de qual pode ter sido o propósito histórico original .
A codificação Base64 faz sua primeira aparição na RFC 1421 datada de 1993. Na verdade, essa RFC concentra-se na criptografia de e-mail e a base64 é descrita em uma pequena seção 4.3.2.4 .
Este RFC não explica a finalidade do preenchimento. O mais próximo que temos de uma menção do propósito original é esta frase:
Não sugere concatenação (resposta principal aqui), nem facilidade de implementação como um propósito explícito para o preenchimento. No entanto, considerando toda a descrição, não é absurdo supor que isso pode ter a intenção de ajudar o decodificador a ler a entrada em unidades de 32 bits ( "quanta" ). Isso não traz nenhum benefício hoje, no entanto, em 1993, o código C inseguro provavelmente teria realmente aproveitado essa propriedade.
fonte
b'Zm9vYmFyZm9vYg==' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy' b'Zm9vYmFyZm9vYmFyZg==' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v'
é igual ao deb'Zm9vYmFyZm9vYg=' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy=' b'Zm9vYmFyZm9vYmFyZg=' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v='