| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /* |
| * Copyright (c) 2015-2017, The Linux Foundation. |
| */ |
| /* |
| * Copyright 2013 Giesecke & Devrient GmbH. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| |
| package com.android.se.internal; |
| |
| /** Utilities class. */ |
| public final class ByteArrayConverter { |
| |
| /** Override the default constructor to make it private. */ |
| private ByteArrayConverter() { |
| } |
| |
| /** |
| * Forms a FileViewProvider-compatible path String (i.e., transforms the byte array {0x3F, 0x00, |
| * 0x2F, 0xE2} into the String "3F00:2FE2"). |
| * |
| * @param rawPath The byte array containing the path component. |
| * @return A FileViewProvider-compatible path String. |
| * @throws IllegalArgumentException if the path has a bad coding. |
| */ |
| public static String byteArrayToPathString(byte[] rawPath) throws IllegalArgumentException { |
| if (rawPath.length % 2 != 0) { |
| throw new IllegalArgumentException("Invald path"); |
| } |
| |
| byte[] buffer = new byte[2]; |
| String path = ""; |
| for (int i = 0; i < rawPath.length; i += 2) { |
| System.arraycopy(rawPath, i, buffer, 0, 2); |
| String fid = byteArrayToHexString(buffer); |
| if (fid.equalsIgnoreCase("3F00")) { |
| // MF should not be included in path |
| continue; |
| } |
| path = path.concat(fid); |
| if (i != rawPath.length - 2) { |
| path = path.concat(":"); |
| } |
| } |
| return path; |
| } |
| |
| /** |
| * Forms an hex-encoded String of the specified byte array. |
| * |
| * @param array The byte array to be hex-encoded. |
| * @param offset The start position. |
| * @param length The number of bytes to be converted. |
| * @return A hex-encoded String of the specified byte array. |
| */ |
| public static String byteArrayToHexString(byte[] array, int offset, int length) { |
| if (array == null) { |
| return ""; |
| } |
| |
| StringBuilder sb = new StringBuilder(); |
| |
| for (int i = 0; i < length; i++) { |
| sb.append(String.format("%02x", array[offset + i] & 0xFF)); |
| } |
| |
| return sb.toString(); |
| } |
| |
| /** Converts the byte array to Hex String from a given offset */ |
| public static String byteArrayToHexString(byte[] array, int offset) { |
| StringBuffer s = new StringBuffer(); |
| for (int i = offset; i < array.length; i++) { |
| s.append(Integer.toHexString(0x100 + (array[i] & 0xff)).substring(1)); |
| } |
| return s.toString(); |
| } |
| |
| /** |
| * Forms an hex-encoded String of the specified byte array. |
| * |
| * @param byteArray The byte array to be hex-encoded. |
| * @return A hex-encoded String of the specified byte array. |
| */ |
| public static String byteArrayToHexString(byte[] byteArray) { |
| if (byteArray == null) { |
| return ""; |
| } |
| return byteArrayToHexString(byteArray, 0, byteArray.length); |
| } |
| |
| /** |
| * Forms a byte array containing the values of the hex-encoded string. |
| * |
| * @param str The hex-encoded string to be converted to byte-array. |
| * @param offset The start position. |
| * @param length The number of chars to be converted (must be multiple of 2). |
| * @return A byte array containing the values of the hex-encoded string. |
| */ |
| public static byte[] hexStringToByteArray(String str, int offset, int length) { |
| if (length % 2 != 0) { |
| throw new IllegalArgumentException("length must be multiple of 2"); |
| } |
| |
| str = str.toUpperCase(); |
| |
| byte[] outputBytes = new byte[str.length() / 2]; |
| |
| for (int i = 0; i < length; i += 2) { |
| char c1 = str.charAt(i + offset); |
| char c2 = str.charAt(i + 1 + offset); |
| if (!isHexChar(c1) || !isHexChar(c2)) { |
| throw new IllegalArgumentException("Invalid char found"); |
| } |
| |
| outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4) + Character.digit(c2, 16)); |
| } |
| |
| return outputBytes; |
| } |
| |
| /** |
| * Forms a byte array containing the values of the hex-encoded string. |
| * |
| * @param str The hex-encoded string to be converted to byte-array. |
| * @return A byte array containing the values of the hex-encoded string. |
| */ |
| public static byte[] hexStringToByteArray(String str) { |
| return hexStringToByteArray(str, 0, str.length()); |
| } |
| |
| /** |
| * Forms a byte array containing the specified integer value. |
| * |
| * @param value The integer value to be converted to byte array. |
| * @return A byte array containing the specified integer value. |
| */ |
| public static byte[] intToByteArray(int value) { |
| return new byte[]{ |
| (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value |
| }; |
| } |
| |
| /** |
| * Forms an integer from a byte array. |
| * |
| * @param byteArray The byte array from where to form the integer. |
| * @return The integer value representing the specified byte array. 0 if the array is empty. If |
| * the array is longer than 4 bytes, only bytes 0 to 3 will be considered. |
| */ |
| public static int byteArrayToInt(byte[] byteArray) { |
| switch (byteArray.length) { |
| case 0: |
| return 0; |
| case 1: |
| return (byteArray[0] & 0xFF); |
| case 2: |
| return (byteArray[0] & 0xFF) << 8 | (byteArray[1] & 0xFF); |
| case 3: |
| return (byteArray[0] & 0xFF) << 16 | (byteArray[1] & 0xFF) << 8 | (byteArray[2] |
| & 0xFF); |
| default: |
| return (byteArray[0] & 0xFF) << 24 |
| | (byteArray[1] & 0xFF) << 16 |
| | (byteArray[2] & 0xFF) << 8 |
| | byteArray[3] & 0xFF; |
| } |
| } |
| |
| /** |
| * Decides whether a char is a valid hex value or not. |
| * |
| * @param c The char to be evaluated. |
| * @return true if the specified char is a valid hex value, false otherwise. |
| */ |
| public static boolean isHexChar(char c) { |
| if (Character.isLowerCase(c)) { |
| c = Character.toUpperCase(c); |
| } |
| |
| return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'); |
| } |
| } |