Convertir binarios a caracter ASCII en C

publicado por: Anonymous

Alguien me puediera ayudar con algun programa escrito en C a convertir una cadena de binarios en una cadena de caracteres en ASCII?,ya recibí una muy buena respuesta pero no están de más otras sugerencias.
Muchas gracias de antemano.
Saludos

solución

Bien como sucede muchas veces, el mismo resultado se puede obtener de muchas maneras, yo estuve barajando varias opciones, como por ejemplo parsear la tabla ASCII y usar el incremento de 32 entre mayusculas y minusculas, pero al final me decidi por el uso de lo siguiente:

int main(void)
{
    //Test contiene la informacion.
    char informacion[] = "010000100110100101100101011011100111011001100101011011100110100101100100011011110010000001100001001000000101001101110100011000010110001101101011010011110111011001100101011100100110011001101100011011110111011100101110";

    //Se usara para mostrar la informacion
    char *textDeco;

    int informacionLength, sim;

    //usamos strlen
    informacionLength = strlen(informacion);

    /*
    para codificar cualquier caracter ASCII en binario, 
    necesitamos al menos 7 bits, en la practica se añade 
    un octavo bit y se utiliza como bit de paridad para detectar errores
    de transmision. 
    Sin embargo, estos 8 bits (1 byte) tambien permiten representar un 
    mayor rango de caracteres puede mirar ASCII extendido
    */

    //basandonos en lo anterior hacemos estas matematicas, puesto que cada simbolo "consta"
    //de 8 (digamos un octeto, si se trabajara con bits por decirlo de alguna manera "reales o directamente") (o para este caso los 0 y 1 no son bits, sino que son representados en char osea 1 byte por cada digito) operamos y mas uno para la terminacion.

    sim = informacionLength / 8 + 1;

    //malloc
    textDeco = malloc(sim + 1);

    //Llamada a 1 de las dos funciones creadas para usar    
    binarioToText(informacion, informacionLength, sim, textDeco);

    //pues eso
    printf("La informacion contenida en ASCII: %sn", textDeco);

    //free
    free(textDeco);

    return 0;
}

void binarioToText(char *informacionBin, int informacionLength, int sim, char *text ){

        int a;

        for(a = 0; a < informacionLength; a += 8, informacionBin += 8){

            char *byte = informacionBin;

            //Arimetica de punteros
            //*(byte+8) = '';

            //azucar para lo anterior
            byte[8] = '';

            //lo que nos retorna lo añadimos y asi hasta leer enviar toda la informacion
            *text ++ = binarioToDecimal(byte, 8);
        }

        //text -= sim;
    }

creo que esta es la parte mas delicada no porque sea dificil, sino porque no se si me expresare de la manera mas simple y adecuada.

unsigned long binarioToDecimal(char *binario, int length){

        int a;

        unsigned long decimal = 0;
        unsigned long peso = 1;

        binario += length - 1;
        peso = 1;

        //Vamos a recorrer el for tantas veces como indique length,
        //nada nuevo, pero tener encuenta que binario decrece,
        //el numero de bytes de su tipo de datos

        //saltamos hacia atras el tamaño de char "8" porque aunque 8 bits, son ocho digitos "01",
        //un byte, un char son "8" osea que 8 representa uno que es un simbolo digamos 0 o 1, al
        //al ser un char donde esta almacenado y no se esta accediendo a los "bit puros realmente".

        //se envia un length de 8, que simulan los 8 bits, pero realmente al ser caracteres no son
        //1 byte sino 8 * 1.

        for(a = 0; a < length; ++a, --binario){

            if(*binario == '1'){
                decimal += peso;
            }

            //
            peso *= 2;
        }

        return decimal;
    }

Para tratar de explicar mejor la funcion anterior:

Partiendo de que el digito del extremo derecho tiene un peso de 1.
porque 2^0 = 1.
entoces si el valor del digito es 1, se suma al resultado, ahora el siguiente a la
izquierda tiene el doble del peso del anterior y haci hasta pasar por todos, digamos la simulacion
del octeto
, tener en cuenta que solo se suma si, el digito es 1, pero en cada desplazamiento se
dobla el valor del peso
a la izquierda.

Quizas con un ejemplo se entienda mejor lo que quiero decir arriba:

Binario                     Decimal

01010101                  =  X?

1 peso                * 1 = 1 (es uno con lo que se suma) 
2 (doblamos peso)     * 0 = 0 (no es uno con lo que no se suma)
4 (doblamos)          * 1 = 4 (es uno con lo que se suma)
8 (doblamos)          * 0 = 0 (no es uno con lo que no se suma)
16(doblamos anterior) * 1 = 16(es uno con lo que se suma)
32 ...                * 0 = 0 (no es uno con lo que no se suma)
64 ...                * 1 = 64(es uno con lo que se suma)
128 ...               * 0 = 0 (no es uno con lo que no se suma)

resultado = 1 + 4 + 16 + 64 = 85

ideoneTest

#include <stdio.h>
#include <string.h>

unsigned long binarioToDecimal(char *binario, int length){

        int a;

        unsigned long decimal = 0;
        unsigned long peso = 1;

        binario += length - 1;
        peso = 1;

        //Vamos a recorrer el for tantas veces como indique length,
        //nada nuevo, pero tener encuenta que binario decrece,
        //el numero de bytes de su tipo de datos

        //saltamos hacia atras el tamaño de char "8" porque aunque 8 bits, son ocho digitos "01",
        //un byte, un char son "8" osea que 8 representa uno que es un simbolo digamos 0 o 1, al
        //al ser un char donde esta almacenado y no se esta accediendo a los bit puros realmente.

        //se envia un length de 8, que simulan los 8 bits, pero realmente al ser caracteres no son
        //1 byte sino 8 * 1.

        for(a = 0; a < length; ++a, --binario){

            if(*binario == '1'){
                decimal += peso;
            }

            //
            peso *= 2;
        }

        return decimal;
    }

    void binarioToText(char *informacionBin, int informacionLength, int sim, char *text ){

    int a;

    for(a = 0; a < informacionLength; a += 8, informacionBin += 8){

        char *byte = informacionBin;

        //Arimetica de punteros
        //*(byte+8) = '';

        //azucar para lo anterior
        byte[8] = '';

        //lo que nos retorna lo añadimos y asi hasta leer enviar toda la informacion
        *text ++ = binarioToDecimal(byte, 8);
    }

    //text -= sim;
}

int main(void)
{
    //Test contiene la informacion.
    char informacion[] = "010000100110100101100101011011100111011001100101011011100110100101100100011011110010000001100001001000000101001101110100011000010110001101101011010011110111011001100101011100100110011001101100011011110111011100101110";

    //Se usara para mostrar la informacion
    char *textDeco;

    int informacionLength, sim;

    //usamos strlen
    informacionLength = strlen(informacion);

    /*
    para codificar cualquier caracter ASCII en binario, 
    necesitamos al menos 7 bits, en la practica se añade 
    un octavo bit y se utiliza como bit de paridad para detectar errores
    de transmision. 
    Sin embargo, estos 8 bits (1 byte) también permiten representar un 
    mayor rango de caracteres ver ASCII extendido
    */

    //basandonos en lo anterior hacemos estas matematicas, puesto que cada simbolo "consta"
    //de 8 (digamos un octeto) operamos y mas uno para la terminacion. 
    sim = informacionLength / 8 + 1;

    //malloc
    textDeco = malloc(sim + 1);

    binarioToText(informacion, informacionLength, sim, textDeco);

    printf("La informacion contenida en ASCII: %sn", textDeco);

    //free
    free(textDeco);

    return 0;
}
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *