es posible concatenar un array byte?

Iniciado por Belial & Grimoire, 31 Enero 2014, 06:33 AM

0 Miembros y 1 Visitante están viendo este tema.

Belial & Grimoire

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.
.                                 

x64core

Cita de: 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.
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



eferion

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.

x64core

#3
Cita de: eferion en 31 Enero 2014, 08:46 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.

eferion

Cita de: x64Core en 31 Enero 2014, 08:57 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...

Belial & Grimoire

#5
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
.                                 

Yoel Alejandro

#6
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 (cpp) [Seleccionar]

unsigned char buffer[2] = {0x00, 0x02};


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

Código (cpp) [Seleccionar]

unsigned short int word1;

word1 = 0x0100 * buffer[1] + buffer[0];


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 (cpp) [Seleccionar]

unsigned ong int dword1;
char buffer[4];

/* aquí llenas el buffer */

/* luego convertimos */
dword1 = 0x01000000 * buffer[3] + 0x010000 * buffer[2] + 0x0100 * buffer[1] + buffer[0];


que es algo así como hacer:
Código (cpp) [Seleccionar]

dword1 = 256^3 * buffer[3]  + 256^2 * buffer[2] + 256 * buffer[1] + buffer[0];


=====================
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 ....
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

leosansan

Cita de: yoel_alejandro en  7 Febrero 2014, 02:36 AM
......................................................

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

Código (cpp) [Seleccionar]

unsigned short int word1;

word1 = 0x0100 * buffer[1] + buffer[0];


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! ..... !!!!




Yoel Alejandro

Cita de: leosansan en  7 Febrero 2014, 02:49 AM
;-) ;-) ;-) ;-) ;-)

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
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

x64core

@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.