elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Duda con Operador de Bit en C# (codificación en Base64)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Duda con Operador de Bit en C# (codificación en Base64)  (Leído 2,515 veces)
Fireball-CH

Desconectado Desconectado

Mensajes: 131


Rebelblade 2009


Ver Perfil
Duda con Operador de Bit en C# (codificación en Base64)
« en: 20 Septiembre 2012, 05:34 am »

Hola, qué tal!

He querido implementar el uso del cifrado en Base64 en Java sin basarme en ningún código, y lo logré (http://foro.elhacker.net/java/pequena_demostracion_de_codificacion_en_base64-t371317.0.html).
Aunque sólo funciona con los caracteres estándares. Cuando ingreso acentos, por ejemplo, no funciona. :-\

Ante este problema busqué un poco. En una de mis revistas @RROBA encontré un ejemplo de ese cifrado pero en C#, y veo que sí funciona. Traté de analizarlo pero no lo comprendo al 100%. En la línea 48 veo que se utiliza el operador de bits << (sí es de bits, ¿cierto?), y quiero pensar que ahí está la clave para que funcione con los acentos. Yo no sé utilizar esos operadores.

Ese operador desplaza bits, ¿no? Mi duda es, ¿para qué se quiere desplazar bits (en ese código)? ¿Y cómo sé que tengo que desplazar y cuántos bits?

Ojalá me puedan ayudar.
Muchas gracias, saludos!

Código de la revista @RROBA:
Base64.cs
Código:
// Código fuente obtenido de la revisa @RROBA, número 85 Año VIII, página 16.
using System;

// Clase principal del programa
class Base64 {
  static int Main(String[] args) {
    string cbinario = "";
    string cCadena = "";
    int restocCadena = 0;

    if(args.Length != 1) {
      Console.WriteLine("Sintaxis: Base64 <texto>");
      return 0;
    }
    else {
      Console.WriteLine("Conversión a Base64");
      Console.WriteLine("===================");
      Console.WriteLine("Texto a convertir = {0}", args[0]);

      DectoBin oBin = new DectoBin();

      for(int i = 0; i < args[0].Length; i++) {
        char c = args[0][i];
        cbinario = "";
        cbinario += oBin.convertir((int)c);
        cCadena += cbinario.PadLeft(8, '0');
      }

      restocCadena = cCadena.Length % 6;
      int anadir = 0;

      for(int i = 0; (cCadena.Length + i) % 6 != 0; i++)
        anadir += 1;

      if(restocCadena != 0)
        cCadena = cCadena.PadRight(cCadena.Length + anadir, '0');

      string tabla64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      string enBase64 = "";
      int posicion = 0;

      for(int i = 1; i <= cCadena.Length / 6; i++) {
        string String6 = cCadena.Substring((posicion), 6);
        posicion = posicion + 6;
        int nDecimal = 0;

        for(int j = 1; j <= 6; j++)
          nDecimal += String6[6 - j] == '1' ? (1 << (j - 1)) : 0;

        enBase64 += tabla64[nDecimal];
      }

      anadir = 0;

      for(int i = 0; (enBase64.Length + i) % 4 != 0; i++)
        anadir += 1;

      enBase64 = (enBase64.Length % 4 != 0) ? enBase64.PadRight(enBase64.Length + anadir, '=') : enBase64;

      Console.WriteLine(" ");
      Console.WriteLine("Cadena codificada --> {0}", enBase64);
      //Console.WriteLine(" ");
      //Console.WriteLine("Pulse una tecla para terminar.");
      //Console.ReadLine();
      return 0;
    }
  }
}

// Clase para convertir a binario.
// Adaptada para devolver el valor
// Posteada por RHC.
class DectoBin {
  public double convertir(int n) {
    double binario = 0;
    long potencia = 0;
    int num = n;

    do {
      potencia++;
      n = n / 2;
    } while(n != 0);

    int Res = 0;
    double pot = 0, base10 = 10;
    n = num;

    do {
      Res = n % 2;

      if(pot < potencia)
        binario += Res * Math.Pow(base10, pot);

      pot++;
      n = n / 2;
    } while(n != 0);

    return binario;
  }
}

Mi código en Java (que no funciona con acentos):
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;
    }
}

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);
    }
}


« Última modificación: 20 Septiembre 2012, 05:36 am por Fireball-CH » En línea

Video en el que explico cómo instalar y configurar Apache 2.0.54, PHP 5.0.0 y MySQL 4.0.20: http://www.mediafire.com/?fevmmnlyzzd
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda :Codificación Y Compresión De Un MP3
Multimedia
00000000000 3 2,055 Último mensaje 11 Noviembre 2005, 07:56 am
por Sourraund
Duda con java en la codificacion bluetooth
Java
Lycans 1 2,115 Último mensaje 18 Abril 2007, 02:50 am
por coolfrog
Pequeña demostración de codificación en Base64
Java
Fireball-CH 6 6,952 Último mensaje 28 Septiembre 2012, 06:50 am
por Fireball-CH
[DUDA] ¿Como funciona la codificacion?
Dudas Generales
Meine programmen 3 2,521 Último mensaje 24 Diciembre 2012, 17:26 pm
por Ori-chan
Duda con encoding y el modulo base64 en python3
Scripting
retr02332 4 2,437 Último mensaje 30 Noviembre 2019, 02:22 am
por retr02332
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines