1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.id; 19 20 import org.apache.commons.id.DecoderException; 21 import org.apache.commons.id.EncoderException; 22 23 /** 24 * Hex encoder and decoder. 25 * 26 * @since 1.1 27 * @author Apache Software Foundation 28 * @version $Id: Hex.java 480488 2006-11-29 08:57:26Z bayard $ 29 */ 30 public class Hex {//implements BinaryEncoder, BinaryDecoder { 31 32 /** 33 * Used to build output as Hex 34 */ 35 private static final char[] DIGITS = { 36 '0', '1', '2', '3', '4', '5', '6', '7', 37 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 38 }; 39 40 /** 41 * Converts an array of characters representing hexidecimal values into an 42 * array of bytes of those same values. The returned array will be half the 43 * length of the passed array, as it takes two characters to represent any 44 * given byte. An exception is thrown if the passed char array has an odd 45 * number of elements. 46 * 47 * @param data An array of characters containing hexidecimal digits 48 * @return A byte array containing binary data decoded from 49 * the supplied char array. 50 * @throws DecoderException Thrown if an odd number or illegal of characters 51 * is supplied 52 */ 53 public static byte[] decodeHex(char[] data) throws DecoderException { 54 55 int len = data.length; 56 57 if ((len & 0x01) != 0) { 58 throw new DecoderException("Odd number of characters."); 59 } 60 61 byte[] out = new byte[len >> 1]; 62 63 // two characters form the hex value. 64 for (int i = 0, j = 0; j < len; i++) { 65 int f = toDigit(data[j], j) << 4; 66 j++; 67 f = f | toDigit(data[j], j); 68 j++; 69 out[i] = (byte) (f & 0xFF); 70 } 71 72 return out; 73 } 74 75 /** 76 * Converts a hexadecimal character to an integer. 77 * 78 * @param ch A character to convert to an integer digit 79 * @param index The index of the character in the source 80 * @return An integer 81 * @throws DecoderException Thrown if ch is an illegal hex character 82 */ 83 protected static int toDigit(char ch, int index) throws DecoderException { 84 int digit = Character.digit(ch, 16); 85 if (digit == -1) { 86 throw new DecoderException("Illegal hexadecimal charcter " + ch + " at index " + index); 87 } 88 return digit; 89 } 90 91 /** 92 * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order. 93 * The returned array will be double the length of the passed array, as it takes two characters to represent any 94 * given byte. 95 * 96 * @param data 97 * a byte[] to convert to Hex characters 98 * @return A char[] containing hexidecimal characters 99 */ 100 public static char[] encodeHex(byte[] data) { 101 102 int l = data.length; 103 104 char[] out = new char[l << 1]; 105 106 // two characters form the hex value. 107 for (int i = 0, j = 0; i < l; i++) { 108 out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ]; 109 out[j++] = DIGITS[ 0x0F & data[i] ]; 110 } 111 112 return out; 113 } 114 115 /** 116 * Converts an array of character bytes representing hexidecimal values into an 117 * array of bytes of those same values. The returned array will be half the 118 * length of the passed array, as it takes two characters to represent any 119 * given byte. An exception is thrown if the passed char array has an odd 120 * number of elements. 121 * 122 * @param array An array of character bytes containing hexidecimal digits 123 * @return A byte array containing binary data decoded from 124 * the supplied byte array (representing characters). 125 * @throws DecoderException Thrown if an odd number of characters is supplied 126 * to this function 127 * @see #decodeHex(char[]) 128 */ 129 public byte[] decode(byte[] array) throws DecoderException { 130 return decodeHex(new String(array).toCharArray()); 131 } 132 133 /** 134 * Converts a String or an array of character bytes representing hexidecimal values into an 135 * array of bytes of those same values. The returned array will be half the 136 * length of the passed String or array, as it takes two characters to represent any 137 * given byte. An exception is thrown if the passed char array has an odd 138 * number of elements. 139 * 140 * @param object A String or, an array of character bytes containing hexidecimal digits 141 * @return A byte array containing binary data decoded from 142 * the supplied byte array (representing characters). 143 * @throws DecoderException Thrown if an odd number of characters is supplied 144 * to this function or the object is not a String or char[] 145 * @see #decodeHex(char[]) 146 */ 147 public Object decode(Object object) throws DecoderException { 148 try { 149 char[] charArray = object instanceof String ? ((String) object).toCharArray() : (char[]) object; 150 return decodeHex(charArray); 151 } catch (ClassCastException e) { 152 throw new DecoderException(e.getMessage()); 153 } 154 } 155 156 /** 157 * Converts an array of bytes into an array of bytes for the characters representing the 158 * hexidecimal values of each byte in order. The returned array will be 159 * double the length of the passed array, as it takes two characters to 160 * represent any given byte. 161 * 162 * @param array a byte[] to convert to Hex characters 163 * @return A byte[] containing the bytes of the hexidecimal characters 164 * @see #encodeHex(byte[]) 165 */ 166 public byte[] encode(byte[] array) { 167 return new String(encodeHex(array)).getBytes(); 168 } 169 170 /** 171 * Converts a String or an array of bytes into an array of characters representing the 172 * hexidecimal values of each byte in order. The returned array will be 173 * double the length of the passed String or array, as it takes two characters to 174 * represent any given byte. 175 * 176 * @param object a String, or byte[] to convert to Hex characters 177 * @return A char[] containing hexidecimal characters 178 * @throws EncoderException Thrown if the given object is not a String or byte[] 179 * @see #encodeHex(byte[]) 180 */ 181 public Object encode(Object object) throws EncoderException { 182 try { 183 byte[] byteArray = object instanceof String ? ((String) object).getBytes() : (byte[]) object; 184 return encodeHex(byteArray); 185 } catch (ClassCastException e) { 186 throw new EncoderException(e.getMessage()); 187 } 188 } 189 190 } 191