c# bytearray numeric biginteger

c# - byte[] a BigInteger sin firmar?



bytearray numeric (5)

Motivación: 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 (grandes) resultantes sean positivos.

Puedo convertir el byte [] a BigInteger en C # ...
Muestra de lo que tengo hasta ahora:

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

Pero (aquí está el CS oxidado) estoy en lo cierto al corregir una matriz de bytes de dos maneras: A: como un número firmado B: como un número sin signo

¿Es posible hacer un BigInteger UNSIGNED desde un byte [] en C #?

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

EDIT: Gracias a AakashM, Jon y Adam Robinson, al agregar un byte cero logró lo que necesitaba. /

EDIT2: Lo principal que debería haber hecho fue leer el documento detallado del constructor BigInteger (byte []), luego habría visto las secciones sobre cómo restringir a números positivos agregando el byte cero.


Pero (aquí está el CS oxidado) estoy en lo cierto al corregir una matriz de bytes de dos maneras: A: como un número firmado B: como un número sin signo

Lo que es más correcto 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 cierto que una matriz de bytes siempre se pueda interpretar como una versión firmada o sin firmar 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 ni ufloat ) y, en este caso particular, no hay una versión sin firmar de BigInteger .

Entonces, en otras palabras, no, no es posible, pero como BigInteger puede representar un valor entero arbitrariamente grande, no está perdiendo ningún rango debido a su firma.

En cuanto a la segunda pregunta, deberá agregar 0x00 al final de la matriz, ya que el constructor BigInteger analiza los valores en orden de bytes little-endian.


Al examinar la documentación del constructor relevante de BigInteger , vemos:

Los bytes individuales en la matriz de valores deben estar en orden little-endian , desde el byte de orden más bajo hasta el byte de orden más alto

[...]

El constructor espera que los valores positivos en la matriz de bytes usen la representación de signo y magnitud, y los valores negativos para usar la representación de complemento de dos. En otras palabras, si se establece el bit de orden más alto del byte de orden más alto en valor, el valor BigInteger resultante es negativo . Dependiendo de la fuente de la matriz de bytes, esto puede causar que un valor positivo sea malinterpretado como un valor negativo.

[...]

Para evitar que los valores positivos se malinterpreten como valores negativos, puede agregar un valor de cero bytes al final de la matriz.


Como han señalado otras respuestas, debe agregar un 00 bytes al final de la matriz para garantizar que el BigInteger resultante sea positivo.

De acuerdo con la estructura de BigInteger (System.Numerics) MSDN Documentation

Para evitar que el constructor BigInteger (Byte []) confunda la representación complementaria de dos de un valor negativo con la representación de signo y magnitud de un valor positivo, los valores positivos en los que el bit más significativo del último byte en la matriz de bytes normalmente sería conjunto debe 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());


Las observaciones para el estado del constructor BigInteger indican que puede asegurarse de que cualquier BigInteger creado a partir de un byte[] no esté firmado si agrega un 00 bytes al 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 BigInteger resultante tenga un valor particular.


Una alternativa es crear un BigInteger usando su matriz de bytes, luego usar Abs (equivalente a Math.Abs ) para convertirlo en un valor absoluto:

var bi = new BigInteger(result); var biPositive = BigInteger.Abs(bi1);

Técnicamente, solo necesita usar Abs si bi es negativo (por ejemplo, si bi.Sign == -1 )