Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Belial & Grimoire en 31 Enero 2014, 06:33 am



Título: es posible concatenar un array byte?
Publicado por: Belial & Grimoire en 31 Enero 2014, 06:33 am
hola

alguien sabe como podria o si es posible concatenar bytes de un mismo array, por ejemplo

BYTE *buffer[2] = {0x00, 0x02}

me gustaria poder concatenarla pero al reves para que quede asi... 0x200, porque necesito cambiar ese valor a decimal, que serian 512 y guardarlo en algun integer

lo intente con strcpy, strcat y memcpy pero no me funcionan porque el buffer es BYTE y aun haciendo cast (char) me tira error

alguien sabe alguna forma de lograr juntar los hexadecimales del array?, porque tambien necesito hacerlo con arrays mas grandes por ejemplo

buff = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00}

y necesito que quede asi 0x20000 para poder convertirlo en decimal

aguna idea o ejemplo que me puedan dar porfavor.


Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 31 Enero 2014, 08:42 am
hola

alguien sabe como podria o si es posible concatenar bytes de un mismo array, por ejemplo

BYTE *buffer[2] = {0x00, 0x02}

me gustaria poder concatenarla pero al reves para que quede asi... 0x200, porque necesito cambiar ese valor a decimal, que serian 512 y guardarlo en algun integer

lo intente con strcpy, strcat y memcpy pero no me funcionan porque el buffer es BYTE y aun haciendo cast (char) me tira error

alguien sabe alguna forma de lograr juntar los hexadecimales del array?, porque tambien necesito hacerlo con arrays mas grandes por ejemplo

buff = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00}

y necesito que quede asi 0x20000 para poder convertirlo en decimal

aguna idea o ejemplo que me puedan dar porfavor.
Si esto es relaciónado a los demás temas que he visto los miembros de la estructura definida deberian de apuntar correctamente cuando se
hacen referencia a ellos, de lo contrario esta mal definida la estructura (¿ Qué estructura es?).
Además en ambos casos ejemplo 1 y ejemplo 2 simplemente se hace un casting de word para obtener directamente 0x200 y de tipo DWORD para el segundo.

Lo de convertirlo de Hex a decimal parece que hay una gran confusión, la base numerica no tiene nada que ver es simplemente para representar los valores en memoria puede ser incluso octal o binario y los valores son los mismos. esto es diferente si hablamos de un
array de char's osea una cadena que para representar un entero en base hexadecimal podria tener 1 o 2 caracteres/bytes y para
representarlo en decimal hasta 3, en binario hasta 8, etc.

Y para enteros de valores altos (Mayores a QWORD o incluso a TBYTE ) pues vas a tener que usar mascaras y rotar los bytes/bits que quieres.
en el ejemplo de buffer[2] = {0x00,0x02}:

Valor = (buffer[1] << 8) | buffer[0]; // 0x200




Título: Re: es posible concatenar un array byte?
Publicado por: eferion en 31 Enero 2014, 08:46 am
Tienes que ser consciente que, hablando de forma básica, hay dos tipos de arquitecturas "big endian" y "little endian". La diferencia básica se encuentra en la forma en la que se almacena la información en memoria.

Big endian almacena los bytes de forma "natural", es decir, el dato 0x01020304 se almacenará en memoria tal que 0x01 0x02 0x03 0x04, mientras que en un little endian quedaría almacenado tal que 0x04 0x03 0x02 0x01.

Te lo comento porque dependiendo de la forma en la que recodifiques esos datos puedes acabar obteniendo un resultado inesperado en determinadas máquinas.

Dicho esto, una forma de operar es crearte un buffer del mismo tamaño al original y usarlo para invertir los valores del buffer ( el primero al último y así ).

Tienes que tener en cuenta que si el buffer es superior a 4 bytes no vas a poder realizar conversiones a int. sin perder información.


Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 31 Enero 2014, 08:57 am
Tienes que tener en cuenta que si el buffer es superior a 4 bytes no vas a poder realizar conversiones a int. sin perder información.
se puede hacer un casting superior a 4 bytes usando uint64_t/__int64 o incluso más si habilita extensiones especiales tales como SSE2 luego el compilador es el que se preocupa de generar las instrucciones correctas para trasladar los bytes.


Título: Re: es posible concatenar un array byte?
Publicado por: eferion en 31 Enero 2014, 09:26 am
se puede hacer un casting superior a 4 bytes usando uint64_t/__int64 o incluso más si habilita extensiones especiales tales como SSE2 luego el compilador es el que se preocupa de generar las instrucciones correctas para trasladar los bytes.


Eso lo se, pero lo que intentaba dejar claro es que un int como tal son 32 bits... por lo que una conversión a int que abarque más de 32 bits forzosamente va a generar un número incorrecto...


Título: Re: es posible concatenar un array byte?
Publicado por: Belial & Grimoire en 31 Enero 2014, 19:55 pm
ok, ya entendi y logre hacerlo

se que no es necesario la conversion, pero intento hacer lo mismo que la funcion BitConverter para poder continuar, es que intento no hacer un copy - paste de codigos, asi que si quiero aprender bien, no tengo de otra mas que rehacer lo que veo para poder comprender como funcionan las cosas  :-\

gracias  ;D


Título: Re: es posible concatenar un array byte?
Publicado por: Yoel Alejandro en 7 Febrero 2014, 02:36 am
Hola ...... Mira mi consejo es "matar la serpiente por la cabeza". Busca siempre la solución MAS SIMPLE, y evita cualquier posibilidad de error. Y no te compliques buscando códigos por toda la web, y repito, medita hasta encontrar la solución más lógica y simple.

Si quieres convertir el arreglo:

Código
  1. unsigned char buffer[2] = {0x00, 0x02};
  2.  

en 0x0200, de una manera independiente de la arquitectura, pues simplemente has la aritmética:

Código
  1. unsigned short int word1;
  2.  
  3. word1 = 0x0100 * buffer[1] + buffer[0];
  4.  

así que te dará: 0x0100 * 0x02 + 0x00 , o en decimal 256 * 2 + 0 = 512

Listo  :laugh:

¿La lógica de esto? Veamos, pensando en decimal .... ¿cómo conviertes el arreglo {2, 3} en el número decimal 23? Pues, multiplicas la parte más significativa (el orden de la parte más y la menos significativa la defines tú en el software) por la base numérica, y le sumas la menos significativa. En tu caso, la "base" resultante de agrupar en lotes de 8 bits (o sea, bytes) será 256, o 0x0100.

En caso que quieras llevar un arreglo de cuatro bytes a un entero de 32 bits (para lo que requieres declarar long int) debes usar la fórmula:

Código
  1. unsigned ong int dword1;
  2. char buffer[4];
  3.  
  4. /* aquí llenas el buffer */
  5.  
  6. /* luego convertimos */
  7. dword1 = 0x01000000 * buffer[3] + 0x010000 * buffer[2] + 0x0100 * buffer[1] + buffer[0];
  8.  

que es algo así como hacer:
Código
  1. dword1 = 256^3 * buffer[3]  + 256^2 * buffer[2] + 256 * buffer[1] + buffer[0];
  2.  

=====================
Nota (sobre los tipos int): El estándar ANSI C especifica que el tipo "short int" lleva como mínimo 16 bits, por que lo que alcanza para almacenar un doble byte. Especifica también que el tipo "long int" lleva como mínimo 32 bits, y que "int" mayor a "short int" y menor o igual a "long int". Así que "long int" alcanza con seguridad para el tipo cuádruple byte.

Esta solución es independiente de hardware, y no fallará siempre y cuando el compilador respete los tipos enteros definidos por el estándar ANSI C, que es algo que seguro se cumple!!

... Espero te sirva ....


Título: Re: es posible concatenar un array byte?
Publicado por: leosansan en 7 Febrero 2014, 02:49 am
......................................................

en 0x0200, de una manera independiente de la arquitectura, pues simplemente has la aritmética:

Código
  1. unsigned short int word1;
  2.  
  3. word1 = 0x0100 * buffer[1] + buffer[0];
  4.  

así que te dará: 0x0100 * 0x02 + 0x00 , o en decimal 256 * 2 + 0 = 512

Listo  :laugh:
..........................................
... Espero te sirva ....

;-) ;-) ;-) ;-) ;-)

Me encantan las soluciones simples y de pura lógica.

Me duele que no se me haya ocurrido antes. :rolleyes:

Enhorabuena amigo yoel_alejandro

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: es posible concatenar un array byte?
Publicado por: Yoel Alejandro en 8 Febrero 2014, 15:57 pm
;-) ;-) ;-) ;-) ;-)

Me encantan las soluciones simples y de pura lógica.

Me duele que no se me haya ocurrido antes. :rolleyes:

Enhorabuena amigo yoel_alejandro


Gracias amigo leosasan!!!! Lo que pasa es que también soy aficionado a las matemáticas, y suelo enfocar estos problemillas aritméticos por su base teórico-algebraica, jeje


Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 8 Febrero 2014, 17:52 pm
@yoel_alejandro:

<<,>> = *, /
& = -
| = +

Es lo mismo, al final es el compilador quien decide qué instrucción usará, pero en realidad la manipulación de bits es mucho más
rapida que usar la multiplicación, eso incluye AND y OR.




Título: Re: es posible concatenar un array byte?
Publicado por: Yoel Alejandro en 9 Febrero 2014, 18:12 pm
x64Core, es cierto lo que dices, la rotación es más rápida.

El código podría entonces quedar así, para concatenar 2 bytes en un entero de 16bits:

Código:
unsigned short word1;
 
word1 = (unsigned short) buffer[1] << 8 + buffer[0];

Para concatenar 4 bytes bajo la forma de un entero de 32 bits, sería:

Código:
unsigned long int dword1;
char buffer[4];
 
/* luego convertimos */
dword1 = (unsigned long )buffer[3] << 24 + (unsigned long )buffer[2] << 16 + (unsigned long )buffer[1] << 8 + buffer[0];

Pero yo no sabría garantizar de forma absoluta la infalibilidad de este código. Lei en un libro que las operaciones a nivel de bits son "altamente dependientes de máquina", por lo que pudieran tener un comportamiento indeseado dependiendo de la arquitectura.

Como dijo otro usuario, en algunos sistemas el byte bajo es el menos significativo, mientras en otros sistemas es el más significativo, por eso cuando hablamos de "desplazamiento de bits hacia la izquierda", ¿desplaza al byte más alto o al más bajo?

Pero suponemos que al hacer el cast explícito (unsigned sort), ---el cual es indispensable en cualquier caso---, el compilador entiende que la variable en cuestión ocupa dos bytes de memoria y debe hacer el desplazamiento de bits hacia el byte más significativo, sea que este ocupe la posición más baja o más alta de memoria, dependiendo de la máquina donde esté implementado el programa. Y similarmente con el caso de los enteros de 32 bits.

Pero es una suposición mía, no lo puedo asegurar al 100%. Por ello propuse la solución basada en multiplicación, que creí más segura.


Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 9 Febrero 2014, 22:33 pm
x64Core, es cierto lo que dices, la rotación es más rápida.

El código podría entonces quedar así, para concatenar 2 bytes en un entero de 16bits:

Código:
unsigned short word1;
 
word1 = (unsigned short) buffer[1] << 8 + buffer[0];

Para concatenar 4 bytes bajo la forma de un entero de 32 bits, sería:

Código:
unsigned long int dword1;
char buffer[4];
 
/* luego convertimos */
dword1 = (unsigned long )buffer[3] << 24 + (unsigned long )buffer[2] << 16 + (unsigned long )buffer[1] << 8 + buffer[0];

Pero yo no sabría garantizar de forma absoluta la infalibilidad de este código. Lei en un libro que las operaciones a nivel de bits son "altamente dependientes de máquina", por lo que pudieran tener un comportamiento indeseado dependiendo de la arquitectura.

Como dijo otro usuario, en algunos sistemas el byte bajo es el menos significativo, mientras en otros sistemas es el más significativo, por eso cuando hablamos de "desplazamiento de bits hacia la izquierda", ¿desplaza al byte más alto o al más bajo?

Pero suponemos que al hacer el cast explícito (unsigned sort), ---el cual es indispensable en cualquier caso---, el compilador entiende que la variable en cuestión ocupa dos bytes de memoria y debe hacer el desplazamiento de bits hacia el byte más significativo, sea que este ocupe la posición más baja o más alta de memoria, dependiendo de la máquina donde esté implementado el programa. Y similarmente con el caso de los enteros de 32 bits.

Pero es una suposición mía, no lo puedo asegurar al 100%. Por ello propuse la solución basada en multiplicación, que creí más segura.

Estoy interesado en qué fuente es quien dice que las operaciones a nivel de bits son altamente dependiente de maquina.
Me pregunto si se refieren a la arquitectura ( Little, Endian ) espero que no...



Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 10 Febrero 2014, 21:57 pm
Aun esperando el enlace donde dice eso yoel_alejandro. Además no habia visto esto:
Citar
Código:
word1 = (unsigned short) buffer[1] << 8 + buffer[0];

Como dije, es mejor la manipulacion de bits, se puede sustituir la operacion de suma con el operador OR, lo cual vendria ser exactamente
la misma operacion que escribí en mi primer 'post'.


Título: Re: es posible concatenar un array byte?
Publicado por: Yoel Alejandro en 11 Febrero 2014, 02:36 am
Estimado, Deitel&Deitel, "Cómo programar en C/C++", segunda edición. en Español, 1995.

En el tema "Estructuras, uniones, manipulaciones de bits y enumeraciones", p. 407, reza:

Citar
"(...) También los programas de las secciones 10.9 y 10.10 fueron probados en una Macintosh de Apple usando Thisk C y una PC compatible, utilizando Borland C++. Ambos sistemas utilizan enteros de 16 bits (2 bytes). Dada la naturaleza de dependencia de la máquina de las manipulaciones a nivel de bits, estos programas pudieran no funcionar en su sistema"
Como vez, lo dicen Deitel&Deitel (dos profesores con décadas de experiencia enseñando C), y no yo. Por eso digo que yo no se ...

Por otra parte, ten cuidado x64 con que la suma aritmética no siempre es igual a la suma lógica. Los resultados no son iguales en caso de que se practique una suma binaria con acarreo. Por ejemplo, la suma aritmética de b'01' y b'01' será b'10' (2 en decimal). En cambio, la misma suma lógica produce b'01'. En nuestro caso, por la teoría subyacente de sistemas numéricos sabemos que debe ser la suma aritmética.

============
Por último, respecto a lo extraño de la sentencia:

Código
  1. word1 = (unsigned short) buffer[1] << 8 + buffer[0];

la acabo de probar en mi compilador (GNU gcc acorde con C99) y me dice que está bien, sólo recomienda revisar la prioridad de los operadores. Entonces, revisando más a fondo el asunto recorde que el operador de suma posee mayor prioridad que el de desplazamiento (sorry por el olvido  :-[), por lo que lo correcto sería en todo caso:

Código
  1. word1 = ((unsigned short) buffer[1] << 8) + buffer[0];

y similarmente con las demás.


Título: Re: es posible concatenar un array byte?
Publicado por: x64core en 15 Febrero 2014, 18:58 pm
Estimado, Deitel&Deitel, "Cómo programar en C/C++", segunda edición. en Español, 1995.

En el tema "Estructuras, uniones, manipulaciones de bits y enumeraciones", p. 407, reza:
Como vez, lo dicen Deitel&Deitel (dos profesores con décadas de experiencia enseñando C), y no yo. Por eso digo que yo no se ...

Por otra parte, ten cuidado x64 con que la suma aritmética no siempre es igual a la suma lógica. Los resultados no son iguales en caso de que se practique una suma binaria con acarreo. Por ejemplo, la suma aritmética de b'01' y b'01' será b'10' (2 en decimal). En cambio, la misma suma lógica produce b'01'. En nuestro caso, por la teoría subyacente de sistemas numéricos sabemos que debe ser la suma aritmética.

============
Por último, respecto a lo extraño de la sentencia:

Código
  1. word1 = (unsigned short) buffer[1] << 8 + buffer[0];

la acabo de probar en mi compilador (GNU gcc acorde con C99) y me dice que está bien, sólo recomienda revisar la prioridad de los operadores. Entonces, revisando más a fondo el asunto recorde que el operador de suma posee mayor prioridad que el de desplazamiento (sorry por el olvido  :-[), por lo que lo correcto sería en todo caso:

Código
  1. word1 = ((unsigned short) buffer[1] << 8) + buffer[0];

y similarmente con las demás.

Hola, perdon por la tardanza; habia olvidado el tema. alejandro, pues claro que las operaciones que se pueden hacer con los operadores
logicos no pueden reemplazar a los operadores aritmeticos, pero en este caso era simplemente movimientos de valores enteros ( No en
realidad, era de un byte ) así que lo mejor es hacerlo mediante operadores logicos, sino pues, talvez puedes decirnos algo mucho más
justificado de porqué hacerlo de otra manera ( vamos, estamos en el 2014 ).

Por cierto,  puede que nos quieras decir cómo en tu suma logica el binario 01 + 01 daria como resultado 01?
( ¿No crees que te haz empatanado un poco? )