001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.tomcat.util.buf;
019:
020: import java.io.ByteArrayOutputStream;
021: import org.apache.tomcat.util.res.StringManager;
022:
023: /**
024: * Library of utility methods useful in dealing with converting byte arrays
025: * to and from strings of hexadecimal digits.
026: * Code from Ajp11, from Apache's JServ.
027: *
028: * @author Craig R. McClanahan
029: */
030:
031: public final class HexUtils {
032:
033: // -------------------------------------------------------------- Constants
034:
035: /**
036: * Table for HEX to DEC byte translation.
037: */
038: public static final int[] DEC = { -1, -1, -1, -1, -1, -1, -1, -1,
039: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
040: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
041: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
042: 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
043: 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
044: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
045: 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
046: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
047: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
048: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
049: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
050: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
051: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
052: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
053: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
054: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
055: -1, -1, -1, -1, -1, -1, -1, -1, };
056:
057: /**
058: * Table for DEC to HEX byte translation.
059: */
060: public static final byte[] HEX = { (byte) '0', (byte) '1',
061: (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
062: (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
063: (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
064:
065: /**
066: * The string manager for this package.
067: */
068: private static StringManager sm = StringManager
069: .getManager("org.apache.tomcat.util.buf.res");
070:
071: // --------------------------------------------------------- Static Methods
072:
073: /**
074: * Convert a String of hexadecimal digits into the corresponding
075: * byte array by encoding each two hexadecimal digits as a byte.
076: *
077: * @param digits Hexadecimal digits representation
078: *
079: * @exception IllegalArgumentException if an invalid hexadecimal digit
080: * is found, or the input string contains an odd number of hexadecimal
081: * digits
082: */
083: public static byte[] convert(String digits) {
084:
085: ByteArrayOutputStream baos = new ByteArrayOutputStream();
086: for (int i = 0; i < digits.length(); i += 2) {
087: char c1 = digits.charAt(i);
088: if ((i + 1) >= digits.length())
089: throw new IllegalArgumentException(sm
090: .getString("hexUtil.odd"));
091: char c2 = digits.charAt(i + 1);
092: byte b = 0;
093: if ((c1 >= '0') && (c1 <= '9'))
094: b += ((c1 - '0') * 16);
095: else if ((c1 >= 'a') && (c1 <= 'f'))
096: b += ((c1 - 'a' + 10) * 16);
097: else if ((c1 >= 'A') && (c1 <= 'F'))
098: b += ((c1 - 'A' + 10) * 16);
099: else
100: throw new IllegalArgumentException(sm
101: .getString("hexUtil.bad"));
102: if ((c2 >= '0') && (c2 <= '9'))
103: b += (c2 - '0');
104: else if ((c2 >= 'a') && (c2 <= 'f'))
105: b += (c2 - 'a' + 10);
106: else if ((c2 >= 'A') && (c2 <= 'F'))
107: b += (c2 - 'A' + 10);
108: else
109: throw new IllegalArgumentException(sm
110: .getString("hexUtil.bad"));
111: baos.write(b);
112: }
113: return (baos.toByteArray());
114:
115: }
116:
117: /**
118: * Convert a byte array into a printable format containing a
119: * String of hexadecimal digit characters (two per byte).
120: *
121: * @param bytes Byte array representation
122: */
123: public static String convert(byte bytes[]) {
124:
125: StringBuffer sb = new StringBuffer(bytes.length * 2);
126: for (int i = 0; i < bytes.length; i++) {
127: sb.append(convertDigit((int) (bytes[i] >> 4)));
128: sb.append(convertDigit((int) (bytes[i] & 0x0f)));
129: }
130: return (sb.toString());
131:
132: }
133:
134: /**
135: * Convert 4 hex digits to an int, and return the number of converted
136: * bytes.
137: *
138: * @param hex Byte array containing exactly four hexadecimal digits
139: *
140: * @exception IllegalArgumentException if an invalid hexadecimal digit
141: * is included
142: */
143: public static int convert2Int(byte[] hex) {
144: // Code from Ajp11, from Apache's JServ
145:
146: // assert b.length==4
147: // assert valid data
148: int len;
149: if (hex.length < 4)
150: return 0;
151: if (DEC[hex[0]] < 0)
152: throw new IllegalArgumentException(sm
153: .getString("hexUtil.bad"));
154: len = DEC[hex[0]];
155: len = len << 4;
156: if (DEC[hex[1]] < 0)
157: throw new IllegalArgumentException(sm
158: .getString("hexUtil.bad"));
159: len += DEC[hex[1]];
160: len = len << 4;
161: if (DEC[hex[2]] < 0)
162: throw new IllegalArgumentException(sm
163: .getString("hexUtil.bad"));
164: len += DEC[hex[2]];
165: len = len << 4;
166: if (DEC[hex[3]] < 0)
167: throw new IllegalArgumentException(sm
168: .getString("hexUtil.bad"));
169: len += DEC[hex[3]];
170: return len;
171: }
172:
173: /**
174: * [Private] Convert the specified value (0 .. 15) to the corresponding
175: * hexadecimal digit.
176: *
177: * @param value Value to be converted
178: */
179: private static char convertDigit(int value) {
180:
181: value &= 0x0f;
182: if (value >= 10)
183: return ((char) (value - 10 + 'a'));
184: else
185: return ((char) (value + '0'));
186:
187: }
188:
189: }
|