Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /*
     17  * Copyright (c) 2015-2017, The Linux Foundation.
     18  */
     19 /*
     20  * Copyright 2013 Giesecke & Devrient GmbH.
     21  *
     22  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
     23  * use this file except in compliance with the License. You may obtain a copy of
     24  * the License at
     25  *
     26  * http://www.apache.org/licenses/LICENSE-2.0
     27  *
     28  * Unless required by applicable law or agreed to in writing, software
     29  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     30  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     31  * License for the specific language governing permissions and limitations under
     32  * the License.
     33  */
     34 
     35 package com.android.se.internal;
     36 
     37 /** Utilities class. */
     38 public final class ByteArrayConverter {
     39 
     40     /** Override the default constructor to make it private. */
     41     private ByteArrayConverter() {
     42     }
     43 
     44     /**
     45      * Forms a FileViewProvider-compatible path String (i.e., transforms the byte array {0x3F, 0x00,
     46      * 0x2F, 0xE2} into the String "3F00:2FE2").
     47      *
     48      * @param rawPath The byte array containing the path component.
     49      * @return A FileViewProvider-compatible path String.
     50      * @throws IllegalArgumentException if the path has a bad coding.
     51      */
     52     public static String byteArrayToPathString(byte[] rawPath) throws IllegalArgumentException {
     53         if (rawPath.length % 2 != 0) {
     54             throw new IllegalArgumentException("Invald path");
     55         }
     56 
     57         byte[] buffer = new byte[2];
     58         String path = "";
     59         for (int i = 0; i < rawPath.length; i += 2) {
     60             System.arraycopy(rawPath, i, buffer, 0, 2);
     61             String fid = byteArrayToHexString(buffer);
     62             if (fid.equalsIgnoreCase("3F00")) {
     63                 // MF should not be included in path
     64                 continue;
     65             }
     66             path = path.concat(fid);
     67             if (i != rawPath.length - 2) {
     68                 path = path.concat(":");
     69             }
     70         }
     71         return path;
     72     }
     73 
     74     /**
     75      * Forms an hex-encoded String of the specified byte array.
     76      *
     77      * @param array  The byte array to be hex-encoded.
     78      * @param offset The start position.
     79      * @param length The number of bytes to be converted.
     80      * @return A hex-encoded String of the specified byte array.
     81      */
     82     public static String byteArrayToHexString(byte[] array, int offset, int length) {
     83         if (array == null) {
     84             return "";
     85         }
     86 
     87         StringBuilder sb = new StringBuilder();
     88 
     89         for (int i = 0; i < length; i++) {
     90             sb.append(String.format("%02x", array[offset + i] & 0xFF));
     91         }
     92 
     93         return sb.toString();
     94     }
     95 
     96     /** Converts the byte array to Hex String from a given offset */
     97     public static String byteArrayToHexString(byte[] array, int offset) {
     98         StringBuffer s = new StringBuffer();
     99         for (int i = offset; i < array.length; i++) {
    100             s.append(Integer.toHexString(0x100 + (array[i] & 0xff)).substring(1));
    101         }
    102         return s.toString();
    103     }
    104 
    105     /**
    106      * Forms an hex-encoded String of the specified byte array.
    107      *
    108      * @param byteArray The byte array to be hex-encoded.
    109      * @return A hex-encoded String of the specified byte array.
    110      */
    111     public static String byteArrayToHexString(byte[] byteArray) {
    112         if (byteArray == null) {
    113             return "";
    114         }
    115         return byteArrayToHexString(byteArray, 0, byteArray.length);
    116     }
    117 
    118     /**
    119      * Forms a byte array containing the values of the hex-encoded string.
    120      *
    121      * @param str    The hex-encoded string to be converted to byte-array.
    122      * @param offset The start position.
    123      * @param length The number of chars to be converted (must be multiple of 2).
    124      * @return A byte array containing the values of the hex-encoded string.
    125      */
    126     public static byte[] hexStringToByteArray(String str, int offset, int length) {
    127         if (length % 2 != 0) {
    128             throw new IllegalArgumentException("length must be multiple of 2");
    129         }
    130 
    131         str = str.toUpperCase();
    132 
    133         byte[] outputBytes = new byte[str.length() / 2];
    134 
    135         for (int i = 0; i < length; i += 2) {
    136             char c1 = str.charAt(i + offset);
    137             char c2 = str.charAt(i + 1 + offset);
    138             if (!isHexChar(c1) || !isHexChar(c2)) {
    139                 throw new IllegalArgumentException("Invalid char found");
    140             }
    141 
    142             outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4) + Character.digit(c2, 16));
    143         }
    144 
    145         return outputBytes;
    146     }
    147 
    148     /**
    149      * Forms a byte array containing the values of the hex-encoded string.
    150      *
    151      * @param str The hex-encoded string to be converted to byte-array.
    152      * @return A byte array containing the values of the hex-encoded string.
    153      */
    154     public static byte[] hexStringToByteArray(String str) {
    155         return hexStringToByteArray(str, 0, str.length());
    156     }
    157 
    158     /**
    159      * Forms a byte array containing the specified integer value.
    160      *
    161      * @param value The integer value to be converted to byte array.
    162      * @return A byte array containing the specified integer value.
    163      */
    164     public static byte[] intToByteArray(int value) {
    165         return new byte[]{
    166                 (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value
    167         };
    168     }
    169 
    170     /**
    171      * Forms an integer from a byte array.
    172      *
    173      * @param byteArray The byte array from where to form the integer.
    174      * @return The integer value representing the specified byte array. 0 if the array is empty. If
    175      * the array is longer than 4 bytes, only bytes 0 to 3 will be considered.
    176      */
    177     public static int byteArrayToInt(byte[] byteArray) {
    178         switch (byteArray.length) {
    179             case 0:
    180                 return 0;
    181             case 1:
    182                 return (byteArray[0] & 0xFF);
    183             case 2:
    184                 return (byteArray[0] & 0xFF) << 8 | (byteArray[1] & 0xFF);
    185             case 3:
    186                 return (byteArray[0] & 0xFF) << 16 | (byteArray[1] & 0xFF) << 8 | (byteArray[2]
    187                         & 0xFF);
    188             default:
    189                 return (byteArray[0] & 0xFF) << 24
    190                         | (byteArray[1] & 0xFF) << 16
    191                         | (byteArray[2] & 0xFF) << 8
    192                         | byteArray[3] & 0xFF;
    193         }
    194     }
    195 
    196     /**
    197      * Decides whether a char is a valid hex value or not.
    198      *
    199      * @param c The char to be evaluated.
    200      * @return true if the specified char is a valid hex value, false otherwise.
    201      */
    202     public static boolean isHexChar(char c) {
    203         if (Character.isLowerCase(c)) {
    204             c = Character.toUpperCase(c);
    205         }
    206 
    207         return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
    208     }
    209 }
    210