简体   繁体   English

十六进制字符串到字节数组的转换 java

[英]Hex String to Byte array conversion java

I know this question is asked a lot of times but please hear me out.我知道这个问题被问了很多次,但请听我说完。

Previously I have tried following methods to convert hex string to byte array.以前我尝试过以下方法将十六进制字符串转换为字节数组。

say my keyA = "D14E2C5A5B5F", I use byte[] of this key to authenticate a mifare card说我的keyA =“D14E2C5A5B5F”,我使用这个密钥的byte []来验证mifare卡

First Approach:第一种方法:

byte[] ka = new BigInteger(keyA, 16).toByteArray();

(With this approach using ka as key authenticates few cards and fails in few cards) (通过这种使用ka作为密钥的方法可以验证几张卡并且在几张卡中失败)

Second Approach:第二种方法:

byte[] ka = hexStringToByteArray(keyA);
public 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;
}

(With this approach using ka as key authenticates few cards, but success rate is more than first approach and fails in few cards). (通过这种使用ka作为密钥的方法可以验证少数卡片,但成功率高于第一种方法并且在少数卡片中失败)。

Am I missing anything?我错过了什么吗? Is there any better way to convert hex string to byte array in java?在 java 中有没有更好的方法将十六进制字符串转换为字节数组?

Thanks in advance.提前致谢。

The difference is in the leading 0 values created by BigInteger .区别在于BigInteger创建的前导0值。

public void test() {
    test("D14E2C5A5B5F");
    test("00D14E2C5A5B5F");
    test("614E2C5A5B5F");
    test("00614E2C5A5B5F");
}

private void test(String s) {
    byte[] ka = new BigInteger(s, 16).toByteArray();
    byte[] kb = hexStringToByteArray(s);
    if (!Arrays.equals(ka, kb)) {
        System.out.println(s + ":" + Arrays.toString(ka) + " != " + Arrays.toString(kb));
    }
}

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

prints印刷

D14E2C5A5B5F:[0, -47, 78, 44, 90, 91, 95] != [-47, 78, 44, 90, 91, 95] D14E2C5A5B5F:[0, -47, 78, 44, 90, 91, 95] != [-47, 78, 44, 90, 91, 95]

00614E2C5A5B5F:[97, 78, 44, 90, 91, 95] != [0, 97, 78, 44, 90, 91, 95] 00614E2C5A5B5F:[97, 78, 44, 90, 91, 95] != [0, 97, 78, 44, 90, 91, 95]

See the extra leading 0 s.查看额外的前导0秒。

Also, your hexStringToByteArray is assuming an even number of hex digits - this may be an issue.此外,您的hexStringToByteArray假设十六进制数字为偶数 - 这可能是一个问题。

Something like this should be correct.这样的事情应该是正确的。 It ensure the byte[] is always the right length whatever the length of the string.它确保byte[]始终是正确的长度,无论字符串的长度如何。 You may wish to add an exception for when the string is too long.当字符串太长时,您可能希望添加一个例外。

public byte[] asKey(String hex, int bytes) {
    // Make sure the byte [] is always the correct length.
    byte[] key = new byte[bytes];
    // Using i as the distance from the END of the string.
    for (int i = 0; i < hex.length() && (i / 2) < bytes; i++) {
        // Pull out the hex value of the character.
        int nybble = Character.digit(hex.charAt(hex.length() - 1 - i), 16);
        if ((i & 1) != 0) {
            // When i is odd we shift left 4.
            nybble = nybble << 4;
        }
        // Use OR to avoid sign issues.
        key[bytes - 1 - (i / 2)] |= (byte) nybble;
    }
    return key;
}

Try this.尝试这个。

public static byte[] hexStringToByteArray(String s) {
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++) {
      int index = i * 2;
      int v = Integer.parseInt(s.substring(index, index + 2), 16);
      b[i] = (byte) v;
    }
    return b;
  }

This is what works for me:这对我有用:

public static byte[] hexToByteData(String hex)
{
    byte[] convertedByteArray = new byte[hex.length()/2];
    int count  = 0;

    for( int i = 0; i < hex.length() -1; i += 2 )
    {
        String output;
        output = hex.substring(i, (i + 2));
        int decimal = (int)(Integer.parseInt(output, 16));
        convertedByteArray[count] =  (byte)(decimal & 0xFF);
        count ++;
    }
    return convertedByteArray;
}

Here is my code that showed the best performance...这是我的代码,显示出最佳性能......

    public static byte[] hex2bytes(String str) {
        if( str == null || str.length() == 0 )
            return null;

        byte[] hex = new byte[str.length() / 2];
        int tmp1, tmp2;

        for(int i=0; i < hex.length; i++) {
            tmp1 = str.charAt(i*2);
            tmp2 = str.charAt(i*2+1);
            hex[i] = (byte)( (tmp1 < 0x41 ? (tmp1 & 0x0F) << 4 : ((tmp1 & 0x0F) + 9) << 4)
                    | (tmp2 < 0x41 ? tmp2 & 0x0F : (tmp2 & 0x0F) + 9) );
        }

        return hex;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM