001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/HexUtils.java,v 1.3 2001/07/22 20:25:13 pier Exp $
003: * $Revision: 1.3 $
004: * $Date: 2001/07/22 20:25:13 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.catalina.util;
065:
066: import java.io.ByteArrayOutputStream;
067:
068: /**
069: * Library of utility methods useful in dealing with converting byte arrays
070: * to and from strings of hexadecimal digits.
071: *
072: * @author Craig R. McClanahan
073: */
074:
075: public final class HexUtils {
076: // Code from Ajp11, from Apache's JServ
077:
078: // Table for HEX to DEC byte translation
079: public static final int[] DEC = { -1, -1, -1, -1, -1, -1, -1, -1,
080: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
081: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
082: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
083: 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
084: 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
085: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
086: 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
087: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
088: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
089: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
090: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
091: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
092: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
093: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
094: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
095: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
096: -1, -1, -1, -1, -1, -1, -1, -1, };
097:
098: /**
099: * The string manager for this package.
100: */
101: private static StringManager sm = StringManager
102: .getManager("org.apache.catalina.util");
103:
104: /**
105: * Convert a String of hexadecimal digits into the corresponding
106: * byte array by encoding each two hexadecimal digits as a byte.
107: *
108: * @param digits Hexadecimal digits representation
109: *
110: * @exception IllegalArgumentException if an invalid hexadecimal digit
111: * is found, or the input string contains an odd number of hexadecimal
112: * digits
113: */
114: public static byte[] convert(String digits) {
115:
116: ByteArrayOutputStream baos = new ByteArrayOutputStream();
117: for (int i = 0; i < digits.length(); i += 2) {
118: char c1 = digits.charAt(i);
119: if ((i + 1) >= digits.length())
120: throw new IllegalArgumentException(sm
121: .getString("hexUtil.odd"));
122: char c2 = digits.charAt(i + 1);
123: byte b = 0;
124: if ((c1 >= '0') && (c1 <= '9'))
125: b += ((c1 - '0') * 16);
126: else if ((c1 >= 'a') && (c1 <= 'f'))
127: b += ((c1 - 'a' + 10) * 16);
128: else if ((c1 >= 'A') && (c1 <= 'F'))
129: b += ((c1 - 'A' + 10) * 16);
130: else
131: throw new IllegalArgumentException(sm
132: .getString("hexUtil.bad"));
133: if ((c2 >= '0') && (c2 <= '9'))
134: b += (c2 - '0');
135: else if ((c2 >= 'a') && (c2 <= 'f'))
136: b += (c2 - 'a' + 10);
137: else if ((c2 >= 'A') && (c2 <= 'F'))
138: b += (c2 - 'A' + 10);
139: else
140: throw new IllegalArgumentException(sm
141: .getString("hexUtil.bad"));
142: baos.write(b);
143: }
144: return (baos.toByteArray());
145:
146: }
147:
148: /**
149: * Convert a byte array into a printable format containing a
150: * String of hexadecimal digit characters (two per byte).
151: *
152: * @param bytes Byte array representation
153: */
154: public static String convert(byte bytes[]) {
155:
156: StringBuffer sb = new StringBuffer(bytes.length * 2);
157: for (int i = 0; i < bytes.length; i++) {
158: sb.append(convertDigit((int) (bytes[i] >> 4)));
159: sb.append(convertDigit((int) (bytes[i] & 0x0f)));
160: }
161: return (sb.toString());
162:
163: }
164:
165: /**
166: * Convert 4 hex digits to an int, and return the number of converted
167: * bytes.
168: *
169: * @param hex Byte array containing exactly four hexadecimal digits
170: *
171: * @exception IllegalArgumentException if an invalid hexadecimal digit
172: * is included
173: */
174: public static int convert2Int(byte[] hex) {
175: // Code from Ajp11, from Apache's JServ
176:
177: // assert b.length==4
178: // assert valid data
179: int len;
180: if (hex.length < 4)
181: return 0;
182: if (DEC[hex[0]] < 0)
183: throw new IllegalArgumentException(sm
184: .getString("hexUtil.bad"));
185: len = DEC[hex[0]];
186: len = len << 4;
187: if (DEC[hex[1]] < 0)
188: throw new IllegalArgumentException(sm
189: .getString("hexUtil.bad"));
190: len += DEC[hex[1]];
191: len = len << 4;
192: if (DEC[hex[2]] < 0)
193: throw new IllegalArgumentException(sm
194: .getString("hexUtil.bad"));
195: len += DEC[hex[2]];
196: len = len << 4;
197: if (DEC[hex[3]] < 0)
198: throw new IllegalArgumentException(sm
199: .getString("hexUtil.bad"));
200: len += DEC[hex[3]];
201: return len;
202: }
203:
204: /**
205: * [Private] Convert the specified value (0 .. 15) to the corresponding
206: * hexadecimal digit.
207: *
208: * @param value Value to be converted
209: */
210: private static char convertDigit(int value) {
211:
212: value &= 0x0f;
213: if (value >= 10)
214: return ((char) (value - 10 + 'a'));
215: else
216: return ((char) (value + '0'));
217:
218: }
219:
220: }
|