1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.rng.examples.stress;
18
19 /**
20 * Encodes and decodes bytes as hexadecimal characters.
21 *
22 * <p>Adapted from commons-codec.</p>
23 */
24 final class Hex {
25 /**
26 * Used to build 4-bit numbers as Hex.
27 */
28 private static final char[] HEX_DIGITS = {
29 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
30 };
31
32 /** No public construction. */
33 private Hex() {}
34
35 /**
36 * Converts an array of bytes into an array of characters representing the hexadecimal
37 * values of each byte in order. The returned array will be double the length of the
38 * passed array, as it takes two characters to represent any given byte.
39 *
40 * <p>This can be used to encode byte array seeds into a text representation.</p>
41 *
42 * @param data A byte[] to convert to Hex characters
43 * @return A char[] containing the lower-case Hex representation
44 */
45 static char[] encodeHex(final byte[] data) {
46 final int l = data.length;
47 final char[] out = new char[l << 1];
48 // Two characters form the hex value
49 for (int i = 0; i < l; i++) {
50 // Upper 4-bits
51 out[2 * i] = HEX_DIGITS[(0xf0 & data[i]) >>> 4];
52 // Lower 4-bits
53 out[2 * i + 1] = HEX_DIGITS[ 0x0f & data[i]];
54 }
55 return out;
56 }
57
58 /**
59 * Converts an array of characters representing hexadecimal values into an array
60 * of bytes of those same values. The returned array will be half the length of
61 * the passed array, as it takes two characters to represent any given byte. An
62 * exception is thrown if the passed char array has an odd number of elements.
63 *
64 * @param data An array of characters containing hexadecimal digits
65 * @return A byte array containing binary data decoded from the supplied char array.
66 * @throws IllegalArgumentException Thrown if an odd number or illegal of
67 * characters is supplied
68 */
69 static byte[] decodeHex(final CharSequence data) {
70 final int len = data.length();
71
72 if ((len & 0x01) != 0) {
73 throw new IllegalArgumentException("Odd number of characters.");
74 }
75
76 final byte[] out = new byte[len >> 1];
77
78 // Two characters form the hex value
79 for (int j = 0; j < len; j += 2) {
80 final int f = (toDigit(data, j) << 4) |
81 toDigit(data, j + 1);
82 out[j / 2] = (byte) f;
83 }
84
85 return out;
86 }
87
88 /**
89 * Converts a hexadecimal character to an integer.
90 *
91 * @param data An array of characters containing hexadecimal digits
92 * @param index The index of the character in the source
93 * @return An integer
94 * @throws IllegalArgumentException Thrown if ch is an illegal hex character
95 */
96 private static int toDigit(final CharSequence data, final int index) {
97 final char ch = data.charAt(index);
98 final int digit = Character.digit(ch, 16);
99 if (digit == -1) {
100 throw new IllegalArgumentException("Illegal hexadecimal character " + ch +
101 " at index " + index);
102 }
103 return digit;
104 }
105 }