viernes, 9 de diciembre de 2011

Conversión a Base64

En términos simples, Base64 permite representar Bytes de cualquier valor (0 a 255) por medio de caracteres de texto. En este artículo me propongo mostrar cómo desarrollar código capaz de realizar la traducción, y al mismo tiempo que puedan hacer el código ustedes mismos.

Como ejemplo muestro el método implementado por medio de Excel que permite visualizar la lógica detrás del proceso, y luego dos programitas en ASP que pueden usar los lectores como punto de partida para realizar su propio programa ya sea en ASP cómo también en Visual Basic, o, con un poco de trabajo, a Java o JavaScript.

Fig. 1 Conversión en Excel


El Proceso de Conversión en Excel

En la Fig. 1 se puede observar el proceso de conversión de manera visual, se parte de una cadena TRES caracteres ACII, en este caso "URL". El hecho de tomar TRES caracteres no es arbitrario, es uno de los requisitos de la conversión, ya que Base64 permite convertir TRES caracteres ASCII (o sus equivalentes valores binarios) en CUATRO caracteres de 6 BITS legibles.

La matemática es clara:

3 * 8 bits = 24 bits
4 * 6 bits = 24 bits



Lo que se debe hacer es armar una ristra de 24 bits concatenando los bits individuales de los 3 caracteres ASCI I y luego extraer 4 grupos de 6 bits de esa ristra. Simple, ¿no es cierto?

Funciones de Excel



En ASP

El ejemplo en Excel es útil para observar el proceso requerido en la traducción, pero no es para nada práctico, excepto que lo implementen en una función de VBA. Por lo tanto aquí va un ejemplo en ASP.

Fig. 2 Conversor ASP


La principal diferencia entre este ejemplo y el anterior, es que no vamos a convertir los valores en una ristra de caracteres 0 y 1 (algo absolutamente ineficiente); en este caso, la ristra consistirá de un número bastante grande (de 24 bits) que contendrá los TRES caracteres requeridos (mas adelante veremos qué pasa cuando hay más o menos de tres caracteres).

La Ristra

La ristra consistirá de la sumatoria de los valores ascii de cada carácter escalándolo para que ocupe su posición relativa dentro de la ristra, según el siguiente esquema:

1) El valor del primer carácter habrá que multiplicarlo por 256^2 para que ocupe su lugar a partir del bit 16 hasta el bit 23 (considerando el número en binario).
2) El valor del segundo carácter habrá que multiplicarlo por 256 para que ocupe su lugar a partir del bit 8 hasta el bit 15 (considerando el número en binario).
3)El valor del tercer carácter se deja como está ya que ocupa los bits 0 hasta el bit 7.

La siguiente instrucción almacena la “ristra” numérica en la variable tmp:



La Extracción

El Segundo tema consiste en la extracción de los grupos de 6 bits, ahora no hay una cadena (string) de ceros y unos, sino que tenemos un valor numérico. Por esta razón debemos emplear una máscara binaria para quedarnos con la parte que nos interesa.

Máscaras en binario

B1 = 111111 000000 000000 000000
B2 = 000000 111111 000000 000000
B3 = 000000 000000 111111 000000
B4 = 000000 000000 000000 111111

Máscaras en decimal

b1=16515072
b2=258048
b3=4032
b4=63

Las máscaras funcionan por medio de las operaciones binarias (bit a bit), por ejemplo:
 Valor10100101
AND
 Máscara11110000
 Resultado10100000


Una vez que se realizó la operación AND con la máscara, tenemos al grupo de 6 bits correspondiente a la máscara utilizada. Sin embargo, antes de poder usarlo para contrastar con la tabla de símbolos Base64 (el vector b64 del ejemplo) tendremos que llevar el valor a ocupar el rango apropiado, desde el bit 0 hasta el bit 5, es decir, hay que cambiarlo de escala.

Para cambiar de escala el valor, debemos realizar una división entera cuyo numerador será el valor extraído por medio de la máscara, dividido por el nivel de escala que corresponde al grupo de bits extraído, por ejemplo r1 que corresponde al nivel más alto de la escala, es decir el que está más a la izquierda, le corresponde el divisor 2^18. Esto se debe a que este grupo está localizado entre el bit 18 y el bit 23. Con el resto de los grupos se procede de manera idéntica, excepto el último grupo que está en la escala correcta (su divisor sería 2^0 = 1).

Luego de la división, el valor quedará localizado entre los bits 0 y 5 que es el rango admisible para los símbolos Base64.Finalmente, se buscan los valores en la tabla de conversión que es el arreglo b64 en nuestro ejemplo y se obtienen la secuencia de caracteres en Base64.



Tratamiento de la cadena

Eso está muy bien, el programa funciona correctamente con cualquier grupo de 3 Bytes que lo alimente. Sin embargo, las cadenas de cualquier elemento, sean de texto o de una secuencia binaria correspondiente a una imagen, por ejemplo, no crecen DE A TRES, lo hacen DE A UNO. Y este es uno de los problemas que hay que resolver.

¿Qué hacer con las cadenas mayores o menores que tres pero no divisibles por 3?

Más adelante, en un programa ASP de ejemplo, presentamos un método para tratar con las cadenas de texto mayores o menores, antes de alimentarlas a la función de conversión (cuya base la aporta el programa Base64.asp), pero antes de ver los detalles, continuemos con las reglas de conversión.

Las reglas de conversión indican que, hay que rellenar la cadena que no se ajuste a la REGLA DE TRES, con caracteres nulos según sea necesario, es decir si yo quisiera traducir solamente la U de URL, simplemente tendría que agregarle 2 caracteres Null detrás.

Podemos probar esto rápidamente con el primer programa

'Cadena de texto a convertir
s="U" & chr(0) & chr(0)

El resultado será
V Q A A

Y con la cadena UR

'Cadena de texto a convertir
s="UR" & chr(0)

El resultado será
V V I A

Obtenemos un resultado, sin embargo, no es del todo correcto, ya que el programa tradujo partes de la cadena que eran inválidas debido a que eran simplemente caracteres de relleno. Por lo tanto, hay otra regla (hay muchas más reglas que se aplican al ámbito de Internet donde pueden surgir conflictos con los símbolos de conversión) que se debe aplicar en estos casos y que dice que en el caso de que sobre 1 carácter (o que falten 2 que es lo mismo) se deben reemplazar los dos últimos caracteres del valor convertido por el símbolo "=" y en el caso de que sobren 2 caracteres, se le debe reemplazar el último.

Si aplicamos esta regla, en el primer caso quedaría VQ== y en el segundo VVI= que son ambas cadenas Base64 válidas.



El programa cadena.asp permite tratar con las cadenas de texto antes detecta si tiene caracteres sobrantes, le aplica los caracteres de relleno (si fuera necesario) y deja la variable sobra con el valor apropiado para realizar el último paso que vimos, es decir, el reemplazo o no de los últimos caracteres.

Para Finalizar

Los ejemplos presentados en el artículo, junto con los programitas permiten, con muy poco trabajo poner en funcionamiento un convertidor propio, según este lineamiento:

1.Procesar la cadena de texto originaria
2.Implementar un ciclo que separe la cadena en grupos de 3
3.Convertir el grupo
4.Acumular las conversiones parciales
5.Agregar los terminadores = si corresponde.

¡Que tengan un gran día!

Sergio Otaño

0 comentarios: