Here is a java.util.Base64
-like implementation, isn't it pretty?
import java.util.Arrays;
public class Base16/* a.k.a. Hex */ {
public static class Encoder{
private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
private boolean upper;
public Encoder(boolean upper) {
this.upper=upper;
}
public String encode(byte[] data){
char[] value=new char[data.length*2];
char[] toHex=upper?toUpperHex:toLowerHex;
for(int i=0,j=0; i<data.length; i++){
int octet=data[i]&0xFF;
value[j++]=toHex[octet>>4];
value[j++]=toHex[octet&0xF];
}
return new String(value);
}
static final Encoder LOWER_CASE=new Encoder(false);
static final Encoder UPPER_CASE=new Encoder(true);
}
public static Encoder getEncoder(){
return Encoder.LOWER_CASE;
}
public static Encoder getUpperEncoder(){
return Encoder.UPPER_CASE;
}
public static class Decoder{
private static int maxIndex=102;
private static int[] toIndex;
static {
toIndex=new int[maxIndex+1];
Arrays.fill(toIndex, -1);
char[] chars={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
for(int i=0; i<chars.length; i++) {
toIndex[(int)chars[i]]=i;
}
}
public Decoder() {
}
public byte[] decode(String str) {
char[] value=str.toCharArray();
int start=0;
if(value.length>2 && value[0]=='0' && (value[1]=='x' || value[1]=='X')) {
start=2;
}
int byteLength=(value.length-start)/2; // ignore trailing odd char if exists
byte[] data=new byte[byteLength];
for(int i=start,j=0;i<value.length;i+=2,j++){
int i1;
int i2;
char c1=value[i];
char c2=value[i+1];
if(c1>maxIndex || (i1=toIndex[(int)c1])<0 || c2>maxIndex || (i2=toIndex[(int)c2])<0) {
throw new IllegalArgumentException("Invalid character at "+i);
}
data[j]=(byte)((i1<<4)+i2);
}
return data;
}
static final Decoder IGNORE_CASE=new Decoder();
}
public static Decoder getDecoder(){
return Decoder.IGNORE_CASE;
}
}