package com.gettingmobile.io;
public final class Base16 {
private Base16() {
}
private static char encodeNibble(int nibble) {
final byte n = (byte) (nibble & 0x0f);
return (char) ((n < 10) ? '0' + n : 'a' + (n - 10));
}
public static String encode(byte[] data) {
StringBuffer s = new StringBuffer();
for (byte b : data) {
s.append(encodeNibble(b >> 4)).append(encodeNibble(b & 0x0f));
}
return s.toString();
}
private static byte decodeNibble(char nc) {
final char c = Character.toLowerCase(nc);
if (c >= '0' && c <= '9') {
return (byte) (c - '0');
} else if (c >= 'a' && c <= 'f') {
return (byte) (10 + c - 'a');
} else {
throw new IllegalArgumentException("Invalid nibble " + nc);
}
}
public static byte[] decode(String encoded) {
if (encoded.length() % 2 != 0)
throw new IllegalArgumentException("No valid hexadecimal string");
final byte[] data = new byte[encoded.length() / 2];
for (int i = 0; i < encoded.length(); i+= 2) {
data[i / 2] = (byte) ((decodeNibble(encoded.charAt(i)) << 4) | decodeNibble(encoded.charAt(i + 1)));
}
return data;
}
}