2011-04-13 9 views
21

Motivo: Me gustaría convertir hashes (MD5/SHA1, etc.) en enteros decimales con el fin de hacer códigos de barras en Code128C. Para simplificar, prefiero que todos los números resultantes (grandes) sean positivos.byte [] a BigInteger sin firmar?

soy capaz de convertir byte [] para BigInteger en C# ...
de ejemplo de lo que tengo hasta ahora:

byte[] data; 
byte[] result; 
BigInteger biResult; 

result = shaM.ComputeHash(data); 
biResult = new BigInteger(result); 

Pero (CS oxidada aquí) Estoy en lo correcto que una matriz de bytes puede siempre interpretarse de dos maneras: a: como un número con signo B: como un número sin signo

¿es posible hacer una BigInteger sin signo de un byte [] en C#?

¿Debo simplemente anteponer un 0x00 (cero byte) al frente del byte []?

EDIT:. Gracias a AakashM, Jon y Adam Robinson, añadiendo un byte cero logró lo que necesitaba \

Edit2: Lo principal que debería haber hecho era leer el documento detallado de la BigInteger (byte []) constructor, entonces habría visto las secciones sobre cómo restringir a números positivos al agregar el byte cero.

+1

debe marcar una respuesta aceptada –

Respuesta

32

El estado remarks for the BigInteger constructor que puede asegurarse de que cualquier BigInteger creado a partir de un byte[] está sin firmar Si escribe un byte 00al final de la matriz antes de llamar al constructor.

Nota: el constructor BigInteger espera que la matriz esté en orden little-endian. Tenga esto en cuenta si espera que el resultado BigInteger tenga un valor particular.

5

Pero (oxidado CS aquí) Estoy en lo correcto que una matriz de bytes siempre se puede interpretar de dos maneras: A: como un número con signo B: como un número sin signo

Lo que es más correcta es que todos los números (en virtud de estar almacenados en la computadora) son básicamente una serie de bytes, que es lo que es una matriz de bytes. No es correcto decir que una matriz de bytes siempre se puede interpretar como una versión firmada o no firmada de un tipo numérico en particular, ya que no todos los tipos numéricos tienen versiones firmadas y sin firmar. Los tipos de punto flotante generalmente solo tienen versiones firmadas (no hay udouble o ufloat) y, en esta instancia particular, no hay una versión sin firma de BigInteger.

Por lo tanto, en otras palabras, no, no es posible, pero dado que BigInteger puede representar un valor entero arbitrariamente grande, no está perdiendo ningún rango en virtud de su firma.

En cuanto a su segunda pregunta, lo que se necesita para anexar 0x00 para poner fin a extremo de la matriz, como el BigInteger constructor analiza los valores de orden de bytes ascendente hacia la izquierda.

5

Examinar the documentation for the relevant BigInteger constructor, vemos:

Los bytes individuales en el valor matriz debe estar en ascendente hacia la izquierda orden, a partir del byte de orden inferior a byte de orden más alto

[...]

Constru ctor espera valores positivos en la matriz de bytes para usar representación de signo y magnitud, y valores negativos para usar la representación complementaria de dos. En otras palabras , si se establece el bit de mayor orden del byte de mayor orden en valor, el valor de BigInteger resultante es negativo. Dependiendo de la fuente de la matriz de bytes, esto puede causar que un valor positivo se malinterprete como un valor negativo.

[...]

Para evitar valores positivos de ser mal interpretados como valores negativos, que puede agregar un valor de cero bytes al final de la matriz.

4

Como han señalado otras respuestas, debe agregar un byte 00 al final de la matriz para asegurarse de que BigInteger resultante es positivo.

Según la the BigInteger Structure (System.Numerics) MSDN Documentation

Para evitar que el constructor BigInteger (byte []) a partir de confundir representación de complemento a dos de un valor negativo con el signo y la magnitud representación de un valor positivo, los valores positivos en los que el el bit más significativo del último byte de la matriz de bytes normalmente se establecería debería incluir un byte adicional cuyo valor es 0.

Aquí está el código para hacerlo:

byte[] byteArray; 
// ... 
var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray());