Here is my attempt at converting hex strings to byte arrays and converting byte arrays to hex strings:
net.coderodde.util.ByteStringConverter
package net.coderodde.util;
import java.util.Scanner;
public class ByteStringConverter {
/**
* Converts the given byte array to its textual hex representation.
* @param bytes the byte array to stringify.
* @return the string representing the input byte array.
*/
public static String convertByteArrayToHexString(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
stringBuilder.append(convertByteToHexString(b));
}
return stringBuilder.toString();
}
/**
* Converts the given hex string to the byte array it represents.
* @param hexString the hex string to convert.
* @return the byte array represented by the input hex string.
*/
public static byte[] convertHexStringToByteArray(String hexString) {
byte[] byteArray = new byte[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
byteArray[i / 2] = convertHexByteStringToByte(
hexString.substring(i, i + 2));
}
return byteArray;
}
/**
* Converts the input character {@code c} to the nibble it represents. This
* method assumes that {@code c} is numeric or within range
* {@code a, b, c, d, e, f}.
* @param c the character to convert to a nibble.
* @return the byte value of the textual representation of a nibble.
*/
private static byte convertHexCharToNibble(char c) {
c = Character.toLowerCase(c);
switch (c) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
return 10;
case 'b':
return 11;
case 'c':
return 12;
case 'd':
return 13;
case 'e':
return 14;
case 'f':
return 15;
default:
throw new IllegalArgumentException("Not a hex digit: " + c);
}
}
/**
* Converts the input hex byte string to the byte it represents.
* @param hexByteString the hex byte string to convert.
* @return the byte value represented by {@code hexByteString}.
*/
private static byte convertHexByteStringToByte(String hexByteString) {
char lo = hexByteString.charAt(1);
char hi = hexByteString.charAt(0);
byte lob = convertHexCharToNibble(lo);
byte hib = convertHexCharToNibble(hi);
return (byte)((hib << 4) | lob);
}
/**
* Converts the given byte to its textual hex representation.
* @param b the byte to convert.
* @return the textual representation of the byte {@code b}.
*/
private static String convertByteToHexString(byte b) {
byte lo = (byte)(b & (byte) 0xf);
byte hi = (byte)((b >>> 4) & (byte) 0xf);
StringBuilder stringBuilder = new StringBuilder(2);
appendNibbleToStringBuilder(stringBuilder, hi);
appendNibbleToStringBuilder(stringBuilder, lo);
return stringBuilder.toString();
}
/**
* Appends the textual representation of {@code nibble} to
* {@code stringBuilder}.
* @param stringBuilder the target string builder.
* @param nibble the nibble to append.
*/
private static void appendNibbleToStringBuilder(StringBuilder stringBuilder,
byte nibble) {
switch (nibble) {
case 0:
stringBuilder.append('0');
break;
case 1:
stringBuilder.append('1');
break;
case 2:
stringBuilder.append('2');
break;
case 3:
stringBuilder.append('3');
break;
case 4:
stringBuilder.append('4');
break;
case 5:
stringBuilder.append('5');
break;
case 6:
stringBuilder.append('6');
break;
case 7:
stringBuilder.append('7');
break;
case 8:
stringBuilder.append('8');
break;
case 9:
stringBuilder.append('9');
break;
case 10:
stringBuilder.append('a');
break;
case 11:
stringBuilder.append('b');
break;
case 12:
stringBuilder.append('c');
break;
case 13:
stringBuilder.append('d');
break;
case 14:
stringBuilder.append('e');
break;
case 15:
stringBuilder.append('f');
break;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
String hexString = scanner.next();
byte[] hexBytes = convertHexStringToByteArray(hexString);
String newHexString = convertByteArrayToHexString(hexBytes);
System.out.println(newHexString);
}
}
}
As always, any critique is much appreciated!
1 Answer 1
You implemented convertByteArrayToHexString
really inefficiently because you allocate a new string for each byte that is converted.
Also, there's no need for a StringBuilder since a character array suffices. The idiomatic code for converting a byte array to a hex string is:
public static String toHex(byte[] bytes) {
char[] chars = new char[2 * bytes.length];
for (int i = 0; i < bytes.length; i++) {
chars[2 * i] = "0123456789abcdef".charAt((bytes[i] & 0xf0) >> 4);
chars[2 * i + 1] = "0123456789abcdef".charAt(bytes[i] & 0x0f);
}
return new String(chars);
}
I wonder why you chose the inefficient variant over this straightforward code.
Explore related questions
See similar questions with these tags.