1 /* 2 * Copyright 2015-2018 HuntLabs.cn 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 module hunt.sql.util.HexBin; 17 import std.conv; 18 /** 19 * format validation This class encodes/decodes hexadecimal data 20 * 21 */ 22 public class HexBin { 23 24 private enum int BASE_LENGTH = 128; 25 private enum int LOOKUP_LENGTH = 16; 26 private __gshared byte[] HEX_NUMBER_TABLE; 27 private __gshared char[] UPPER_CHARS ; 28 private __gshared char[] LOWER_CHARS ; 29 30 shared static this() { 31 HEX_NUMBER_TABLE = new byte[BASE_LENGTH]; 32 UPPER_CHARS = new char[LOOKUP_LENGTH]; 33 LOWER_CHARS = new char[LOOKUP_LENGTH]; 34 35 for (int i = 0; i < BASE_LENGTH; i++) { 36 HEX_NUMBER_TABLE[i] = -1; 37 } 38 for (int i = '9'; i >= '0'; i--) { 39 HEX_NUMBER_TABLE[i] = cast(byte) (i - '0'); 40 } 41 for (int i = 'F'; i >= 'A'; i--) { 42 HEX_NUMBER_TABLE[i] = cast(byte) (i - 'A' + 10); 43 } 44 for (int i = 'f'; i >= 'a'; i--) { 45 HEX_NUMBER_TABLE[i] = cast(byte) (i - 'a' + 10); 46 } 47 48 for (int i = 0; i < 10; i++) { 49 UPPER_CHARS[i] = cast(char) ('0' + i); 50 LOWER_CHARS[i] = cast(char) ('0' + i); 51 } 52 for (int i = 10; i <= 15; i++) { 53 UPPER_CHARS[i] = cast(char) ('A' + i - 10); 54 LOWER_CHARS[i] = cast(char) ('a' + i - 10); 55 } 56 } 57 58 public static string encode(byte[] bytes) { 59 return encode(bytes, true); 60 } 61 62 public static string encode(byte[] bytes, bool upperCase) { 63 64 if (bytes is null) { 65 return null; 66 } 67 68 char[] chars = upperCase ? UPPER_CHARS : LOWER_CHARS; 69 70 char[] hex = new char[bytes.length * 2]; 71 for (int i = 0; i < bytes.length; i++) { 72 int b = bytes[i] & 0xFF; 73 hex[i * 2] = chars[b >> 4]; 74 hex[i * 2 + 1] = chars[b & 0xf]; 75 } 76 return to!string(hex); 77 } 78 79 /** 80 * Decode hex string to a byte array 81 * 82 * @param encoded encoded string 83 * @return return array of byte to encode 84 */ 85 static public byte[] decode(string encoded) { 86 if (encoded is null) { 87 return null; 88 } 89 90 int lengthData = cast(int)(encoded.length); 91 if (lengthData % 2 != 0) { 92 return null; 93 } 94 95 char[] binaryData = /* encoded.toCharArray() */ to!(char[])(encoded); 96 int lengthDecode = lengthData / 2; 97 byte[] decodedData = new byte[lengthDecode]; 98 byte temp1, temp2; 99 char tempChar; 100 for (int i = 0; i < lengthDecode; i++) { 101 tempChar = binaryData[i * 2]; 102 temp1 = (tempChar < BASE_LENGTH) ? HEX_NUMBER_TABLE[tempChar] : -1; 103 if (temp1 == -1) { 104 return null; 105 } 106 tempChar = binaryData[i * 2 + 1]; 107 temp2 = (tempChar < BASE_LENGTH) ? HEX_NUMBER_TABLE[tempChar] : -1; 108 if (temp2 == -1) { 109 return null; 110 } 111 decodedData[i] = cast(byte) ((temp1 << 4) | temp2); 112 } 113 return decodedData; 114 } 115 }