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 }