Quería compartir con uds. mi código fuente para cifrar texto (caracteres estándares) en Base64.
Para ver qué opinan! Hablando en cuestión de estética o profesionalismo, ¿está bien escrito el código fuente?
Aún me falta crear un método para hacer la decodificación.
El código fuente lo pueden descargar aquí: http://bit.ly/U7EiXN
URL del vídeo: http://bit.ly/RTdPho
Espero consejos y sugerencias, gracias. Saludos!
Main.java
Código:
// Necesarios para que el usuario pueda ingresar datos
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/**
*
* @author Mario A. Aguirre Romaní
*/
public class Main {
public static void main(String[] args) {
if(args.length > 0) { // Si fue llamado con argumentos...
System.out.println("Texto a cifrar: " + args[0]);
System.out.println("Texto cifrado:");
System.out.println(Base64.codificar(args[0]));
}
else { // Si no fue llamado con argumentos, se pide el texto...
// Para los datos ingresados por el usuario
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.print("Texto a cifrar: ");
String entrada = in.readLine();
System.out.println("Texto cifrado:");
System.out.println(Base64.codificar(entrada));
}
catch(IOException e) {
System.err.println(e.getMessage());
System.err.print("\007");
System.err.flush();
System.exit(1);
}
}
}
}
Conversor.java
Código:
/**
*
* @author Mario A. Aguirre Romaní
*/
public class Conversor {
/**
* Convierte un número en sistema decimal a sistema binario.
* @param numero_decimal Número en sistema decimal a convertir.
* @return Número convertido a sistema binario.
*/
public static String decimalAbinario(int numero_decimal) {
String regreso = "";
//int resultado = Integer.parseInt(numero_decimal);
// Mientras el número decimal sea mayor que 1, seguirá dividiéndose
while(numero_decimal > 1) {
// Si el módulo es 0, el número es múltiplo de 2
if((numero_decimal % 2) == 0) {
numero_decimal = numero_decimal / 2;
regreso += "0"; // Se agrega un 0 a la cadena
}
// Si el módulo no es 0, al número se le resta 1 y se divide entre 2
else {
numero_decimal = (numero_decimal - 1) / 2;
regreso += "1"; // Se agrega un 1 a la cadena
}
}
// Como al final quedó el número 1, se agrega un 1 a la cadena
regreso += "1";
/*
* Si la cantidad de dígitos es menor que 8, se agregarán ceros al
* final de la cadena hasta tener los 8 dígitos. Más adelante se
* invertirá la cadena, así los ceros habrán sido agregados a la
* izquierda y no a la derecha.
*/
if(regreso.length() < 8) {
String ceros = "";
for(int i = 1; i <= (8 - regreso.length()); i++)
ceros += "0";
regreso += ceros;
}
return invertirCadena(regreso);
}
public static int binarioAdecimal(String numero_binario) {
String invertida = invertirCadena(numero_binario);
int suma = 0;
int exponente = 0;
// Un ciclo que recorre todos los dígitos del número binario
for(int i = 0; i < invertida.length(); i++) {
/*
* El caracter de la posición i es convertido a cadena, luego a
* entero y al último se almacena en la variable numero.
*/
int numero = Integer.parseInt(String.valueOf(invertida.charAt(i)));
/*
* El número es multiplicado por 2, que está elevado a exponente,
* y el resultado se le suma al contenido de la variable suma.
*/
suma += numero * Math.pow(2, exponente);
exponente++; // Se incrementa en 1 el exponente
}
return suma; // La suma es el número convertido a sistema decimal
}
/**
* Invierte una cadena.
* @param cadena Cadena a invertir.
* @return Cadena invertida.
*/
private static String invertirCadena(String cadena) {
// Se crea un arreglo de caracteres de la misma longitud que la cadena
char arreglo[] = new char[cadena.length()];
int indice = 0;
// Ciclo que recorre desde la última posición hasta la primera
for(int i = cadena.length() - 1; i >= 0; i--) {
arreglo[indice] = cadena.charAt(i);
indice++; // Se incrementa en 1 el índice
}
// El arreglo de caracteres es convertido a cadena y después devuelto
return String.valueOf(arreglo);
}
}
Base64.java
Código:
/**
*
* @author Mario A. Aguirre Romaní
*/
public class Base64 {
/**
* Codifica en Base64 una cadena pasada como parámetro.
* @param cadena Cadena a convertir.
* @return Cadena codificada.
*/
public static String codificar(String cadena) {
String regreso = ""; // Contenido (codificado) que será devuelto
String binario = "";
// La cadena es convertida a un arreglo de caracteres
char arreglo[] = cadena.toCharArray();
// Ciclo que recorre todos los caracteres
for(int i = 0; i < arreglo.length; i++) {
int codigo_ascii = ascii(arreglo[i]);
/*
* Se convierte a número binario el código ASCII del caracter
* actual, y después es almacenado en la variable binario.
*/
binario += Conversor.decimalAbinario(codigo_ascii);
}
/*
* La longitud de la cadena binario es dividida entre 6, debido a que
* se necesita tomar dígitos de 6 en 6, comenzando de izquierda a
* derecha.
*/
int division = binario.length() / 6;
int diferencia;
/*
* Si el resultado de la división multiplicada por 6 es menor que
* la longitud de la cadena binario, se rellena con ceros a la
* derecha.
*/
if(division * 6 < binario.length()) {
/*
* A la longitud de la cadena binario se le resta el resultado de
* la división multiplicada por 6. De ésta manera se sabrá cuántos
* ceros tendrán que ser agregados hasta alcanzar la longitud de
* la cadena binario.
*/
diferencia = binario.length() - division * 6;
String ceros = "";
for(int i = 1; i <= (6 - diferencia); i++)
ceros += "0";
binario += ceros; // Se agregan los ceros a la derecha
}
/*
* Se crea un arreglo de cadenas en la que cada elemento tendrá los
* 6 dígitos binarios (tomados de 6 en 6, comenzando de izquierda a
* derecha). En otras palabras, la cadena binario es partida en grupos
* de 6 dígitos, y cada grupo es almacenado en cada uno de los elementos
* del arreglo de cadenas.
*/
String binarios[] = new String[binario.length() / 6];
// Variables que marcan el rango (desde dónde hasta dónde) de los 6 dígitos
int inicio = 0, fin = 6;
// Ciclo que recorre todos los elementos del arreglo de cadenas binarios
for(int i = 0; i < binarios.length; i++) {
// El rango o grupo de 6 dígitos es almacenado en el elemento
binarios[i] = binario.substring(inicio, fin);
inicio = fin; // El inicio ahora será el valor del final
fin += 6; // El final aumentará 6 posiciones
}
// Ciclo que recorre todos los elementos del arreglo de cadenas binarios
for(int i = 0; i < binarios.length; i++) {
// Se convierte a número decimal el número binario del elemento actual
int numero_decimal = Conversor.binarioAdecimal(binarios[i]);
// Se obtiene el caracter de ese número
char caracter = caracter(numero_decimal);
regreso += caracter; // Se agrega el caracter a la variable regreso
}
/*
* La regla dice que los caracteres de Base64 deben estar en grupos
* de 4. Según http://telectronica.blogspot.es/1173731640/
* La longitud de la cadena regreso es dividida entre 4, debido a que
* se necesita tomar caracteres en un rango de 4 en 4, comenzando de
* izquierda a derecha.
*/
division = regreso.length() / 4;
/*
* Si el resultado de la división multiplicada por 4 es menor que
* la longitud de la cadena regreso, se agregan al final de la
* cadena signos igual (=).
*/
if(division * 4 < regreso.length()) {
/*
* A la longitud de la cadena regreso se le resta el resultado de
* la división multiplicada por 4. De ésta manera se sabrá cuántos
* signos igual (=) tendrán que ser agregados hasta alcanzar la
* longitud de la cadena regreso.
*/
diferencia = regreso.length() - division * 4;
String signos_igual = "";
for(int i = 1; i <= (4 - diferencia); i++)
signos_igual += "=";
regreso += signos_igual; // Se agregan los signos a la derecha
}
return regreso; // Se regresa el resultado ya codificado
}
/**
* Devuelve el código ASCII de un caracter estándar pasado como parámetro.
* @param caracter Caracter estándar del cual se desea obtener su código ASCII.
* @return El código ASCII del caracter estándar.
*/
private static int ascii(char caracter) {
int codigo_ascii = -1;
// Los códigos ASCII van desde 0 hasta 127, según http://www.ascii.cl/es/
for(int i = 0; i <= 127; i++) {
if(caracter == (char)i) {
codigo_ascii = i;
break;
}
}
return codigo_ascii;
}
/**
* Devuelve el caracter que se encuentra en la posición que es pasada
* como parámetro.
* @param numero_decimal Posición de la cual se desea obtener su caracter.
* @return El caracter que se encuentra en esa posición.
*/
private static char caracter(int posicion) {
String cadena = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char caracter = '\0';
// Ciclo que recorre todos los caracteres de la cadena
for(int i = 0; i < cadena.length(); i++) {
// Si el ciclo actual coincide con la posición pasa como parámetro...
if(i == posicion) {
// El caracter del ciclo actual es almacenado en la variable caracter
caracter = cadena.charAt(i);
break; // Termina el ciclo
}
}
return caracter;
}
}