byte[] 到无符号 BigInteger?

发布于 2024-11-01 14:29:16 字数 707 浏览 4 评论 0原文

动机: 我想将哈希值(MD5/SHA1 等)转换为十进制整数,以便在 Code128C 中制作条形码。 为简单起见,我希望所有结果(大)数字都是正数。

我能够在 C# 中将 byte[] 转换为 BigInteger...
到目前为止我所拥有的示例:

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

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

但是(这里生锈的CS)我是否正确,字节数组总是可以用两种方式解释:

  • (A):作为有符号数
  • (B):作为无符号数

是吗?是否可以在 C# 中从 byte[] 生成 UNSIGNED BigInteger?

我应该简单地在 byte[] 前面添加 0x00(零字节)吗?

编辑: 感谢 AakashM、Jon 和 Adam Robinson,附加一个零字节实现了我所需要的。

编辑2: 我应该做的主要事情是阅读 BigInteger(byte[]) 构造函数的详细文档,然后我会看到有关如何通过附加零字节来限制正数的部分。

Motivation:
I would like to convert hashes (MD5/SHA1 etc) into decimal integers for the purpose of making barcodes in Code128C.
For simplicity, I prefer all the resulting (large) numbers to be positive.

I am able to convert byte[] to BigInteger in C#...
Sample from what I have so far:

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

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

But (rusty CS here) am I correct that a byte array can always be interpreted in two ways:

  • (A): as a signed number
  • (B): as an unsigned number

Is it possible to make an UNSIGNED BigInteger from a byte[] in C#?

Should I simply prepend a 0x00 (zero byte) to the front of the byte[]?

EDIT:
Thank you to AakashM, Jon and Adam Robinson, appending a zero byte achieved what I needed.

EDIT2:
The main thing I should have done was to read the detailed doc of the BigInteger(byte[]) constructor, then I would have seen the sections about how to restrict to positive numbers by appending the zero byte.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请远离我 2024-11-08 14:29:16

BigInteger 的备注< /code> 构造函数 声明您可以确保从 a 创建的任何 BigInteger如果在调用构造函数之前将 00 字节附加到数组末尾,则 byte[] 是无符号的。

注意:BigInteger 构造函数要求数组采用小端顺序。如果您希望生成的 BigInteger 具有特定值,请记住这一点。

The remarks for the BigInteger constructor state that you can make sure any BigInteger created from a byte[] is unsigned if you append a 00 byte to the end of the array before calling the constructor.

Note: the BigInteger constructor expects the array to be in little-endian order. Keep that in mind if you expect the resulting BigInteger to have a particular value.

波浪屿的海角声 2024-11-08 14:29:16

从 .NET Core 2.1 开始,BigInteger 具有 构造函数

public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);

Since .NET Core 2.1, BigInteger has a constructor with an optional parameter isUnsigned:

public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);
芸娘子的小脾气 2024-11-08 14:29:16

检查相关 BigInteger 构造函数的文档 ,我们看到:

值中的各个字节
数组应该是小端
顺序,从最低位字节到
最高位字节

[...]

构造函数期望为正值
要使用的字节数组中的值
符号和数值表示,以及
使用二进制的负值
补充表示。 在其他方面
的话,如果的最高位
设置值中的最高位字节,
结果 BigInteger 值为
负面
。取决于来源
字节数组,这可能会导致
正值会被误解为
负值。

[...]

为了防止
积极的价值观
被误解为负面价值观,你
可以在末尾添加一个零字节值
数组的。

Examining the documentation for the relevant BigInteger constructor, we see:

The individual bytes in the value
array should be in little-endian
order, from lowest-order byte to
highest-order byte

[...]

The constructor expects positive
values in the byte array to use
sign-and-magnitude representation, and
negative values to use two's
complement representation. In other
words, if the highest-order bit of the
highest-order byte in value is set,
the resulting BigInteger value is
negative
. Depending on the source of
the byte array, this may cause a
positive value to be misinterpreted as
a negative value.

[...]

To prevent
positive values from being
misinterpreted as negative values, you
can add a zero-byte value to the end
of the array.

萌吟 2024-11-08 14:29:16

正如其他答案所指出的,您应该在数组末尾附加一个 00 字节,以确保生成的 BigInteger 为正。

根据 BigInteger 结构 (System.Numerics) MSDN 文档

为了防止 BigInteger(Byte[]) 构造函数将负值的二进制补码表示与正值的符号和大小表示混淆,正值中字节数组中最后一个字节的最高有效位通常设置应包含一个值为 0 的附加字节。

下面是执行此操作的代码:

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

As other answers have pointed out, you should append a 00 byte to the end of the array to ensure the resulting BigInteger is positive.

According to the the BigInteger Structure (System.Numerics) MSDN Documentation

To prevent the BigInteger(Byte[]) constructor from confusing the two's complement representation of a negative value with the sign and magnitude representation of a positive value, positive values in which the most significant bit of the last byte in the byte array would ordinarily be set should include an additional byte whose value is 0.

Here's code to do it:

byte[] byteArray;
// ...
var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray());
世界等同你 2024-11-08 14:29:16

但是(这里生锈的CS)我是否正确,字节数组总是可以用两种方式解释:A:作为有符号数B:作为无符号数

更正确的是所有数字(由于存储在计算机中)基本上是一系列字节,这就是字节数组。字节数组始终可以解释为特定数字类型的有符号或无符号版本是不正确的,因为并非所有数字类型都有有符号和无符号版本。浮点类型通常只有有符号版本(没有 udoubleufloat),并且在本例中,没有无符号版本的 BigInteger >。

因此,换句话说,不,这是不可能的,但由于 BigInteger 可以表示任意大的整数值,因此您不会因为它的签名而丢失任何范围。

至于第二个问题,您需要将 0x00 附加到数组的末尾 end,如 BigInteger 构造函数 以小端字节顺序解析值。

But (rusty CS here) am I correct that a byte array can always be interpreted in two ways: A: as a signed number B: as an unsigned number

What's more correct is that all numbers (by virtue of being stored in the computer) are basically a series of bytes, which is what a byte array is. It's not true to say that a byte array can always be interpreted as a signed or unsigned version of a particular numeric type, as not all numeric types have signed and unsigned versions. Floating point types generally only have signed versions (there's no udouble or ufloat), and, in this particular instance, there is no unsigned version of BigInteger.

So, in other words, no, it's not possible, but since BigInteger can represent an arbitrarily large integer value, you're not losing any range by virtue of its being signed.

As to your second question, you would need to append 0x00 to end end of the array, as the BigInteger constructor parses the values in little-endian byte order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文