Está en la página 1de 4

Cmo codificar en Base64 con Java

Base64 es un mtodo para codificar, cada 3 bytes de entrada en 4 bytes de salida; es muy comnmente usado para codificar imgenes o archivos de audio para enviar por correo electrnico (aunque los das de transmisin de archivos a 7-bit estn por acabarse), y un modo de ocultar como inicias sesin en un sitio web (usuarios y contraseas) de "snooping". Aqu tienes un ejemplo de como programar un codificador Base64 en Java, un lenguaje de programacin para mltiples plataformas.

Pasos

1 2 3

Ingresa Informacin y Nombre del archivo

Inicia tu editor preferido, como "Notepad" "vi", e ingresa el cdigo predeterminado, como lo son la declaracin de clases y constantes. Nombra

el archivo como Base64.java.

Esos valores constantes son especificos, como se establece en el articulo, en las RFC (Llamadas a funciones remotas por sus siglas en Ingls)

relevantes. Es generalmente una buena prctica. leer todas las RFC antes de empezar un cdigo.

public class Base64 { private static final String base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; private static final int splitLinesAt = 76;

Tratar caracteres como bytes, significa que los caracteres "multibyte", como los Japoneses o Chinos, no sern codificados correctamente. Por lo tanto, debemos usar el mtodo getBytes() of String para poder convertir los caracteres Unicode a bytes antes de empezar a codificar. Pero, por ejemplo, si estas trabajando con un documento Japons y esta configurado en American English locale, vas a tener que especificar locale para la salida de getBytes(), as como getBytes("UTF-8"). Vamos a investigar cuantos padding bytes son necesarios. El operador de modulo de Java, %, ayuda mucho en esta situacin. Vamos tambin a declarar la subrutina nombre y parmetros mientras estamos en esto. Ahora utilizamos ese valor para hacer null pad la entrada. Observa que si no se necesita padding, no se tiene que agregar, ya que tomamos el mdulo de 3 por segunda vez, convirtiendo un 3 en un 0.

public static byte[] zeroPad(int length, byte[] bytes) { byte[] padded = new byte[length]; // se inicializa en cero por JVM System.arraycopy(bytes, 0, padded, 0, bytes.length);

1 of 4

07/11/2013 03:28 p.m.

return padded; } public static String encode(String string) { String encoded = ""; byte[] stringArray; try { stringArray = string.getBytes("UTF-8"); // utiliza la cadena de cdigo correcta! } catch (Exception ignored) { stringArray = string.getBytes(); // utiliza locale como default en lugar de croak } int paddingCount = (3 - (stringArray.length % 3)) % 3; stringArray = zeroPad(stringArray.length + paddingCount, stringArray);

Empacando los Bytes 1. Ahora si llegamos a lo que nos preocupa: empacar 3 bytes a la vez en un entero de 24 bit, luego extraer ndices de 6-bit en el cdigo de la cadena. Estos nmeros no son mgicos: 24 se divide entre 6 exactamente 4 veces, y 6 bits puede contener valores desde 0 hasta 63, lo cual puede indexar a cualquier valor en la cadena de 64 byte.

for (int i = 0; i < stringArray.length; i += 3) { int j = ((stringArray[i] & 0xff) << 16) + ((stringArray[i + 1] & 0xff) << 8) + (stringArray[i + 2] & 0xff); encoded = encoded + base64code.charAt((j >> 18) & 0x3f) + base64code.charAt((j >> 12) & 0x3f) + base64code.charAt((j >> 6) & 0x3f) + base64code.charAt(j & 0x3f); }

1. Por ltimo, empacamos la salida, despus de hacerle, insertando los CRLFs en los respectivos lmites de 76 byte, utilizando una subrutina separada para mas claridad.
return splitLines(encoded.substring(0, encoded.length() - paddingCount) "==".substring(0, paddingCount)); } public static String splitLines(String string) { String lines = ""; for (int i = 0; i < string.length(); i += splitLinesAt) { lines += string.substring(i, Math.min(string.length(), i + splitLinesAt)); lines += "\r\n"; } return lines; }

Podemos, si as se desea, agregar una rutina principal para propsitos de prueba. Esto es usualmente una buena idea antes de publicar su cdigo para

consumo pblico.

public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.err.println("encoding \"" + args[i] + "\""); System.out.println(encode(args[i])); } }

Aqu est el mduo terminado:

public class Base64 { private static final String base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/";

2 of 4

07/11/2013 03:28 p.m.

private static final int splitLinesAt = 76; public static byte[] zeroPad(int length, byte[] bytes) { byte[] padded = new byte[length]; // initialized to zero by JVM System.arraycopy(bytes, 0, padded, 0, bytes.length); return padded; } public static String encode(String string) { String encoded = ""; byte[] stringArray; try { stringArray = string.getBytes("UTF-8"); // utiliza la cadena de cdigo correcta! } catch (Exception ignored) { stringArray = string.getBytes(); //utiliza locale como default en lugar de croak } // determina cuantos bytes de padding se deben agregar a la salida int paddingCount = (3 - (stringArray.length % 3)) % 3; // agrega los padding necesarios a la entrada stringArray = zeroPad(stringArray.length + paddingCount, stringArray); // procesa 3 bytes a la vez, produciendo en serie 4 salidas de bytes // preocpate acerca de las inserciones CRLF despus for (int i = 0; i < stringArray.length; i += 3) { int j = ((stringArray[i] & 0xff) << 16) + ((stringArray[i + 1] & 0xff) << 8) + (stringArray[i + 2] & 0xff); encoded = encoded + base64code.charAt((j >> 18) & 0x3f) + base64code.charAt((j >> 12) & 0x3f) + base64code.charAt((j >> 6) & 0x3f) + base64code.charAt(j & 0x3f); } // reemplaza los padding codificados en null con "=" return splitLines(encoded.substring(0, encoded.length() paddingCount) + "==".substring(0, paddingCount)); } public static String splitLines(String string) { String lines = ""; for (int i = 0; i < string.length(); i += splitLinesAt) { lines += string.substring(i, Math.min(string.length(), i + splitLinesAt lines += "\r\n"; } return lines; } public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.err.println("encoding \"" + args[i] + "\""); System.out.println(encode(args[i])); } } }

Ahora vamos a compilarlo, utilizando javac, gcj, jikes, o like; y prueba, utilizando el artculo Hobbes de Wikipedia:
$ gcj -C Base64.java $ java Base64 "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."

Aqu est el resultado:


encoding "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure." TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

3 of 4

07/11/2013 03:28 p.m.

Coincide exactamente! Eso significa que los dos programas estn mal, o los dos estn mas o menos bien. En este punto tal vez quieras visitar nuevamente el artculo de Wikipedia, y leer los enlaces de RFC para ver si nos falta algo.

Consejos
No sientas que siempre tienes que entender algo antes de codificarlo. Las cosas se vuelven ms claras a medida que vas avanzando. Mientras que leer los RFC relevantes es necesario para la produccin de cdigo, la sobrecarga de informacin puede ser abrumadora; algunas veces la mejor manera es deshacer el cdigo a lo que tu entiendas, y luego regresarte a verificar la funcionalidad punto por punto en contar de los requerimientos obligatorios de los RFC. Java esta bien como lenguaje de propsito general, y para dispositivos como telfonos celulares podra ser la nica opcin para los programadores; pero la sintaxis de Javascript o Python te puede parecer mas concisa y poderosa. Todos los diferentes lenguajes tienen sus propias debilidades y fortalezas. Intenta escribir el cdigo complementario del mtodo para ste modulo!

Acerca del artculo

Categoras: Computadoras y electrnica Otros idiomas: English: How to Encode a String to Base64 With Java

Esta pgina ha sido visitada 1.399 veces.

4 of 4

07/11/2013 03:28 p.m.

También podría gustarte