Java 字节数组的比较

Java 字节数组的比较,java,bytearray,Java,Bytearray,我尝试比较2字节数组 字节数组1是包含sha1哈希的最后3个字节的数组: private static byte[] sha1SsidGetBytes(byte[] sha1) { return new byte[] {sha1[17], sha1[18], sha1[19]}; } 字节数组2是我用来自十六进制字符串的3个字节填充的数组: private static byte[] ssidGetBytes(String ssid) { BigIntege

我尝试比较2字节数组

字节数组1是包含sha1哈希的最后3个字节的数组:

  private static byte[] sha1SsidGetBytes(byte[] sha1)
  {
    return new byte[] {sha1[17], sha1[18], sha1[19]};
  }
字节数组2是我用来自十六进制字符串的3个字节填充的数组:

  private static byte[] ssidGetBytes(String ssid)
  {
    BigInteger ssidBigInt = new BigInteger(ssid, 16);

    return ssidBigInt.toByteArray();
  }
这种比较怎么可能:

  if (Arrays.equals(ssidBytes, sha1SsidGetBytes(snSha1)))
  {
  }
大多数情况下有效,但有时无效。字节顺序


e、 g.对于“6451E6”(十六进制字符串)它工作正常,对于“ABED74”它不

通过BigInteger解析十六进制字符串的方法基本上是有缺陷的。例如,
new biginger(“ABED74”).toByteArray()
返回一个4字节的数组,而不是3字节的数组。虽然你可以解决这个问题,但你根本不想做任何涉及大整数值的事情。。。你只是想解析十六进制

我建议您使用库进行解析:

byte[] array = (byte[]) new Hex().decode(text);

(ApacheCodec的API还有待改进,但它确实有效。)

通过BigInteger解析十六进制字符串的方法基本上是有缺陷的。例如,
new biginger(“ABED74”).toByteArray()
返回一个4字节的数组,而不是3字节的数组。虽然你可以解决这个问题,但你根本不想做任何涉及大整数值的事情。。。你只是想解析十六进制

我建议您使用库进行解析:

byte[] array = (byte[]) new Hex().decode(text);

(Apache编解码器的API还有一些地方需要改进,但它确实可以工作。)

如果您尝试以下方法,问题是非常明显的:

BigInteger b1 = new BigInteger("6451E6", 16);
BigInteger b2 = new BigInteger("ABED74", 16);

System.out.println(b1.toByteArray().length);
System.out.println(b2.toByteArray().length);
具体地说,ABED74创建了一个字节数组长度为4字节的BigInteger,因此它当然不会等于任何三字节数组

简单的解决方法是将
ssidGetBytes
中的return语句从

return ssidBigInt.toByteArray();


如果您尝试以下方法,问题很明显:

BigInteger b1 = new BigInteger("6451E6", 16);
BigInteger b2 = new BigInteger("ABED74", 16);

System.out.println(b1.toByteArray().length);
System.out.println(b2.toByteArray().length);
具体地说,ABED74创建了一个字节数组长度为4字节的BigInteger,因此它当然不会等于任何三字节数组

简单的解决方法是将
ssidGetBytes
中的return语句从

return ssidBigInt.toByteArray();

来自javadoc的(我的重点):

返回包含 两个补码表示法 这个大整数。字节数组将 按大端字节顺序:最大 有效字节位于第0位 元素。数组将包含 所需的最小字节数 表示这个大整数,包括 至少一个符号位,即 (ceil((this.bitLength()+1)/8))。 (此表示是兼容的 使用(字节[])构造函数

您正在使用的ByteInteger(String,radix)构造函数中正在进行大量计算,这并不能保证构造的BigInteger将生成与字符串的getBytes()编码结果相当的字节数组(通过其toByteArray()方法)

toByteArray()的输出主要用作BigInteger的(byte[])构造函数的输入。除此之外,它不保证其他用途

如下所示:toByteArray()的输出是BigInteger对象的字节表示,以及其中的所有内容,包括内部属性,如幅值。这些属性不存在于输入字符串中,而是在构造BIINTEGER对象期间计算的

这将与输入字符串的字节表示形式不兼容,该字符串只携带用于创建BigInteger的初始值

返回包含 两个补码表示法 这个大整数。字节数组将 按大端字节顺序:最大 有效字节位于第0位 元素。数组将包含 所需的最小字节数 表示这个大整数,包括 至少一个符号位,即 (ceil((this.bitLength()+1)/8))。 (此表示是兼容的 使用(字节[])构造函数

您正在使用的ByteInteger(String,radix)构造函数中正在进行大量计算,这并不能保证构造的BigInteger将生成与字符串的getBytes()编码结果相当的字节数组(通过其toByteArray()方法)

toByteArray()的输出主要用作BigInteger的(byte[])构造函数的输入。除此之外,它不保证其他用途

如下所示:toByteArray()的输出是BigInteger对象的字节表示,以及其中的所有内容,包括内部属性,如幅值。这些属性不存在于输入字符串中,而是在构造BIINTEGER对象期间计算的


这与输入字符串的字节表示不兼容,该字符串只携带用于创建BigInteger的初始值。

您是否查看了调试器中的字节数组?您是否可能遇到有符号字节的问题?如何查看它们是否有符号?是否查看了调试器中的字节数组?你有可能遇到有符号字节的问题吗?我怎么看它们是否有符号?那么我想这就是问题所在了?有没有其他方法可以将十六进制字符串(长度6)解析为3个字节的数组?@tersmitten:是的,正如我所说:使用专门设计的方法将十六进制字符串解析为字节,而不是为了完成更大的任务而碰巧使用的方法。当然,您不必使用第三方库:如果您愿意,编写一个解析十六进制的方法很容易。@tersmitten:显然不是:)那么我想这就是问题所在了吧?有没有其他方法可以将十六进制字符串(长度6)解析为3个字节的数组?@tersmitten:是的,正如我所说:使用专门设计的方法将十六进制字符串解析为字节,而不是为了完成更大的任务而碰巧使用的方法。当然,您不必使用第三方库