1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/* 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright 2001-2004 The Apache Software Foundation. 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * you may not use this file except in compliance with the License. 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You may obtain a copy of the License at 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See the License for the specific language governing permissions and 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * limitations under the License. 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.commons.codec.binary; 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.BinaryDecoder; 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.BinaryEncoder; 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.DecoderException; 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.EncoderException; 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Hex encoder and decoder. 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Apache Software Foundation 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Id: Hex.java,v 1.13 2004/04/18 18:22:33 ggregory Exp $ 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class Hex implements BinaryEncoder, BinaryDecoder { 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Used building output as Hex 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final char[] DIGITS = { 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project '0', '1', '2', '3', '4', '5', '6', '7', 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }; 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts an array of characters representing hexidecimal values into an 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of bytes of those same values. The returned array will be half the 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * length of the passed array, as it takes two characters to represent any 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * given byte. An exception is thrown if the passed char array has an odd 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * number of elements. 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param data An array of characters containing hexidecimal digits 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A byte array containing binary data decoded from 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the supplied char array. 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException Thrown if an odd number or illegal of characters 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is supplied 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static byte[] decodeHex(char[] data) throws DecoderException { 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int len = data.length; 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if ((len & 0x01) != 0) { 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException("Odd number of characters."); 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project byte[] out = new byte[len >> 1]; 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // two characters form the hex value. 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0, j = 0; j < len; i++) { 66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int f = toDigit(data[j], j) << 4; 67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project j++; 68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project f = f | toDigit(data[j], j); 69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project j++; 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project out[i] = (byte) (f & 0xFF); 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return out; 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts a hexadecimal character to an integer. 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param ch A character to convert to an integer digit 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param index The index of the character in the source 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return An integer 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException Thrown if ch is an illegal hex character 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static int toDigit(char ch, int index) throws DecoderException { 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int digit = Character.digit(ch, 16); 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (digit == -1) { 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException("Illegal hexadecimal charcter " + ch + " at index " + index); 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return digit; 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order. 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The returned array will be double the length of the passed array, as it takes two characters to represent any 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * given byte. 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param data 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * a byte[] to convert to Hex characters 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A char[] containing hexidecimal characters 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static char[] encodeHex(byte[] data) { 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int l = data.length; 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project char[] out = new char[l << 1]; 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // two characters form the hex value. 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0, j = 0; i < l; i++) { 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ]; 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project out[j++] = DIGITS[ 0x0F & data[i] ]; 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return out; 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts an array of character bytes representing hexidecimal values into an 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of bytes of those same values. The returned array will be half the 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * length of the passed array, as it takes two characters to represent any 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * given byte. An exception is thrown if the passed char array has an odd 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * number of elements. 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param array An array of character bytes containing hexidecimal digits 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A byte array containing binary data decoded from 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the supplied byte array (representing characters). 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException Thrown if an odd number of characters is supplied 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to this function 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #decodeHex(char[]) 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public byte[] decode(byte[] array) throws DecoderException { 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decodeHex(new String(array).toCharArray()); 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts a String or an array of character bytes representing hexidecimal values into an 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of bytes of those same values. The returned array will be half the 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * length of the passed String or array, as it takes two characters to represent any 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * given byte. An exception is thrown if the passed char array has an odd 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * number of elements. 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param object A String or, an array of character bytes containing hexidecimal digits 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A byte array containing binary data decoded from 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the supplied byte array (representing characters). 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException Thrown if an odd number of characters is supplied 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to this function or the object is not a String or char[] 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #decodeHex(char[]) 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object decode(Object object) throws DecoderException { 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project char[] charArray = object instanceof String ? ((String) object).toCharArray() : (char[]) object; 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decodeHex(charArray); 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassCastException e) { 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException(e.getMessage()); 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts an array of bytes into an array of bytes for the characters representing the 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * hexidecimal values of each byte in order. The returned array will be 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * double the length of the passed array, as it takes two characters to 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * represent any given byte. 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param array a byte[] to convert to Hex characters 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A byte[] containing the bytes of the hexidecimal characters 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #encodeHex(byte[]) 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public byte[] encode(byte[] array) { 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new String(encodeHex(array)).getBytes(); 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Converts a String or an array of bytes into an array of characters representing the 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * hexidecimal values of each byte in order. The returned array will be 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * double the length of the passed String or array, as it takes two characters to 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * represent any given byte. 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param object a String, or byte[] to convert to Hex characters 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return A char[] containing hexidecimal characters 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws EncoderException Thrown if the given object is not a String or byte[] 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #encodeHex(byte[]) 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object encode(Object object) throws EncoderException { 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project byte[] byteArray = object instanceof String ? ((String) object).getBytes() : (byte[]) object; 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return encodeHex(byteArray); 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassCastException e) { 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new EncoderException(e.getMessage()); 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 193