Java BigInteger在.NET中的字节数组等效物

4

我正在与一个使用Java的合作伙伴进行集成,他使用Java的BigInteger生成一个字节数组作为简单加密算法的密钥。我尝试找到等效的.NET代码,但没有什么好的结果。

他们使用的Java代码是:

String keyString = "48B734DA47388C656913C9BF5146E186";
byte key[] = new BigInteger(keyString, 16).toByteArray();

这将产生以下byte数组:

[72, -73, 52, -38, 71, 56, -116, 101, 105, 19, -55, -65, 81, 70, -31, -122]

这一点很令人不安,因为 .NET 中的 byte 范围是从 0 到 255,所以负值超出了范围。

我想到的最接近的 .NET 代码如下:

string keyString = "48B734DA47388C656913C9BF5146E186";
byte[] key = BigInteger.Parse(keyString, NumberStyles.HexNumber).ToByteArray();

这将产生以下byte数组:

[134, 225, 70, 81, 191, 201, 19, 105, 101, 140, 56, 71, 218, 52, 183, 72]

目前,我认为一个.NET的等效方案似乎不可能实现 - 特别是因为负的byte值。

期待大家的想法。


尝试在 ToByteArray() 后面添加 .Cast<sbyte>().ToArray();。应该可以解决问题。 - It'sNotALie.
这不是一个字节数组。无论如何,它是一个System.SByte[] - Federico Berasategui
@HighCore 第一个字节数组是Java的byte数组,它们是有符号值。第二个是.Net的byte数组,它们不是有符号值。 - NominSim
rjygraham,看看这段代码会输出什么:var s = String.Join(",", key.Reverse().Select(x => (sbyte)x).ToArray()); - I4V
OP,你有没有不使用 byte 而使用 sbyte 的理由? - Mike Precup
3个回答

7
使用评论中提供的LINQ方法可以轻松解决它。
  sbyte[] key = BigInteger.Parse(keyString, NumberStyles.HexNumber).ToByteArray().Reverse().Select(x => (sbyte)x).ToArray();

这将得到您想要的数组。.NET默认使用无符号字节,而Java默认使用有符号字节。它们具有相同的位表示形式,因此根据您对其进行的操作,实际上可能并不重要使用哪一个,但是如果您想在.NET中获得真正等效的输出,则需要使用sbytes而不是bytes,因为在两种语言之间简单地使用byte意味着不同的事情。


谢谢,我完全忘记了sbyte...因为我太专注于Java语法,看不到整体情况。 - rjygraham

3

当我比较Java的两个结果:

[72,-73,52,-38,71,56,-116,101,105,19,-55,-65,81,70,-31,-122]

.Net的结果为:

[134,225,70,81,191,201,19,105,101,140,56,71,218,52,183,72]

我可以告诉你:

  1. 它们看起来很相似——.Net只是顺序相反(这是Java内部表示为Big Endian的结果)。
  2. 在.Net的结果中,没有负数。
  3. 将结果按相反的顺序进行比较,可以发现-73在.Net中为183

因此,我认为我们可以说这些结果是相同的,但需要检查Endianness是否相同,并且符号是否保持不变。

您能展示打印这些结果的代码吗?


字节序是指反转顺序。 - Mzf

2

看起来 .Net 的结果与 Java 的结果相反,但它们是相同的值。然而,.Net 字节是无符号的,而 Java 字节是有符号的(包含负数,正如你注意到的那样)。你可以将获得的结果转换为有符号字节 (sbyte),并且也可以反转顺序:

sbyte[] finalResult = (sbyte[])(Array)key.Reverse().ToArray();

结果为: [72, -73, 52, -38, 71, 56, -116, 101, 105, 19, -55, -65, 81, 70, -31, -122]

需要注意的是,位表示将相同,因此如果您将其用作某些加密的密钥并在位级别上操作它,则可能不需要获取实际的有符号字节(sbyte),但如果您这样做,可能会更容易可视化从Java到.Net的转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接