001: /*
002: * Copyright 1999,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.catalina.util;
018:
019: import java.io.ByteArrayOutputStream;
020:
021: /**
022: * Library of utility methods useful in dealing with converting byte arrays
023: * to and from strings of hexadecimal digits.
024: *
025: * @author Craig R. McClanahan
026: */
027:
028: public final class HexUtils {
029: // Code from Ajp11, from Apache's JServ
030:
031: // Table for HEX to DEC byte translation
032: public static final int[] DEC = { -1, -1, -1, -1, -1, -1, -1, -1,
033: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
034: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
035: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
036: 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
037: 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
038: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
039: 11, 12, 13, 14, 15, -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, -1, -1, -1, -1, -1,
042: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
043: -1, -1, -1, -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, -1,
045: -1, -1, -1, -1, -1, -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, };
050:
051: /**
052: * The string manager for this package.
053: */
054: private static StringManager sm = StringManager
055: .getManager("org.apache.catalina.util");
056:
057: /**
058: * Convert a String of hexadecimal digits into the corresponding
059: * byte array by encoding each two hexadecimal digits as a byte.
060: *
061: * @param digits Hexadecimal digits representation
062: *
063: * @exception IllegalArgumentException if an invalid hexadecimal digit
064: * is found, or the input string contains an odd number of hexadecimal
065: * digits
066: */
067: public static byte[] convert(String digits) {
068:
069: ByteArrayOutputStream baos = new ByteArrayOutputStream();
070: for (int i = 0; i < digits.length(); i += 2) {
071: char c1 = digits.charAt(i);
072: if ((i + 1) >= digits.length())
073: throw new IllegalArgumentException(sm
074: .getString("hexUtil.odd"));
075: char c2 = digits.charAt(i + 1);
076: byte b = 0;
077: if ((c1 >= '0') && (c1 <= '9'))
078: b += ((c1 - '0') * 16);
079: else if ((c1 >= 'a') && (c1 <= 'f'))
080: b += ((c1 - 'a' + 10) * 16);
081: else if ((c1 >= 'A') && (c1 <= 'F'))
082: b += ((c1 - 'A' + 10) * 16);
083: else
084: throw new IllegalArgumentException(sm
085: .getString("hexUtil.bad"));
086: if ((c2 >= '0') && (c2 <= '9'))
087: b += (c2 - '0');
088: else if ((c2 >= 'a') && (c2 <= 'f'))
089: b += (c2 - 'a' + 10);
090: else if ((c2 >= 'A') && (c2 <= 'F'))
091: b += (c2 - 'A' + 10);
092: else
093: throw new IllegalArgumentException(sm
094: .getString("hexUtil.bad"));
095: baos.write(b);
096: }
097: return (baos.toByteArray());
098:
099: }
100:
101: /**
102: * Convert a byte array into a printable format containing a
103: * String of hexadecimal digit characters (two per byte).
104: *
105: * @param bytes Byte array representation
106: */
107: public static String convert(byte bytes[]) {
108:
109: StringBuffer sb = new StringBuffer(bytes.length * 2);
110: for (int i = 0; i < bytes.length; i++) {
111: sb.append(convertDigit((int) (bytes[i] >> 4)));
112: sb.append(convertDigit((int) (bytes[i] & 0x0f)));
113: }
114: return (sb.toString());
115:
116: }
117:
118: /**
119: * Convert 4 hex digits to an int, and return the number of converted
120: * bytes.
121: *
122: * @param hex Byte array containing exactly four hexadecimal digits
123: *
124: * @exception IllegalArgumentException if an invalid hexadecimal digit
125: * is included
126: */
127: public static int convert2Int(byte[] hex) {
128: // Code from Ajp11, from Apache's JServ
129:
130: // assert b.length==4
131: // assert valid data
132: int len;
133: if (hex.length < 4)
134: return 0;
135: if (DEC[hex[0]] < 0)
136: throw new IllegalArgumentException(sm
137: .getString("hexUtil.bad"));
138: len = DEC[hex[0]];
139: len = len << 4;
140: if (DEC[hex[1]] < 0)
141: throw new IllegalArgumentException(sm
142: .getString("hexUtil.bad"));
143: len += DEC[hex[1]];
144: len = len << 4;
145: if (DEC[hex[2]] < 0)
146: throw new IllegalArgumentException(sm
147: .getString("hexUtil.bad"));
148: len += DEC[hex[2]];
149: len = len << 4;
150: if (DEC[hex[3]] < 0)
151: throw new IllegalArgumentException(sm
152: .getString("hexUtil.bad"));
153: len += DEC[hex[3]];
154: return len;
155: }
156:
157: /**
158: * [Private] Convert the specified value (0 .. 15) to the corresponding
159: * hexadecimal digit.
160: *
161: * @param value Value to be converted
162: */
163: private static char convertDigit(int value) {
164:
165: value &= 0x0f;
166: if (value >= 10)
167: return ((char) (value - 10 + 'a'));
168: else
169: return ((char) (value + '0'));
170:
171: }
172:
173: }
|