001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064:
065: package com.jcorporate.expresso.core.misc;
066:
067: import com.jcorporate.expresso.kernel.util.FastStringBuffer;
068:
069: /**
070: * Hex encoding class.
071: * Many thanks goes to Wei Dai's
072: * <A HREF="http://www.eskimo.com/~weidai/cryptlib.html">Crypto++</A> for providing
073: * public domain C++ code that this could be derived from.
074: *
075: * @author Michael Rimov
076: */
077: public class HexEncoder {
078:
079: /**
080: * Lookup table used for encoding.
081: */
082: private static final char[] codes = { '0', '1', '2', '3', '4', '5',
083: '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
084:
085: private static final String this Class = HexEncoder.class.getName();
086:
087: public HexEncoder() {
088: }
089:
090: /**
091: * A step in the decoding process.
092: *
093: * @param inChar the character to conver
094: * @return -1 if the input character is not a proper hex code. otherwise the
095: * value we need.
096: */
097: private static int convertToNumber(char inChar) {
098: if (inChar >= '0' && inChar <= '9') {
099: return inChar - '0';
100: }
101: if (inChar >= 'A' && inChar <= 'F') {
102: return inChar - 'A' + 10;
103: }
104: if (inChar >= 'a' && inChar <= 'f') {
105: return inChar - 'a' + 10;
106: }
107:
108: return -1;
109: } /* convertToNumber(char) */
110:
111: /**
112: * Decodes a string containing hexadecimal characters into the resulting binary
113: * values.
114: *
115: * @param inputData - The string to be decoded. The input string must have
116: * only characters "0-9 and A-F" Any other characters in the string
117: * will result in an illegal argument exception.
118: * @return an array of bytes representing the decoded input string
119: * @throws IllegalArgumentException if the string is null, is of zero length, or
120: * contains illegal characters.
121: */
122: public static byte[] decode(String inputData)
123: throws IllegalArgumentException {
124:
125: //Parameter Checks
126: if (inputData == null) {
127: throw new IllegalArgumentException(this Class
128: + "decode(String)" + " inputData must not be null");
129: }
130:
131: int len = inputData.length();
132:
133: if (len == 0) {
134: throw new IllegalArgumentException(this Class
135: + "decode(String)"
136: + " inputData must be of length > 0");
137: }
138: if (len % 2 != 0) {
139: throw new IllegalArgumentException(this Class
140: + "decode(String)"
141: + " inputData must be of even length");
142: }
143:
144: //The main function
145: byte[] finalResult = new byte[len / 2];
146: int temp;
147: int arrayPos = 0;
148:
149: for (int i = 0; i < len; i++) {
150: temp = HexEncoder.convertToNumber(inputData.charAt(i));
151:
152: if (temp < 0) {
153: throw new IllegalArgumentException(this Class
154: + "decode(String)"
155: + " illegal hex character in input Data: "
156: + inputData);
157: }
158: if (i % 2 == 1) {
159: byte temp2 = (byte) (finalResult[arrayPos] << 4);
160: finalResult[arrayPos] = (byte) (temp2 | (byte) temp);
161: arrayPos++;
162: } else {
163: finalResult[arrayPos] = (byte) temp;
164: }
165: }
166:
167: return finalResult;
168: } /* decode(String) */
169:
170: /**
171: * Encode an array of binary data into a string of hexadecimal values.
172: *
173: * @param inputData - A byte array that will be encoded.
174: * @return The resulting encoded string.
175: * @throws IllegalArgumentException If the length of the byte array is zero.
176: */
177: public static String encode(byte[] inputData)
178: throws IllegalArgumentException {
179: int len = inputData.length;
180:
181: if (len == 0) {
182: throw new IllegalArgumentException(this Class
183: + ".encode(byte)"
184: + " inputData must be of length > 0");
185: }
186:
187: FastStringBuffer buffer = new FastStringBuffer(len * 2);
188:
189: for (int i = 0; i < len; i++) {
190: int a = inputData[i];
191:
192: if (a < 0) {
193: a = (a & 0x00FF); //Remove the sign extension
194: }
195:
196: a >>>= 4;
197: buffer.append(codes[a]);
198: buffer.append(codes[inputData[i] & 0x0F]);
199: }
200:
201: return buffer.toString();
202: } /* encode(byte) */
203:
204: /**
205: * Encode an array of binary data into a string of hexadecimal values.
206: *
207: * @param s the string to encode
208: * @return The resulting encoded string.
209: * @throws IllegalArgumentException If the length of the byte array is zero.
210: */
211: public static String encode(String s)
212: throws IllegalArgumentException {
213: return encode(s.getBytes());
214: } /* encode(String) */
215:
216: } /* HexEncoder */
217:
218: /* HexEncoder */
|