ByteStringUtils.java revision f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787
1d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen/* 2d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * Copyright (C) 2017 The Android Open Source Project 3d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * 4d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * Licensed under the Apache License, Version 2.0 (the "License"); 5d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * you may not use this file except in compliance with the License. 6d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * You may obtain a copy of the License at 7d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * 8d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * http://www.apache.org/licenses/LICENSE-2.0 9d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * 10d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * Unless required by applicable law or agreed to in writing, software 11d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * distributed under the License is distributed on an "AS IS" BASIS, 12d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * See the License for the specific language governing permissions and 14d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * limitations under the License. 15d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen */ 16d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 17d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjenpackage android.util; 18d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 19d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen/** 20d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * A utility class for common byte array to hex string operations and vise versa. 21d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * 22d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen * @hide 23d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen */ 24d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjenpublic final class ByteStringUtils { 25f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman private static final char[] HEX_LOWERCASE_ARRAY = "0123456789abcdef".toCharArray(); 26f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman private static final char[] HEX_UPPERCASE_ARRAY = "0123456789ABCDEF".toCharArray(); 27d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 28f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman private ByteStringUtils() { 29d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen /* hide constructor */ 30d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen } 31d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 32f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman /** 33f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * Returns the hex encoded string representation of bytes. 34f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * @param bytes Byte array to encode. 35f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * @return Hex encoded string representation of bytes. 36f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman */ 37f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman public static String toHexString(byte[] bytes) { 38f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman if (bytes == null || bytes.length == 0 || bytes.length % 2 != 0) { 39f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return null; 40f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 41d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 42f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final int byteLength = bytes.length; 43f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final int charCount = 2 * byteLength; 44f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final char[] chars = new char[charCount]; 45d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 46f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman for (int i = 0; i < byteLength; i++) { 47f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final int byteHex = bytes[i] & 0xFF; 48f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman chars[i * 2] = HEX_UPPERCASE_ARRAY[byteHex >>> 4]; 49f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman chars[i * 2 + 1] = HEX_UPPERCASE_ARRAY[byteHex & 0x0F]; 50f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 51f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return new String(chars); 52d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen } 53d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 54f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman /** 55f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * Returns the decoded byte array representation of str. 56f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * @param str Hex encoded string to decode. 57f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman * @return Decoded byte array representation of str. 58f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman */ 59f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman public static byte[] fromHexToByteArray(String str) { 60f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman if (str == null || str.length() == 0 || str.length() % 2 != 0) { 61f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return null; 62f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 63f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman 64f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final char[] chars = str.toCharArray(); 65f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final int charLength = chars.length; 66f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman final byte[] bytes = new byte[charLength / 2]; 67d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 68f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman for (int i = 0; i < bytes.length; i++) { 69f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman bytes[i] = 70f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman (byte) (((getIndex(chars[i * 2]) << 4) & 0xF0) 71f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman | (getIndex(chars[i * 2 + 1]) & 0x0F)); 72f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 73f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return bytes; 74d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen } 75d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen 76f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman private static int getIndex(char c) { 77f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman for (int i = 0; i < HEX_UPPERCASE_ARRAY.length; i++) { 78f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman if (HEX_UPPERCASE_ARRAY[i] == c || HEX_LOWERCASE_ARRAY[i] == c) { 79f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return i; 80f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 81f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman } 82f27d080d1aa101fa4407d2b3ec6b4d1a4a0e5787Dan Cashman return -1; 83d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen } 84d891f01d96cbaa3b1329c3d476084f3fedb30a89Mark Rathjen} 85