1/* 2 * Copyright (C) 2009 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 */ 16package com.android.providers.contacts.util; 17 18/** 19 * Basic hex operations: from byte array to string and vice versa. 20 * 21 * TODO: move to the framework and consider implementing as native code. 22 */ 23public class Hex { 24 25 private static final char[] HEX_DIGITS = new char[]{ 26 '0', '1', '2', '3', '4', '5', '6', '7', 27 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 28 }; 29 30 private static final char[] FIRST_CHAR = new char[256]; 31 private static final char[] SECOND_CHAR = new char[256]; 32 static { 33 for (int i = 0; i < 256; i++) { 34 FIRST_CHAR[i] = HEX_DIGITS[(i >> 4) & 0xF]; 35 SECOND_CHAR[i] = HEX_DIGITS[i & 0xF]; 36 } 37 } 38 39 private static final byte[] DIGITS = new byte['f'+1]; 40 static { 41 for (int i = 0; i <= 'F'; i++) { 42 DIGITS[i] = -1; 43 } 44 for (byte i = 0; i < 10; i++) { 45 DIGITS['0' + i] = i; 46 } 47 for (byte i = 0; i < 6; i++) { 48 DIGITS['A' + i] = (byte)(10 + i); 49 DIGITS['a' + i] = (byte)(10 + i); 50 } 51 } 52 53 /** 54 * Quickly converts a byte array to a hexadecimal string representation. 55 * 56 * @param array byte array, possibly zero-terminated. 57 */ 58 public static String encodeHex(byte[] array, boolean zeroTerminated) { 59 char[] cArray = new char[array.length * 2]; 60 61 int j = 0; 62 for (int i = 0; i < array.length; i++) { 63 int index = array[i] & 0xFF; 64 if (zeroTerminated && index == 0 && i == array.length-1) { 65 break; 66 } 67 68 cArray[j++] = FIRST_CHAR[index]; 69 cArray[j++] = SECOND_CHAR[index]; 70 } 71 72 return new String(cArray, 0, j); 73 } 74 75 /** 76 * Quickly converts a hexadecimal string to a byte array. 77 * 78 * TODO Use checked exceptions instead of RuntimeException. Apparently normalized names *may* 79 * contain non-hex strings and we want to make sure the provider won't crash even with such 80 * input. 81 */ 82 public static byte[] decodeHex(String hexString) { 83 int length = hexString.length(); 84 85 if ((length & 0x01) != 0) { 86 throw new IllegalArgumentException("Odd number of characters: " + hexString); 87 } 88 89 boolean badHex = false; 90 byte[] out = new byte[length >> 1]; 91 for (int i = 0, j = 0; j < length; i++) { 92 int c1 = hexString.charAt(j++); 93 if (c1 > 'f') { 94 badHex = true; 95 break; 96 } 97 98 final byte d1 = DIGITS[c1]; 99 if (d1 == -1) { 100 badHex = true; 101 break; 102 } 103 104 int c2 = hexString.charAt(j++); 105 if (c2 > 'f') { 106 badHex = true; 107 break; 108 } 109 110 final byte d2 = DIGITS[c2]; 111 if (d2 == -1) { 112 badHex = true; 113 break; 114 } 115 116 out[i] = (byte) (d1 << 4 | d2); 117 } 118 119 if (badHex) { 120 throw new IllegalArgumentException("Invalid hexadecimal digit: " + hexString); 121 } 122 123 return out; 124 } 125} 126