0

我正在分配一个故意大于 BitConverter.GetBytes 结果的数组。我的目标是将最后一个字节留空,这样我就可以防止这个数字被视为两者的恭维并拥有 tempPosBytes2[

当我运行 BitConverter.GetBytes 时,我的数组tempPosBytes2似乎缩小了。

uint positiveNumber = 4293967296;
byte[] tempPosBytes2 = new byte[tempPosBytes.Length + 1]; // four bytes plus one
tempPosBytes2 = BitConverter.GetBytes(positiveNumber);  // tempPositiveBytes2 is now 4 bytes!!

问题

幕后发生了什么,如何在不复制数组的情况下留下尾随字节?

我需要它与 BigInteger(byte[]) 一起使用,如下所示:

BigInteger positiveBigIntBAD2 = new BigInteger(tempPosBytes2); // Invalid
4

4 回答 4

3

您的数组没有被缩小,您在内部分配了一个全新的数组BitConverter.GetBytes

当然,您可以将该输出数据复制到具有您选择的大小的数组中。

或者,只需制作您自己的BitConverter. 这真的很简单:

byte[] tempPosBytes2 = new byte[] { (byte)(positiveNumber), 
                                    (byte)(positiveNumber >> 8), 
                                    (byte)(positiveNumber >> 16), 
                                    (byte)(positiveNumber >> 24), 
                                    0 };

我建议您比较使用这两种技术的性能。

顺便说一句,您可以只使用BigInteger带有uint.

于 2012-12-18T16:33:33.727 回答
2

它没有缩小任何东西。GetBytes总是分配一个新数组,并且您的分配会覆盖对现有字节数组的引用。

如果您需要最高字节始终为零,以便 BigInteger 不会将其解释为负数,那么您可以在将大小增加 1之后执行Array.ResizeGetBytes ,新字节的值将为零,例如你要。

BigInteger 构造函数页面上有一个示例讨论了这件事,它提供了一个示例,该示例将导致仅在必要时调整数组的大小。你可以给自己写一个辅助方法CreateUnsignedBigInteger(byte[])来做这件事。

public BigInteger CreateUnsignedBigInteger(byte[] bytes)
{
    if ((bytes[bytes.Length - 1] & 0x80) > 0) 
    {
        byte[] old = bytes;
        bytes = new byte[old.Length + 1];
        Array.Copy(old, bytes, old.Length);
    }

    return new BigInteger(bytes);
}
于 2012-12-18T16:36:13.233 回答
1

BitConverter.GetBytes没有使用您的数组,它不能因为您从未将其传入。

相反,您正在创建一个数组,然后立即销毁它。

如果您需要将结果保存GetBytes在数组中,您可以查看是否有重载或其他方法接收数组以写入,或自己复制内容。

于 2012-12-18T16:33:46.820 回答
1

具有讽刺意味的是,如果您想要一个byte[]可以传递给BigInteger构造函数以提供与您等效的值uint,您可以这样做

byte[] tempPosBytes = new BigInteger(positiveNumber).ToByteArray();
于 2012-12-18T16:38:51.817 回答