字节数组的比较

时间:2010-12-08 19:23:18

标签: 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)
  {
    BigInteger ssidBigInt = new BigInteger(ssid, 16);

    return ssidBigInt.toByteArray();
  }

这种比较怎么可能:

  if (Arrays.equals(ssidBytes, sha1SsidGetBytes(snSha1)))
  {
  }

大部分时间都有效,但有时却没有。字节顺序?

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

3 个答案:

答案 0 :(得分:3)

如果你试试这个问题很明显:

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创建一个BigInteger,其字节数组长度为4个字节 - 所以当然它不会等于任何三个字节数组。

直接的解决方法是更改​​ssidGetBytes中的返回语句

return ssidBigInt.toByteArray();

byte[] ba = ssidBigInt.toByteArray();
return new byte[] { ba[ba.length - 3], ba[ba.length - 2], ba[ba.length - 1] };

答案 1 :(得分:1)

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

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

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

(Apache Codec的API留下了一些需要的东西,但确实有效。)

答案 2 :(得分:1)

来自javadoc(强调我的):

http://download.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html#toByteArray%28%29

  

返回包含的字节数组   二进制补码表示   这个BigInteger。字节数组将   处于大端字节顺序:最多   重要的字节在第0个   元件。该数组将包含   所需的最小字节数   代表这个BigInteger,包括   至少有一个符号位,即   (ceil((this.bitLength()+ 1)/ 8))。   (这种表示是兼容的   使用(byte [])构造函数。)

你正在使用的ByteInteger(String,radix)构造函数中有很多计算,这并不能保证构造的BigInteger会产生一个字节数组(通过它的toByteArray()方法)与结果相当String的getBytes()编码。

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

看起来像这样:toByteArray()的输出是BigInteger对象的字节表示,其中的所有内容包括内部属性,如幅度。这些属性在输入String中不存在,但是在构造BitInteger对象期间计算。

这与输入String 的字节表示不兼容,后者仅包含用于创建BigInteger的初始数值。