001/** 002 * Copyright 2017, Digi International Inc. 003 * 004 * This Source Code Form is subject to the terms of the Mozilla Public 005 * License, v. 2.0. If a copy of the MPL was not distributed with this 006 * file, you can obtain one at http://mozilla.org/MPL/2.0/. 007 * 008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 015 */ 016package com.digi.xbee.api.utils; 017 018/** 019 * Utility class containing methods to work with hexadecimal values and several 020 * data type conversions. 021 */ 022public class HexUtils { 023 024 // Constants. 025 private static final String HEXES = "0123456789ABCDEF"; 026 private static final String HEX_HEADER = "0x"; 027 028 /** 029 * Converts the given byte array into an hex string. 030 * 031 * @param value Byte array to convert to hex string. 032 * 033 * @return Converted byte array to hex string. 034 * 035 * @throws NullPointerException if {@code value == null}. 036 * 037 * @see #hexStringToByteArray(String) 038 */ 039 public static String byteArrayToHexString(byte[] value) { 040 if (value == null ) 041 throw new NullPointerException("Value to convert cannot be null."); 042 043 final StringBuilder hex = new StringBuilder(2 * value.length ); 044 for (final byte b : value) { 045 hex.append(HEXES.charAt((b & 0xF0) >> 4)) 046 .append(HEXES.charAt((b & 0x0F))); 047 } 048 return hex.toString(); 049 } 050 051 /** 052 * Converts the given byte into an hex string. 053 * 054 * @param value Byte to convert to hex string. 055 * 056 * @return Converted byte to hex string. 057 */ 058 public static String byteToHexString(byte value) { 059 final StringBuilder hex = new StringBuilder(2); 060 byte b = value; 061 hex.append(HEXES.charAt((b & 0xF0) >> 4)) 062 .append(HEXES.charAt((b & 0x0F))); 063 return hex.toString(); 064 } 065 066 /** 067 * Converts the given hex string into a byte array. 068 * 069 * @param value Hex string to convert to byte array. 070 * 071 * @return Byte array of the given hex string. 072 * 073 * @throws NullPointerException if {@code value == null}. 074 * 075 * @see #byteArrayToHexString(byte[]) 076 */ 077 public static byte[] hexStringToByteArray(String value) { 078 if (value == null) 079 throw new NullPointerException("Value to convert cannot be null."); 080 081 value = value.trim(); 082 if (value.startsWith(HEX_HEADER)) 083 value = value.substring((HEX_HEADER).length()); 084 int len = value.length(); 085 if (len % 2 != 0) { 086 value = "0" + value; 087 len = value.length(); 088 } 089 byte[] data = new byte[len / 2]; 090 for (int i = 0; i < len; i += 2) { 091 data[i / 2] = (byte) ((Character.digit(value.charAt(i), 16) << 4) 092 + Character.digit(value.charAt(i+1), 16)); 093 } 094 return data; 095 } 096 097 /** 098 * Checks whether the given parameter is a string or a numeric value. 099 * 100 * @param parameter Parameter to check. 101 * 102 * @return {@code true} if the given parameter is a string, 103 * {@code false} otherwise. 104 * 105 * @throws NullPointerException if {@code parameter == null}. 106 */ 107 public static boolean containsLetters(String parameter) { 108 if (parameter == null) 109 throw new NullPointerException("Parameter cannot be null."); 110 111 byte[] byteArray = parameter.getBytes(); 112 for (int i = 0; i < byteArray.length; i++){ 113 if (!((byteArray[i] >= '0') && (byteArray[i] <= '9'))) 114 return true; 115 } 116 return false; 117 } 118 119 /** 120 * Converts the given integer into an hexadecimal string. 121 * 122 * @param value The integer value to convert to hexadecimal string. 123 * @param minBytes The minimum number of bytes to be represented. 124 * 125 * @return The integer value as hexadecimal string. 126 * 127 * @throws IllegalArgumentException if {@code minBytes <= 0}. 128 */ 129 public static String integerToHexString(int value, int minBytes) { 130 if (minBytes <= 0) 131 throw new IllegalArgumentException("Minimum number of bytes must be greater than 0."); 132 133 String f = String.format("%%0%dX", minBytes*2); 134 return String.format(f, value); 135 } 136 137 /** 138 * Converts the given hexadecimal string to a pretty format by splitting the 139 * content byte by byte. 140 * 141 * @param hexString The hexadecimal string to convert. 142 * 143 * @return The hexadecimal string with pretty format. 144 * 145 * @throws NullPointerException if {@code hexString == null}. 146 * 147 * @see #prettyHexString(byte[]) 148 */ 149 public static String prettyHexString(String hexString) { 150 if (hexString == null) 151 throw new NullPointerException("Hexadecimal string cannot be null."); 152 153 String copy = hexString.toUpperCase(); 154 for (final char c : copy.toCharArray()) { 155 if (!HEXES.contains(""+c)) 156 throw new IllegalArgumentException("Given string cannot contain non-hexadecimal characters."); 157 } 158 159 String prettyHexString = ""; 160 if (copy.length() % 2 != 0) 161 copy = "0" + copy; 162 int iterations = copy.length() / 2; 163 for (int i = 0; i < iterations; i++) 164 prettyHexString += copy.substring(2 * i, 2 * i + 2) + " "; 165 return prettyHexString.trim(); 166 } 167 168 /** 169 * Converts the given byte array into an hex string and retrieves it 170 * in pretty format by splitting the content byte by byte. 171 * 172 * @param value The byte array to convert to pretty hex string. 173 * 174 * @return The hexadecimal pretty string. 175 * 176 * @throws NullPointerException if {@code value == null}. 177 * 178 * @see #prettyHexString(String) 179 */ 180 public static String prettyHexString(byte[] value) { 181 return prettyHexString(byteArrayToHexString(value)); 182 } 183}