001 package edu.harvard.deas.hyperenc.util; 002 003 /** 004 * Converts byte sequences into hex strings. 005 */ 006 public class HexCoder 007 { 008 /** 009 * Encodes <code>data</code> as a hex string. <code>data[0]</code> comes first 010 * in the string, followed by the others in order. Each byte is encoded as 011 * specified by {@link java.lang.Integer#toHexString(int)}, except padded with 012 * a leading zero as necessary so that each byte is represented by two 013 * characters. The length of the string is thus exactly 014 * <code>2*data.length</code>. 015 * 016 * @param data 017 * An array of bytes. May not be null. 018 * @return The hex encoding of <code>data</code>. 019 */ 020 public static String encode(byte[] data) { 021 if (data == null) { 022 throw new IllegalArgumentException("data must not be null"); 023 } 024 025 String str = new String(); 026 for(int i = 0; i < data.length; i++) { 027 // Move bytes to unsigned integers and represent as hex 028 // Prepend with 0 if necessary 029 int d = data[i]; 030 if (d < 0) d += 256; 031 str += ((d < 16) ? "0" : "") + Integer.toHexString(d); 032 } 033 assert(str.length() % 2 == 0); 034 return str; 035 } 036 037 /** 038 * Decodes the hex string <code>data</code> and returns the corresponding 039 * bytes. The returned array has size <code>data.length()/2</code>; 040 * <code>data</code> must have even length, and only contain characters 0-9 041 * and a-f. 042 * @param data A hex-encoded string. 043 * @return The byte array encoded by <code>data</code>. 044 * @throws IllegalArgumentException if <code>data</code> does not have even 045 * length, or if <code>data</code> contains an invalid character (one 046 * other than 0-9 or a-f) 047 */ 048 public static byte[] decode(String data) { 049 if (data.length() % 2 != 0) { 050 throw new IllegalArgumentException( 051 "data must have even length (length is " + data.length() + ")"); 052 } 053 054 byte [] b = new byte[data.length() / 2]; 055 for(int i = 0; i < data.length(); i += 2) { 056 try { 057 int d = Integer.parseInt(data.substring(i, i+2), 16); 058 if (d >= 128) d -= 256; 059 b[i/2] = (byte)d; 060 } catch (NumberFormatException e) { 061 throw new IllegalArgumentException( 062 "data contains an illegal character in byte " + i/2, e); 063 } 064 } 065 return b; 066 } 067 } 068 069