Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Hex |
|
| 2.0;2 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | package org.apache.shiro.codec; | |
20 | ||
21 | /** | |
22 | * <a href="http://en.wikipedia.org/wiki/Hexadecimal">Hexadecimal</a> encoder and decoder. | |
23 | * <p/> | |
24 | * This class was borrowed from Apache Commons Codec SVN repository (rev. {@code 560660}) with modifications | |
25 | * to enable Hex conversion without a full dependency on Commons Codec. We didn't want to reinvent the wheel of | |
26 | * great work they've done, but also didn't want to force every Shiro user to depend on the commons-codec.jar | |
27 | * <p/> | |
28 | * As per the Apache 2.0 license, the original copyright notice and all author and copyright information have | |
29 | * remained in tact. | |
30 | * | |
31 | * @see <a href="http://en.wikipedia.org/wiki/Hexadecimal">Wikipedia: Hexadecimal</a> | |
32 | * @since 0.9 | |
33 | */ | |
34 | 0 | public class Hex { |
35 | ||
36 | /** | |
37 | * Used to build output as Hex | |
38 | */ | |
39 | 1 | private static final char[] DIGITS = { |
40 | '0', '1', '2', '3', '4', '5', '6', '7', | |
41 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' | |
42 | }; | |
43 | ||
44 | /** | |
45 | * Encodes the specifed byte array to a character array and then returns that character array | |
46 | * as a String. | |
47 | * | |
48 | * @param bytes the byte array to Hex-encode. | |
49 | * @return A String representation of the resultant hex-encoded char array. | |
50 | */ | |
51 | public static String encodeToString(byte[] bytes) { | |
52 | 17 | char[] encodedChars = encode(bytes); |
53 | 17 | return new String(encodedChars); |
54 | } | |
55 | ||
56 | /** | |
57 | * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order. | |
58 | * The returned array will be double the length of the passed array, as it takes two characters to represent any | |
59 | * given byte. | |
60 | * | |
61 | * @param data byte[] to convert to Hex characters | |
62 | * @return A char[] containing hexidecimal characters | |
63 | */ | |
64 | public static char[] encode(byte[] data) { | |
65 | ||
66 | 17 | int l = data.length; |
67 | ||
68 | 17 | char[] out = new char[l << 1]; |
69 | ||
70 | // two characters form the hex value. | |
71 | 530 | for (int i = 0, j = 0; i < l; i++) { |
72 | 513 | out[j++] = DIGITS[(0xF0 & data[i]) >>> 4]; |
73 | 513 | out[j++] = DIGITS[0x0F & data[i]]; |
74 | } | |
75 | ||
76 | 17 | return out; |
77 | } | |
78 | ||
79 | /** | |
80 | * Converts an array of character bytes representing hexidecimal values into an | |
81 | * array of bytes of those same values. The returned array will be half the | |
82 | * length of the passed array, as it takes two characters to represent any | |
83 | * given byte. An exception is thrown if the passed char array has an odd | |
84 | * number of elements. | |
85 | * | |
86 | * @param array An array of character bytes containing hexidecimal digits | |
87 | * @return A byte array containing binary data decoded from | |
88 | * the supplied byte array (representing characters). | |
89 | * @throws IllegalArgumentException Thrown if an odd number of characters is supplied | |
90 | * to this function | |
91 | * @see #decode(char[]) | |
92 | */ | |
93 | public static byte[] decode(byte[] array) throws IllegalArgumentException { | |
94 | 11 | String s = CodecSupport.toString(array); |
95 | 11 | return decode(s); |
96 | } | |
97 | ||
98 | /** | |
99 | * Converts the specified Hex-encoded String into a raw byte array. This is a | |
100 | * convenience method that merely delegates to {@link #decode(char[])} using the | |
101 | * argument's hex.toCharArray() value. | |
102 | * | |
103 | * @param hex a Hex-encoded String. | |
104 | * @return A byte array containing binary data decoded from the supplied String's char array. | |
105 | */ | |
106 | public static byte[] decode(String hex) { | |
107 | 12 | return decode(hex.toCharArray()); |
108 | } | |
109 | ||
110 | /** | |
111 | * Converts an array of characters representing hexidecimal values into an | |
112 | * array of bytes of those same values. The returned array will be half the | |
113 | * length of the passed array, as it takes two characters to represent any | |
114 | * given byte. An exception is thrown if the passed char array has an odd | |
115 | * number of elements. | |
116 | * | |
117 | * @param data An array of characters containing hexidecimal digits | |
118 | * @return A byte array containing binary data decoded from | |
119 | * the supplied char array. | |
120 | * @throws IllegalArgumentException if an odd number or illegal of characters | |
121 | * is supplied | |
122 | */ | |
123 | public static byte[] decode(char[] data) throws IllegalArgumentException { | |
124 | ||
125 | 12 | int len = data.length; |
126 | ||
127 | 12 | if ((len & 0x01) != 0) { |
128 | 0 | throw new IllegalArgumentException("Odd number of characters."); |
129 | } | |
130 | ||
131 | 12 | byte[] out = new byte[len >> 1]; |
132 | ||
133 | // two characters form the hex value. | |
134 | 377 | for (int i = 0, j = 0; j < len; i++) { |
135 | 365 | int f = toDigit(data[j], j) << 4; |
136 | 365 | j++; |
137 | 365 | f = f | toDigit(data[j], j); |
138 | 365 | j++; |
139 | 365 | out[i] = (byte) (f & 0xFF); |
140 | } | |
141 | ||
142 | 12 | return out; |
143 | } | |
144 | ||
145 | /** | |
146 | * Converts a hexadecimal character to an integer. | |
147 | * | |
148 | * @param ch A character to convert to an integer digit | |
149 | * @param index The index of the character in the source | |
150 | * @return An integer | |
151 | * @throws IllegalArgumentException if ch is an illegal hex character | |
152 | */ | |
153 | protected static int toDigit(char ch, int index) throws IllegalArgumentException { | |
154 | 730 | int digit = Character.digit(ch, 16); |
155 | 730 | if (digit == -1) { |
156 | 0 | throw new IllegalArgumentException("Illegal hexadecimal charcter " + ch + " at index " + index); |
157 | } | |
158 | 730 | return digit; |
159 | } | |
160 | ||
161 | ||
162 | } |