Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Miky Gonzalez en 17 Septiembre 2013, 17:43 pm



Título: [Ayuda] Conversiones *char - int
Publicado por: Miky Gonzalez en 17 Septiembre 2013, 17:43 pm
Supongamos que yo tengo la siguiente matriz:

Código
  1. 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?


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: rir3760 en 17 Septiembre 2013, 18:18 pm
Supongo se trata de C, ¿Correcto?

Un problema importante es la declaración del array:
Código
  1. 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:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h> /* CHAR_BIT */
  4.  
  5. int main(void)
  6. {
  7.   int num[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0x4F, 0x33, 0x00};
  8.  
  9.   printf("0x%4X\n", num[5] << CHAR_BIT | num[6]);
  10.  
  11.   return EXIT_SUCCESS;
  12. }

Un saludo


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: Miky Gonzalez en 17 Septiembre 2013, 21:08 pm
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


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: amchacon en 17 Septiembre 2013, 21:45 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?

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
  6.  
  7.    for (short i = 0;i < 8;i++)
  8.        printf("%d \n",(unsigned short)codigo[i]);
  9.  
  10.    return 0;
  11. }
  12.  

O bien:

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
  6.    unsigned short valor = codigo[1];
  7.    printf("%d \n",valor);
  8.  
  9.    return 0;
  10. }
  11.  


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: Miky Gonzalez en 17 Septiembre 2013, 22:07 pm
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.


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: eferion en 18 Septiembre 2013, 14:55 pm
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.


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: 0xDani en 18 Septiembre 2013, 21:00 pm
Código
  1. unsigned char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
  2. unsigned short *ptr = codigo + 5;
  3. printf("%x\n", *ptr);
  4.  

Tal vez eso funcione.

Saludos.


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: rir3760 en 19 Septiembre 2013, 02:40 am
Só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.

De 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:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. int main(void)
  6. {
  7.   unsigned char byte[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xAA, 0xBB, 0x00};
  8.   unsigned short sh = byte[5] << CHAR_BIT | byte[6];
  9.  
  10.   printf("0x%X + 0x%X ==> 0x%X\n", byte[5], byte[6], sh);
  11.   /* Imprime: 0xAA + 0xBB ==> 0xAABB */
  12.  
  13.   return EXIT_SUCCESS;
  14. }

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

Un saludo


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: 0xDani en 19 Septiembre 2013, 17:37 pm
Hay algún problema con la forma que yo he propuesto?


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: rir3760 en 19 Septiembre 2013, 18:37 pm
Hay 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


Título: Re: [Ayuda] Conversiones *char - int
Publicado por: Miky Gonzalez en 19 Septiembre 2013, 21:25 pm
Exactamente como dice rir3760, la única forma portable es utilizando ese método (operaciones a nivel de bits). Comprobado por mi en varios compiladores (gcc [3.x] y gcc[4.x], visual c++, dev-cpp [mingw 3.6]). Los resultando en algunos casos, son "muy extraños" (se vacia buffer de entrada).