关于java:在android中将byte []转换为Hex字符串

Converting byte[] to Hex string in android

本问题已经有最佳答案,请猛点这里访问。

我正在尝试将字节[]转换为十六进制字符串,在Android中将相同的十六进制字符串转换为字节[],数据不匹配。

前任:

接收字节[]数据:[B@B39C86A

转换的十六进制字符串:8be897cc3c4d9e5d6a6bbd106d8e8d487691b56

当我解码十六进制字符串时,我得到了[b@ea6d15b,但它应该是[b@b39c86a

我正在使用下面的代码进行转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public String byte2hex(byte[] a) {
        /*StringBuilder sb = new StringBuilder(a.length * 2);

        for (byte b : a)
            sb.append(String.format("%02x", b & 0xff));
        return sb.toString();*/


        String hexString ="";

        for(int i = 0; i < a.length; i++){
            String thisByte ="".format("%x", a[i]);
            hexString += thisByte;
        }

        return hexString;

    }
    public static byte[] hexStringToByteArray(String s) {
       /* int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;*/


        byte[] bytes = new byte[s.length() / 2];

        for(int i = 0; i < s.length(); i += 2){
            String sub = s.substring(i, i + 2);
            Integer intVal = Integer.parseInt(sub, 16);
            bytes[i / 2] = intVal.byteValue();
            String hex ="".format("0x%x", bytes[i / 2]);
        }

        return bytes;
    }


我想你是通过打印对象得到[B@B39C86A。这些数字是由toString()方法生成的,不会告诉您关于数组内容的任何信息。

例如,如果运行此代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    byte[] arr = new byte[]{1,2,3,4};
    byte[] arr2 = new byte[4];
    for(int i=0; i < 4; i++)
        arr2[i] = arr[i];


    System.out.println("Array 1:" + arr);
    System.out.println("Array 2:" + arr2);
    System.out.println("arr.equals:" + arr.equals(arr2));
    System.out.println("Arrays.equals: " + Arrays.equals(arr,arr2));
    System.out.printf("Contents of array 1: %s
"
, Arrays.toString(arr));
    System.out.printf("Contents of array 2: %s
"
, Arrays.toString(arr2));

例如,输出为:

1
2
3
4
5
6
Array 1: [B@74a14482
Array 2: [B@1540e19d
arr.equals: false
Arrays.equals:  true
Contents of array 1: [1, 2, 3, 4]
Contents of array 2: [1, 2, 3, 4]

ToString方法的格式为classname@hashcode。没有为特定类实现哈希代码(字节数组也是如此)。

如果你看JavaDoc,它会说:

1
2
3
4
5
6
7
8
9
10
/**
....
 * As much as is reasonably practical, the hashCode method defined by
 * class {@code Object} does return distinct integers for distinct
 * objects. (This is typically implemented by converting the internal
 * address of the object into an integer, but this implementation
 * technique is not required by the
 * Java&trade; programming language.)
....
*/

因此,在本质上,这些数字不能用来确定内容是否相等。例如,可以使用:array.equals()。

本质上,内容是相同的(数组是相同的)。但是,您犯了检查特定于对象实例的错误。

但是,您的代码仍然有一个错误:

1
String thisByte ="".format("%x", a[i]);

而不是使用%x,而是使用%02x,这样可以确保输出至少为2位(并且当其字节值也是最大长度2时)。(另外,string.format(..)比".format(..)"更容易接受)


我使用下面的方法,它们会起作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * Converts byte array to hex string
 *
 * @param bytes The data
 * @return String represents the data in HEX string
 */

public static String byteArrayToHexString(final byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for(byte b : bytes){
        sb.append(String.format("%02x", b&0xff));
    }
    return sb.toString();
}

/**
 * Converts hex string to byte array
 *
 * @param s The data in string
 * @return byte represents the string in bytes
 */

public static byte[] hexStringToByteArray(final String s) {
    if (s == null) {
        return (new byte[]{});
    }

    if (s.length() % 2 != 0 || s.length() == 0) {
        return (new byte[]{});
    }

    byte[] data = new byte[s.length() / 2];
    for (int i = 0; i < s.length(); i += 2) {
        try {
            data[i / 2] = (Integer.decode("0x" + s.charAt(i) + s.charAt(i + 1))).byteValue();
        } catch (NumberFormatException e) {
            return (new byte[]{});
        }
    }
    return data;
}


请看我的密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
final protected static char[] hexArray ="0123456789ABCDEF".toCharArray();

public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}


public static byte[] hexStringToByteArray(String s) {
    try {

        int len = s.length();
        if(len>1) {
            byte[] data = new byte[len / 2];
            for (int i = 0 ; i < len ; i += 2) {
                data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                        + Character.digit(s.charAt(i + 1), 16));
            }
            return data;
        }
        else

        {
            return  null;
        }
    }catch (Exception e)
    {
        throw e;
    }
}