Su conclusión de que el relleno es innecesario es correcta. Siempre es posible determinar la longitud de la entrada sin ambigüedades a partir de la longitud de la secuencia codificada.
Sin embargo, el relleno es útil en situaciones donde las cadenas codificadas en base64 se concatenan de tal manera que se pierden las longitudes de las secuencias individuales, como podría suceder, por ejemplo, en un protocolo de red muy simple.
Si se concatenan cadenas sin relleno, es imposible recuperar los datos originales porque se pierde información sobre el número de bytes impares al final de cada secuencia individual. Sin embargo, si se utilizan secuencias rellenas, no hay ambigüedad y la secuencia en su conjunto se puede decodificar correctamente.
Editar: una ilustración
Supongamos que tenemos un programa que codifica palabras en base64, las concatena y las envía a través de una red. Codifica "I", "AM" y "TJM", empareja los resultados sin rellenar y los transmite.
I
codifica a SQ
( SQ==
con relleno)
AM
codifica a QU0
( QU0=
con relleno)
TJM
codifica a VEpN
( VEpN
con relleno)
Entonces los datos transmitidos son SQQU0VEpN
. El receptor base64-decodifica esto como en I\x04\x14\xd1Q)
lugar de lo previsto IAMTJM
. El resultado es una tontería porque el remitente ha destruido información sobre dónde termina cada palabra en la secuencia codificada. Si el remitente hubiera enviado en su SQ==QU0=VEpN
lugar, el receptor podría haber decodificado esto como tres secuencias base64 separadas que se concatenarían para dar IAMTJM
.
¿Por qué molestarse con el acolchado?
¿Por qué no diseñar el protocolo para prefijar cada palabra con una longitud entera? Entonces, el receptor podría decodificar la secuencia correctamente y no habría necesidad de relleno.
Es una gran idea, siempre que sepamos la longitud de los datos que estamos codificando antes de empezar a codificarlos. Pero, ¿y si, en lugar de palabras, codificamos fragmentos de video de una cámara en vivo? Es posible que no sepamos la longitud de cada fragmento de antemano.
Si el protocolo usara relleno, no habría necesidad de transmitir una longitud en absoluto. Los datos podrían codificarse a medida que ingresaban desde la cámara, cada fragmento terminaba con relleno y el receptor podría decodificar la transmisión correctamente.
Obviamente, ese es un ejemplo muy elaborado, pero tal vez ilustra por qué el relleno podría ser útil en algunas situaciones.
En una nota relacionada, aquí hay un convertidor de base para la conversión de base arbitraria que creé para usted. ¡Disfrutar! https://convert.zamicol.com/
¿Qué son los caracteres de relleno?
Los caracteres de relleno ayudan a satisfacer los requisitos de longitud y no tienen significado.
Ejemplo decimal de relleno: dado el requisito arbitrario de que todas las cadenas tengan 8 caracteres de longitud, el número 640 puede cumplir con este requisito utilizando ceros anteriores como caracteres de relleno, ya que no tienen significado, "00000640".
Codificación binaria
El paradigma del byte: el byte es la unidad de medida estándar de facto y cualquier esquema de codificación debe relacionarse con los bytes.
Base256 encaja exactamente en este paradigma. Un byte es igual a un carácter en base256.
Base16 , hexadecimal o hexadecimal, utiliza 4 bits para cada carácter. Un byte puede representar dos caracteres base16.
Base64 no encaja uniformemente en el paradigma de bytes (ni base32), a diferencia de base256 y base16. Todos los caracteres base64 se pueden representar en 6 bits, 2 bits menos que un byte completo.
Podemos representar la codificación base64 frente al paradigma de bytes como una fracción: 6 bits por carácter sobre 8 bits por byte . Reducida esta fracción es de 3 bytes sobre 4 caracteres.
Esta proporción, 3 bytes por cada 4 caracteres base64, es la regla que queremos seguir al codificar base64. La codificación Base64 solo puede prometer una medición uniforme con paquetes de 3 bytes, a diferencia de base16 y base256, donde cada byte puede ser independiente.
Entonces, ¿ por qué se recomienda el relleno a pesar de que la codificación podría funcionar bien sin los caracteres de relleno?
Si se desconoce la longitud de una secuencia o si podría ser útil saber exactamente cuándo termina una secuencia de datos, utilice el relleno. Los caracteres de relleno comunican explícitamente que esos espacios adicionales deben estar vacíos y descarta cualquier ambigüedad. Incluso si se desconoce la longitud con el relleno, sabrá dónde termina su flujo de datos.
Como contraejemplo, algunos estándares como JOSE no permiten caracteres de relleno. En este caso, si falta algo, una firma criptográfica no funcionará o faltarán otros caracteres que no sean base64 (como el "."). Aunque no se hacen suposiciones sobre la longitud, el relleno no es necesario porque si hay algo mal, simplemente no funcionará.
Y esto es exactamente lo que dice el RFC base64 ,
El relleno nos permite decodificar la codificación base64 con la promesa de no perder bits. Sin relleno, ya no existe el reconocimiento explícito de medir en paquetes de tres bytes. Sin relleno, es posible que no pueda garantizar la reproducción exacta de la codificación original sin información adicional, generalmente de algún otro lugar de su pila, como TCP, sumas de comprobación u otros métodos.
Ejemplos
Aquí está el formulario de ejemplo RFC 4648 ( http://tools.ietf.org/html/rfc4648#section-8 )
Cada carácter dentro de la función "BASE64" usa un byte (base256). Luego traducimos eso a base64.
Aquí hay un codificador con el que puede jugar: http://www.motobit.com/util/base64-decoder-encoder.asp
fuente
char*
, necesita el tamaño de la cadena o un terminador nulo. El relleno es redundante. De ahí la pregunta de OP.No tiene mucho beneficio en la actualidad. Así que veamos esto como una cuestión de cuál pudo haber sido el propósito histórico original .
La codificación Base64 hace su primera aparición en RFC 1421 con fecha de 1993. Esta RFC en realidad se centra en el cifrado de correo electrónico, y base64 se describe en una pequeña sección 4.3.2.4 .
Este RFC no explica el propósito del relleno. Lo más cercano que tenemos a una mención del propósito original es esta oración:
No sugiere la concatenación (respuesta superior aquí), ni la facilidad de implementación como un propósito explícito para el relleno. Sin embargo, considerando la descripción completa, no es descabellado suponer que esto puede haber tenido la intención de ayudar al decodificador a leer la entrada en unidades de 32 bits ( "cuantos" ). Eso no tiene ningún beneficio hoy en día, sin embargo, en 1993, el código C inseguro probablemente se habría aprovechado de esta propiedad.
fuente
b'Zm9vYmFyZm9vYg==' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy' b'Zm9vYmFyZm9vYmFyZg==' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v'
es la misma que la deb'Zm9vYmFyZm9vYg=' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy=' b'Zm9vYmFyZm9vYmFyZg=' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v='