-1

Possible Duplicate:
Convert a string representation of a hex dump to a byte array using Java?

I want to convert String "1B4322C2" in to bytes but problem is if I use getBytes() it will convert it into bytes with double the length of string and I want to convert them into half the string length.

e.g. output of above string should be {0x1B , 0x43, 0x22, 0xC2}

Thank You

jww
  • 97,681
  • 90
  • 411
  • 885
Sandip Jadhav
  • 7,377
  • 8
  • 44
  • 76

6 Answers6

5

(I've now voted to close as a duplicate, which I should have done first... but it makes sense to leave this answer here until the question is deleted...)

Right, so what you actually want to do is parse a hex string.

You should look at Apache Commons Codec, which has a Hex class for precisely that purpose. Personally I'm not wild about the API, but this should work:

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

Or:

byte[] data = Hex.decodeHex(text.toCharArray());

(Personally I wish you could just use byte[] data = Hex.decodeHexString(text); but there we go... you could always write your own wrapper method if you want.)

If you don't want to use a 3rd party library, there are plenty of implementations elsewhere on Stack Overflow, e.g. this one.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • you may use `Byte.parseByte(str,16);` – Subhrajyoti Majumder Dec 05 '12 at 07:30
  • @Quoi: Well, that requires creating a new `String` object for each byte. I don't think we need to be quite that inefficient. – Jon Skeet Dec 05 '12 at 07:31
  • Why are we sending a Java beginning off to Apache Commons land? This can be handled with the basic number primitive wrapper classes. edit: Oh wait, this guy isn't a java beginner. Could have fooled me. Carry on. – Chris Bode Dec 05 '12 at 07:33
  • 1
    @JonSkeet - some thing like `if ((str.length() % 2) == 1) str = "0" + str; for(int i=0;i – Subhrajyoti Majumder Dec 05 '12 at 07:42
  • @Quoi: I wasn't saying it wouldn't work. I was saying it was needlessly inefficient. – Jon Skeet Dec 05 '12 at 07:44
  • 1
    @Chris: Even for a beginner, many things certainly *can* be achieved without third party libraries, but shouldn't be - why reinvent a wheel which has been efficiently invented elsewhere? I think that looking for existing libraries which solve a problem is something we should *actively* teach beginners. (Guava and Joda Time being the libraries I'd direct people to first :) – Jon Skeet Dec 05 '12 at 07:45
2

To encode "1B4322C2" as bytes you can use

byte[] bytes = new BigInteger("FB4322C2", 16).toByteArray();
if (bytes.length > 1 && bytes[0] == 0)
    bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
System.out.println(Arrays.toString(bytes));

prints

[-5, 67, 34, -62]
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

You can use String Tokenizer or String Builder and separte the strings and then covert it from hexa to string...

this link might be helpful for you..
Convert Hex to ASCII

hope this helps..

Lucky
  • 16,787
  • 19
  • 117
  • 151
1

If you don't want to use an external lib, this should do the trick with some adjustments (add 0x and { })

public static String byteArrayToHexadecimal(byte[] raw) {
    final BigInteger bi = new BigInteger(1, raw);
    final String result = bi.toString(16);
    if (result.length() % 2 != 0) {
        return "0" + result;
    }
    return result;
}

Sorry, other way around (nothing optimized as it was for me not a bottleneck at all):

public static byte[] hexadecimalToByteArray(String hex) {
    if (hex.length() % 2 != 0) {
        hex = "0" + hex;
    }
    final byte[] result = new byte[hex.length() / 2];
    for (int i = 0; i < hex.length(); i += 2) {
        String sub = "0x" + hex.substring(i, i + 2);
        result[i / 2] = (byte) ((int) Integer.decode(sub));
    }
    return result;
}

I would however advise to go for Apache Commons Codec as suggested by J. Skeet

Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • OP wants it the other way around but I admit the use of `BigInteger` is ingenious. – John Dvorak Dec 05 '12 at 07:24
  • Note that this goes in the opposite direction to what the OP wanted, and personally I *wouldn't* use `BigInteger` for hex conversion - it's not what it's designed for, and it will generally cut leading 0s. (For example, with your code above, { 0, 0, 0 } should give "000000" but I believe it will just give "00".) – Jon Skeet Dec 05 '12 at 07:25
0

getBytes converts each character to its character code in byte form; it doesn't parse out byte values from the string itself. For that, you'll probably need to write your own parsing function.

Kenogu Labz
  • 1,094
  • 1
  • 9
  • 20
0

You don't want the String.getBytes() method. That's going to convert the characters of the string into their byte representations.

To do what you're looking to do, you're going to need to manually split the string into individual strings, one for each pair. Then, you're going to want to parse them.

Unfortunately, Java doesn't have unsigned bytes, and 0xC2 is going to overflow. You'll probably going to want to treat the values as shorts, or integers if memory isn't an issue.

So, you can use the Integer class to parse strings into numbers. Since your strings are hexidecimal, you'll have to use the parse method that lets you supply the radix.

String test = "1B4322C2";

for (int bnum = 0; bnum < test.length() / 2; bnum++) {
    String bstring = test.substring(bnum * 2, bnum * 2 + 2);
    int bval = Integer.parseInt(bstring, 16);
    System.out.println(bstring + " -> " + bval);
}

This will output:

1B -> 27
43 -> 67
22 -> 34
C2 -> 194

If you need them in an array, you can instantiate an array that is half the width of the string and them put each value under its bnum index.

Chris Bode
  • 1,265
  • 7
  • 16
  • `Java doesn't have unsigned bytes, and 0xC2 is going to overflow.` Absolute nonsense. There is no overflow. Try it `byte b = 0xC2;` it works. – Ingo Jan 25 '13 at 13:52