2010-04-17 26 views
10

Tengo un control que tiene una matriz de bytes.Convierte 2 bytes a un número

De vez en cuando hay dos bytes que me dicen algo de información sobre el número de elementos futuros en la matriz.

Así como un ejemplo yo pudiera tener:

 
... 
... 
Item [4] = 7 
Item [5] = 0 
... 
...

El valor de este es claramente 7.

Pero qué pasa con esto?

 
... 
... 
Item [4] = 0 
Item [5] = 7 
... 
...

¿Alguna idea de lo que eso significa (como una int normal)?

Fui a binario y pensé que podría ser 11100000000 que es igual a 1792. Pero no sé si así es como realmente funciona (es decir, si usa los 8 elementos completos para el byte).

¿Hay alguna manera de saber esto sin realizar pruebas?

Nota: Estoy usando C# 3.0 y Visual Studio 2008

+4

Parece que nos está pidiendo que realicemos ingeniería inversa de algunos datos serializados. Eso va a ser complicado. Al menos podría publicar algunos ejemplos de la matriz de bytes completa y lo que corresponde a tres o cuatro ejemplos simples. Pero, ¿por qué quieres saber esto de todos modos? ¿Que problema estas tratando de resolver? –

+0

Estoy tratando de descifrar la matriz de bytes devuelta por el control Signature en el control OpenNETCF para poder rotarla 180 grados. Consulte esta pregunta http://stackoverflow.com/questions/2657388/opennetcf-signature-control-question para obtener más detalles. – Vaccano

Respuesta

19

BitConverter puede convertir fácilmente los dos bytes en un valor entero de dos bytes:

// assumes byte[] Item = someObject.GetBytes(): 
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5] 
+1

@Macho Matt: si quieres comentar una respuesta ya aceptada, es mejor dejar un comentario que editar la pregunta en sí misma. Además, su punto no era estrictamente exacto: no importa si el sistema de la computadora es big-endian o little-endian, solo importa si el sistema que creó originalmente la matriz de bytes tiene una endianidad diferente a la del sistema ejecutando el código .NET aquí. – MusiGenesis

+0

Eso supone que el MSB de la representación binaria de esos dos bytes es el bit de signo (1 = -ve, 0 = + ve). Si ese no es el caso, es decir, si el número no está firmado , entonces necesita usar esto. ushort num = BitConverter.ToUInt16 (Item, 4). También tenga en cuenta que eso tendrá un byte en el índice 5 como primer byte (el byte más significativo) si su arquitectura es poco endian. Read reinventingthewheel .azurewebsites.net/TwosComplementTut.aspx para mo re información sobre el bit de signo. –

11

Un número de dos bytes tiene un bajo y un byte alto. El byte alto vale 256 veces más que el byte bajo:

value = 256 * high + low; 

Así, para alta y baja = 0 = 7, el valor es de 7. Pero para alta y baja = 7 = 0, el valor se convierte 1792.

Esto, por supuesto, supone que el número es un entero simple de 16 bits. Si es algo más elegante, lo anterior no será suficiente. Entonces necesita más conocimiento sobre cómo se codifica el número, para decodificarlo.

El orden en que aparecen los bytes alto y bajo está determinado por el endianness de la secuencia de bytes. En big-endian, verá alto antes que bajo (en una dirección inferior), en little-endian es al revés.

+9

También vale la pena señalar: '(alto << 8) | bajo' – GeReV

0

Si esos bytes son las "partes" de un entero, funciona así. Pero tenga en cuenta que el orden de los bytes es específico de la plataforma y que también depende de la longitud del entero (16 bit = 2 bytes, 32 bit = 4bytes, ...)

0

Use BitConveter.ToInt32 im not 100% seguro que le daría el resultado correcto, pero puede intentar

7

Usted dice "este valor es claramente 7", pero depende completamente de la codificación. Si asumimos bytes de ancho completo, entonces en little-endian, sí; 7, 0 es 7. Pero en big endian no lo es.

Por ascendente hacia la izquierda, lo que quiere decir

int i = byte[i] | (byte[i+1] << 8); 

y para big-endian:

int i = (byte[i] << 8) | byte[i+1]; 

Pero otros esquemas de codificación están disponibles; por ejemplo, algunos esquemas usan aritmética de 7 bits, con el 8vo bit como un bit de continuación. Algunos esquemas (UTF-8) ponen todos los bits de continuación en el primer byte (por lo que el primero tiene solo espacio limitado para los bits de datos) y 8 bits para el resto en la secuencia.

+0

Buen punto. Pero por el uso puedo ver que el valor es 7 (hay siete secciones más de coordenadas en la matriz. – Vaccano

2

Si simplemente desea poner esas dos bytes lado de la otra en formato binario, y ver lo que ese número es de grande en decimal, entonces es necesario utilizar este código:

  if (BitConverter.IsLittleEndian) 
      { 
       byte[] tempByteArray = new byte[2] { Item[5], Item[4] }; 
       ushort num = BitConverter.ToUInt16(tempByteArray, 0); 
      } 
      else 
      { 
       ushort num = BitConverter.ToUInt16(Item, 4); 
      } 

Si utiliza short num = BitConverter.ToInt16(Item, 4); como se ve en la respuesta aceptada, usted está asumiendo que el primer bit de esos dos bytes es el bit de signo (1 = negativo y 0 = positivo). Esa respuesta también supone que estás usando un sistema Big Endian. Consulte this para obtener más información sobre el bit de signo.

0

En caso de que el punto [5] es el MSB

  1. resultado ushort = BitConverter.ToUInt16 (nuevo byte [2] {artículo [5], punto [4]}, 0);

  2. int resultado = 256 * Elemento [5] + Elemento [4];

Cuestiones relacionadas