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 $
30d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *
31d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
32d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
33d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     for further details.
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
35d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class Hex implements BinaryEncoder, BinaryDecoder {
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Used building output as Hex
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final char[] DIGITS = {
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        '0', '1', '2', '3', '4', '5', '6', '7',
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    };
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts an array of characters representing hexidecimal values into an
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * array of bytes of those same values. The returned array will be half the
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * length of the passed array, as it takes two characters to represent any
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * given byte. An exception is thrown if the passed char array has an odd
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * number of elements.
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param data An array of characters containing hexidecimal digits
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A byte array containing binary data decoded from
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         the supplied char array.
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException Thrown if an odd number or illegal of characters
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         is supplied
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public static byte[] decodeHex(char[] data) throws DecoderException {
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int len = data.length;
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if ((len & 0x01) != 0) {
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new DecoderException("Odd number of characters.");
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        byte[] out = new byte[len >> 1];
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // two characters form the hex value.
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 0, j = 0; j < len; i++) {
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int f = toDigit(data[j], j) << 4;
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            j++;
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            f = f | toDigit(data[j], j);
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            j++;
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            out[i] = (byte) (f & 0xFF);
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return out;
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts a hexadecimal character to an integer.
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param ch A character to convert to an integer digit
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param index The index of the character in the source
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return An integer
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException Thrown if ch is an illegal hex character
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected static int toDigit(char ch, int index) throws DecoderException {
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int digit = Character.digit(ch, 16);
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (digit == -1) {
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new DecoderException("Illegal hexadecimal charcter " + ch + " at index " + index);
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return digit;
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order.
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * The returned array will be double the length of the passed array, as it takes two characters to represent any
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * given byte.
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param data
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  a byte[] to convert to Hex characters
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A char[] containing hexidecimal characters
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public static char[] encodeHex(byte[] data) {
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int l = data.length;
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           char[] out = new char[l << 1];
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           // two characters form the hex value.
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           for (int i = 0, j = 0; i < l; i++) {
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project               out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ];
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project               out[j++] = DIGITS[ 0x0F & data[i] ];
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           }
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project           return out;
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts an array of character bytes representing hexidecimal values into an
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * array of bytes of those same values. The returned array will be half the
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * length of the passed array, as it takes two characters to represent any
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * given byte. An exception is thrown if the passed char array has an odd
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * number of elements.
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param array An array of character bytes containing hexidecimal digits
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A byte array containing binary data decoded from
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         the supplied byte array (representing characters).
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException Thrown if an odd number of characters is supplied
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                   to this function
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #decodeHex(char[])
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public byte[] decode(byte[] array) throws DecoderException {
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return decodeHex(new String(array).toCharArray());
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts a String or an array of character bytes representing hexidecimal values into an
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * array of bytes of those same values. The returned array will be half the
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * length of the passed String or array, as it takes two characters to represent any
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * given byte. An exception is thrown if the passed char array has an odd
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * number of elements.
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param object A String or, an array of character bytes containing hexidecimal digits
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A byte array containing binary data decoded from
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         the supplied byte array (representing characters).
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException Thrown if an odd number of characters is supplied
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                   to this function or the object is not a String or char[]
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #decodeHex(char[])
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public Object decode(Object object) throws DecoderException {
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            char[] charArray = object instanceof String ? ((String) object).toCharArray() : (char[]) object;
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return decodeHex(charArray);
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } catch (ClassCastException e) {
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new DecoderException(e.getMessage());
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts an array of bytes into an array of bytes for the characters representing the
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * hexidecimal values of each byte in order. The returned array will be
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * double the length of the passed array, as it takes two characters to
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * represent any given byte.
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param array a byte[] to convert to Hex characters
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A byte[] containing the bytes of the hexidecimal characters
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #encodeHex(byte[])
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public byte[] encode(byte[] array) {
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new String(encodeHex(array)).getBytes();
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Converts a String or an array of bytes into an array of characters representing the
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * hexidecimal values of each byte in order. The returned array will be
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * double the length of the passed String or array, as it takes two characters to
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * represent any given byte.
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param object a String, or byte[] to convert to Hex characters
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return A char[] containing hexidecimal characters
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws EncoderException Thrown if the given object is not a String or byte[]
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #encodeHex(byte[])
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public Object encode(Object object) throws EncoderException {
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            byte[] byteArray = object instanceof String ? ((String) object).getBytes() : (byte[]) object;
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return encodeHex(byteArray);
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } catch (ClassCastException e) {
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new EncoderException(e.getMessage());
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
198