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 public static byte[] decodeHex(final CharSequence data) { 70 71 final int len = data.length(); 72 73 if ((len & 0x01) != 0) { 74 throw new IllegalArgumentException("Odd number of characters."); 75 } 76 77 final byte[] out = new byte[len >> 1]; 78 79 // Two characters form the hex value 80 for (int j = 0; j < len; j += 2) { 81 final int f = (toDigit(data, j) << 4) | 82 toDigit(data, j + 1); 83 out[j / 2] = (byte) f; 84 } 85 86 return out; 87 } 88 89 /** 90 * Converts a hexadecimal character to an integer. 91 * 92 * @param data An array of characters containing hexadecimal digits 93 * @param index The index of the character in the source 94 * @return An integer 95 * @throws IllegalArgumentException Thrown if ch is an illegal hex character 96 */ 97 protected static int toDigit(final CharSequence data, final int index) { 98 final char ch = data.charAt(index); 99 final int digit = Character.digit(ch, 16); 100 if (digit == -1) { 101 throw new IllegalArgumentException("Illegal hexadecimal character " + ch + 102 " at index " + index); 103 } 104 return digit; 105 } 106 }