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