[pyar] padding en base64

Matias Graña matias.alejo en gmail.com
Lun Dic 13 15:24:33 ART 2010


2010/12/13 Ricardo Armas <rarmas en gmail.com>:
> A ver quien me explica esto, como conté antes estoy leyendo correos
> con python. Me fueron de mucha ayuda las sugerencias acerca de como
> decodificar base64. Ahora, me surgió un inconveniente que solucioné de
> una manera medio cabeza, y no entiendo por qué, a ver si alguien
> entiende.
>
> si hago esto:
>
> texto=base64.decodestring(desc + "=" * (3- (len(desc) % 3)) )
>
> da este error
> Error: Incorrect Padding
>
> En cambio así anda:
>
>    if (3 - (len(desc) % 3))==0:
>        texto=base64.decodestring(desc)
>    elif (3- (len(desc) % 3))==1:
>        texto=base64.decodestring(desc + "=")
>    elif (3- (len(desc) % 3))==2:
>        texto=base64.decodestring(desc + "==")
>
> Es más si hago "=" * 2 anda si hago "=" * a (donde a es una variable
> que seteo en función del largo de lo que voy a decodificar) no anda.
>
>
>
>
> --
> Ricardo A. Armas


Ricardo: como te dijo Ramiro, el padding de base64 es de 4 bytes.
Puede que te haya funcionado alguna prueba de casualidad como la que
mandás, con alguna variable desc particular, pero no va a andar
siempre.
La cosa es: cada byte aporta 8 bits, pero en base64 vos armás "bytes"
de 6 bits. Entonces, cada 4 "bytes" de 6 bits, tenés 3 bytes de
verdad. Como vos estás pasando de base64 a ascii, las posibilidades
son
*) el largo de la cadena en ascii es 3*n bytes, y usás 4*n "bytes" de
base64. No hay padding.
*) el largo es 3*n+1, con lo que sobran 8 bits cuando se lo encodea.
Los primeros 6 van a un "byte" base64, los 2 que siguen van a otro, y
te quedan dos bytes colgando. El padding es '=='. La longitud del
texto encodeado, sin el padding, fue 4*n + 2.
*) el largo es 3*n+2, con lo que te sobran 16 bits. Los primeros 12
van a parar a dos "bytes" base64, los 4 restantes a otro, y queda un
byte colgando. El padding es '='. La longitud del texto encodeado fue
4*n + 3.

Para volver a agregarle los '=' que faltan tenés que tomar
4 - len(desc)%4 y cambiarlo por 0 si eso da 4. Se puede hacer fácil con
 texto = base64.decodestring( desc + ['', '', '==', '='][len(desc)%4] )
En los casos de arriba se ve que len(desc)%4 nunca da 1 (a menos que
esté mal encodeado).

Esto es usando base64. También te sugieren usar el módulo email. Nunca
lo usé; no puedo comentar al respecto.

Saludos,
Matías



More information about the pyar mailing list