randomuser1
randomuser1

Reputation: 2803

how can I convert my String (that represents hex values) to bytes?

I have a String in Java that contains 32 characters:

String tempHash = "123456789ABCDEF123456789ABCDEF12"; 

Each character in the String above represents a hex value. I need to convert it to another String, that contains 8-bytes calculated by each hex from the string above. So in the example from above, the output string would be:

"00000001 00000010 00000011 000001000 000001001 000001011 ..."

how can I do that?

I tried to do:

byte[] bytes1 = toByteArray(tempHash);

where

public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
}

but when I iterate over this array:

for (byte singleByte: bytes1) {
    System.out.println(singleByte);
}

for the first character I'm getting 18 instead of 00000001. I'm a little bit lost over here. Could you please help me with that?

Upvotes: 2

Views: 248

Answers (3)

Hassam Abdelillah
Hassam Abdelillah

Reputation: 2294

public byte hexToByte(String hexString) {
    int firstDigit = toDigit(hexString.charAt(0));
    int secondDigit = toDigit(hexString.charAt(1));
    return (byte) ((firstDigit << 4) + secondDigit);
}

private int toDigit(char hexChar) {
    int digit = Character.digit(hexChar, 16);
    if(digit == -1) {
        throw new IllegalArgumentException(
          "Invalid Hexadecimal Character: "+ hexChar);
    }
    return digit;
}

Here is the reference

Upvotes: -1

Jacob G.
Jacob G.

Reputation: 29680

One solution is to use a Stream:

String tempHash = "123456789ABCDEF123456789ABCDEF12";

String binary = tempHash.chars()              // Get stream of chars
    .map(c -> Character.digit(c, 16))         // Convert to hex digit
    .mapToObj(Integer::toBinaryString)        // Convert to binary
    .map(s -> "0".repeat(8 - s.length()) + s) // Pad left with zeros
    .collect(Collectors.joining(" "));        // Collect to String

System.out.println(binary);

Output:

00000001 00000010 00000011 00000100 00000101 ...

As Kevin pointed out in his comment below, a pre-Java 11 solution would be to replace the call to String#repeat:

String binary = tempHash.chars()              // Get stream of chars
    .map(c -> Character.digit(c, 16))         // Convert to hex digit
    .mapToObj(Integer::toBinaryString)        // Convert to binary
    .map(s -> new String(new char[8 - s.length()]).replace('\0', '0') + s) // Pad left with zeros
    .collect(Collectors.joining(" "));        // Collect to String

Upvotes: 3

ControlAltDel
ControlAltDel

Reputation: 35011

You can use Long.parseLong(String,16);

Once you have a long value, you can get the bytes by doing

long val = ...;
ByteBuffer buf = new ByteBuffer();
buf.put(0, val);

If your string is too long you will need to use a BigInteger. It's essentially the same thing, but a little more complicated

Upvotes: 0

Related Questions