[Ayuda] Conversiones *char - int

Iniciado por Miky Gonzalez, 17 Septiembre 2013, 17:43 PM

0 Miembros y 2 Visitantes están viendo este tema.

Miky Gonzalez

Supongamos que yo tengo la siguiente matriz:

char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};

Con esta matriz se podrian hacer muchas cosas, desde interpretarla, hasta leer numeros. Mi pregunta:

En la posición 5 (recordar que empieza desde 0) y en la 6 hay 0xFF. Perfectamente podria poner en numero entero como 256, 256. Pero mi cuestion es: ¿Cómo puedo leer esos dos 0xFF, para que me queden como un 0xFFFF (tamaño de short int). Para que me entiendan, si hubiera: 0x4F, 0x33; quedaria: 0x4F33.

Se me ocurrieron varias opciones como: (0x4F << 2) &  0x33, pero ningun me funciona. ¿Podrían ayudarme?
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

rir3760

Supongo se trata de C, ¿Correcto?

Un problema importante es la declaración del array:
char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
Ya que el tipo de los elementos es char y este usualmente tiene un rango valido de -128 a 127, si tratas de almacenar un valor mayor como 255 se genera comportamiento no definido.

Para concatenar los dos bytes la forma mas fácil es desplazando el byte mas significativo a la izquierda un numero de bits indicado por la macro CHAR_BIT (usualmente ocho) y al resultado se le realiza una operación OR con el byte menos significativo. Por ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* CHAR_BIT */

int main(void)
{
   int num[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0x4F, 0x33, 0x00};
   
   printf("0x%4X\n", num[5] << CHAR_BIT | num[6]);
   
   return EXIT_SUCCESS;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

Miky Gonzalez

#2
Sólo tengo un problema, y es que mi matriz declarada tiene que ser declarada como char. De ahí el problema:
0xAA, 0xBB declarados ambos como char deben pasar a ser 0xAABB. :S
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

amchacon

Cita de: Miky Gonzalez en 17 Septiembre 2013, 17:43 PM¿Cómo puedo leer esos dos 0xFF, para que me queden como un 0xFFFF (tamaño de short int).
Y no te vale con un simple cast?

#include <stdio.h>

int main()
{
    char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};

    for (short i = 0;i < 8;i++)
        printf("%d \n",(unsigned short)codigo[i]);

    return 0;
}


O bien:

#include <stdio.h>

int main()
{
    char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
    unsigned short valor = codigo[1];
    printf("%d \n",valor);
   
    return 0;
}
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

Miky Gonzalez

Ahí está el problema en la conversión por referencia, parece que se comete un bug en el gcc, porque en otras distros de gcc me funciona (lo recien acabo de comprobar, incluso en codepad), pero en la que yo uso no)... creo que no es problema de la programación, porque al convertir este a un short int, y almacenar el valor en un short int, al mostrarlo me devuelve un int.
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

eferion

A ese nivel se te presenta un problema: arquitecturas big endian vs little endian.

Si tomamos por ejemplo el número 0x10203040, en memoria se guardará así:

* big endian: 0x10 0x20 0x30 0x40
* little endian: 0x40 0x30 0x20 0x10

Si tu accedes a los registros con un tipo char 8 bits... notarás la diferencia porque en ese caso la memoria la vas a recorrer siempre de forma secuencial... mientras que si manejas tipos de 32 bits no vas a notar diferencias.

0xDani

#6
unsigned char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
unsigned short *ptr = codigo + 5;
printf("%x\n", *ptr);


Tal vez eso funcione.

Saludos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

rir3760

Cita de: Miky Gonzalez en 17 Septiembre 2013, 21:08 PMSólo tengo un problema, y es que mi matriz declarada tiene que ser declarada como char.
Entonces declara el array con el tipo unsigned char.

Cita de: Miky Gonzalez en 17 Septiembre 2013, 21:08 PMDe ahí el problema:
0xAA, 0xBB declarados ambos como char deben pasar a ser 0xAABB.
Utilizando los operadores de desplazamiento y OR a nivel de bits:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void)
{
   unsigned char byte[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xAA, 0xBB, 0x00};
   unsigned short sh = byte[5] << CHAR_BIT | byte[6];
   
   printf("0x%X + 0x%X ==> 0x%X\n", byte[5], byte[6], sh);
   /* Imprime: 0xAA + 0xBB ==> 0xAABB */
   
   return EXIT_SUCCESS;
}


Otras formas, como ya te comento eferion, tienen sus problemas.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

0xDani

Hay algún problema con la forma que yo he propuesto?
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

rir3760

Cita de: 0xDani en 19 Septiembre 2013, 17:37 PMHay algún problema con la forma que yo he propuesto?
Al convertir la dirección de tipo "unsigned char *" a "unsigned short *" surgen dos problemas: 1) el ya comentado por eferion y 2) el puntero resultante debe cumplir con los requisitos de alineación para el tipo "unsigned short *".

Otra opción es utilizar una unión cuyos campos sean arrays: uno de caracteres y otros mas de tipo short, int, etc. pero en este caso hay que revisar la documentación del compilador para saber si se soportan lecturas/escrituras intercaladas (escribir utilizando el array de caracteres y luego leer utilizando el array de short's). Asi se elimina el problema de alineación pero queda el otro (orden de los bytes).

La única solución portable que recuerdo es utilizando los operadores de desplazamiento y OR a nivel de bits.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language