001: /*
002: * Copyright 2001-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.commons.codec.binary;
018:
019: import org.apache.commons.codec.BinaryDecoder;
020: import org.apache.commons.codec.BinaryEncoder;
021: import org.apache.commons.codec.DecoderException;
022: import org.apache.commons.codec.EncoderException;
023:
024: /**
025: * Hex encoder and decoder.
026: *
027: * @since 1.1
028: * @author Apache Software Foundation
029: * @version $Id: Hex.java,v 1.13 2004/04/18 18:22:33 ggregory Exp $
030: */
031: public class Hex implements BinaryEncoder, BinaryDecoder {
032:
033: /**
034: * Used building output as Hex
035: */
036: private static final char[] DIGITS = { '0', '1', '2', '3', '4',
037: '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
038:
039: /**
040: * Converts an array of characters representing hexidecimal values into an
041: * array of bytes of those same values. The returned array will be half the
042: * length of the passed array, as it takes two characters to represent any
043: * given byte. An exception is thrown if the passed char array has an odd
044: * number of elements.
045: *
046: * @param data An array of characters containing hexidecimal digits
047: * @return A byte array containing binary data decoded from
048: * the supplied char array.
049: * @throws DecoderException Thrown if an odd number or illegal of characters
050: * is supplied
051: */
052: public static byte[] decodeHex(char[] data) throws DecoderException {
053:
054: int len = data.length;
055:
056: if ((len & 0x01) != 0) {
057: throw new DecoderException("Odd number of characters.");
058: }
059:
060: byte[] out = new byte[len >> 1];
061:
062: // two characters form the hex value.
063: for (int i = 0, j = 0; j < len; i++) {
064: int f = toDigit(data[j], j) << 4;
065: j++;
066: f = f | toDigit(data[j], j);
067: j++;
068: out[i] = (byte) (f & 0xFF);
069: }
070:
071: return out;
072: }
073:
074: /**
075: * Converts a hexadecimal character to an integer.
076: *
077: * @param ch A character to convert to an integer digit
078: * @param index The index of the character in the source
079: * @return An integer
080: * @throws DecoderException Thrown if ch is an illegal hex character
081: */
082: protected static int toDigit(char ch, int index)
083: throws DecoderException {
084: int digit = Character.digit(ch, 16);
085: if (digit == -1) {
086: throw new DecoderException("Illegal hexadecimal charcter "
087: + ch + " at index " + index);
088: }
089: return digit;
090: }
091:
092: /**
093: * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order.
094: * The returned array will be double the length of the passed array, as it takes two characters to represent any
095: * given byte.
096: *
097: * @param data
098: * a byte[] to convert to Hex characters
099: * @return A char[] containing hexidecimal characters
100: */
101: public static char[] encodeHex(byte[] data) {
102:
103: int l = data.length;
104:
105: char[] out = new char[l << 1];
106:
107: // two characters form the hex value.
108: for (int i = 0, j = 0; i < l; i++) {
109: out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
110: out[j++] = DIGITS[0x0F & data[i]];
111: }
112:
113: return out;
114: }
115:
116: /**
117: * Converts an array of character bytes representing hexidecimal values into an
118: * array of bytes of those same values. The returned array will be half the
119: * length of the passed array, as it takes two characters to represent any
120: * given byte. An exception is thrown if the passed char array has an odd
121: * number of elements.
122: *
123: * @param array An array of character bytes containing hexidecimal digits
124: * @return A byte array containing binary data decoded from
125: * the supplied byte array (representing characters).
126: * @throws DecoderException Thrown if an odd number of characters is supplied
127: * to this function
128: * @see #decodeHex(char[])
129: */
130: public byte[] decode(byte[] array) throws DecoderException {
131: return decodeHex(new String(array).toCharArray());
132: }
133:
134: /**
135: * Converts a String or an array of character bytes representing hexidecimal values into an
136: * array of bytes of those same values. The returned array will be half the
137: * length of the passed String or array, as it takes two characters to represent any
138: * given byte. An exception is thrown if the passed char array has an odd
139: * number of elements.
140: *
141: * @param object A String or, an array of character bytes containing hexidecimal digits
142: * @return A byte array containing binary data decoded from
143: * the supplied byte array (representing characters).
144: * @throws DecoderException Thrown if an odd number of characters is supplied
145: * to this function or the object is not a String or char[]
146: * @see #decodeHex(char[])
147: */
148: public Object decode(Object object) throws DecoderException {
149: try {
150: char[] charArray = object instanceof String ? ((String) object)
151: .toCharArray()
152: : (char[]) object;
153: return decodeHex(charArray);
154: } catch (ClassCastException e) {
155: throw new DecoderException(e.getMessage());
156: }
157: }
158:
159: /**
160: * Converts an array of bytes into an array of bytes for the characters representing the
161: * hexidecimal values of each byte in order. The returned array will be
162: * double the length of the passed array, as it takes two characters to
163: * represent any given byte.
164: *
165: * @param array a byte[] to convert to Hex characters
166: * @return A byte[] containing the bytes of the hexidecimal characters
167: * @see #encodeHex(byte[])
168: */
169: public byte[] encode(byte[] array) {
170: return new String(encodeHex(array)).getBytes();
171: }
172:
173: /**
174: * Converts a String or an array of bytes into an array of characters representing the
175: * hexidecimal values of each byte in order. The returned array will be
176: * double the length of the passed String or array, as it takes two characters to
177: * represent any given byte.
178: *
179: * @param object a String, or byte[] to convert to Hex characters
180: * @return A char[] containing hexidecimal characters
181: * @throws EncoderException Thrown if the given object is not a String or byte[]
182: * @see #encodeHex(byte[])
183: */
184: public Object encode(Object object) throws EncoderException {
185: try {
186: byte[] byteArray = object instanceof String ? ((String) object)
187: .getBytes()
188: : (byte[]) object;
189: return encodeHex(byteArray);
190: } catch (ClassCastException e) {
191: throw new EncoderException(e.getMessage());
192: }
193: }
194:
195: }
|