001/* 002 * Copyright (c) 2011-2017 Nexmo Inc 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy 005 * of this software and associated documentation files (the "Software"), to deal 006 * in the Software without restriction, including without limitation the rights 007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 008 * copies of the Software, and to permit persons to whom the Software is 009 * furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 020 * THE SOFTWARE. 021 */ 022package com.nexmo.client.sms; 023 024import com.nexmo.client.NexmoUnexpectedException; 025 026import java.io.UnsupportedEncodingException; 027 028 029/** 030 * Static helper methods for working with hex values. 031 * 032 * @author Paul Cook 033 */ 034public class HexUtil { 035 036 private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; 037 038 private HexUtil() { 039 // This class may not be instantiated. 040 } 041 042 /** 043 * translate a byte array of raw data into a String with a hex representation of that data 044 * 045 * @param bytes raw binary data 046 * 047 * @return String Hex representation of the raw data 048 */ 049 public static String bytesToHex(byte[] bytes) { 050 return bytesToHex(bytes, null); 051 } 052 053 /** 054 * translate a byte array of raw data into a String with a hex representation of that data. 055 * Each octet will be separated with a specific separator. 056 * 057 * @param bytes raw binary data 058 * @param separator This string will be injected into the output in between each octet in the stream 059 * 060 * @return String Hex representation of the raw data with each octet separated by 'separator' 061 */ 062 public static String bytesToHex(byte[] bytes, String separator) { 063 StringBuilder tmpBuffer = new StringBuilder(); 064 if (bytes != null) { 065 for (byte c : bytes) { 066 int b = c; 067 if (b < 0) 068 b += 256; 069 if (separator != null) 070 tmpBuffer.append(separator); 071 tmpBuffer.append(HEX_CHARS[(b & 0xf0) / 0x10]); // note, this benchmarks faster than using >> 4 072 tmpBuffer.append(HEX_CHARS[b & 0x0f]); 073 } 074 } 075 return tmpBuffer.toString(); 076 } 077 078 /** 079 * Converts a Hex encoded String into a byte vector. 080 * 081 * @param str The String to be encoded. 082 * 083 * @return A byte vector representing the String. 084 */ 085 public static byte[] hexToBytes(String str) { 086 if (str == null) 087 return null; 088 byte[] hexChars; 089 try { 090 hexChars = str.toUpperCase().getBytes("ISO_8859-1"); 091 } catch (UnsupportedEncodingException e) { 092 throw new NexmoUnexpectedException("ISO_8859_1 is an unsupported encoding in this JVM"); 093 } 094 int size = hexChars.length; 095 byte[] bytes = new byte[size / 2]; 096 int first; 097 int second; 098 099 int rIndex = 0; 100 // Convert to bytes. 101 for (int i = 0; i+1 <size; i= i + 2) { 102 103 // Convert first 104 first = hexChars[i]; 105 if (first < 58) 106 first = ((first - 48) * 16); // 0 - 9 107 else 108 first = ((first - 55) * 16); // A - F 109 110 // Convert second 111 second = hexChars[i + 1]; 112 if (second < 58) 113 second = second - 48; // 0 - 9 114 else 115 second = second - 55; // A - F 116 117 //Value must be between -128 and 127 118 int total = (first + second); 119 if (total > 127) 120 total = (256 + total); 121 122 bytes[rIndex] = (byte) total; 123 rIndex++; 124 } 125 return bytes; 126 } 127 128}