001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.crypt; 020 021public final class BinConverter { 022 023 /** 024 * gets bytes from an array into a long 025 * @param buffer where to get the bytes 026 * @param nStartIndex index from where to read the data 027 * @return the 64bit integer 028 */ 029 public static long byteArrayToLong(byte[] buffer,int nStartIndex) { 030 031 return (((long)buffer[nStartIndex]) << 56) | 032 ((buffer[nStartIndex + 1] & 0x0ffL) << 48) | 033 ((buffer[nStartIndex + 2] & 0x0ffL) << 40) | 034 ((buffer[nStartIndex + 3] & 0x0ffL) << 32) | 035 ((buffer[nStartIndex + 4] & 0x0ffL) << 24) | 036 ((buffer[nStartIndex + 5] & 0x0ffL) << 16) | 037 ((buffer[nStartIndex + 6] & 0x0ffL) << 8) | 038 ((long)buffer[nStartIndex + 7] & 0x0ff); 039 040 } 041 042 /** 043 * converts a long o bytes which are put into a given array 044 * @param lValue the 64bit integer to convert 045 * @param buffer the target buffer 046 * @param nStartIndex where to place the bytes in the buffer 047 */ 048 public static void longToByteArray(long lValue,byte[] buffer,int nStartIndex) { 049 buffer[nStartIndex] = (byte) (lValue >>> 56); 050 buffer[nStartIndex + 1] = (byte) ((lValue >>> 48) & 0x0ff); 051 buffer[nStartIndex + 2] = (byte) ((lValue >>> 40) & 0x0ff); 052 buffer[nStartIndex + 3] = (byte) ((lValue >>> 32) & 0x0ff); 053 buffer[nStartIndex + 4] = (byte) ((lValue >>> 24) & 0x0ff); 054 buffer[nStartIndex + 5] = (byte) ((lValue >>> 16) & 0x0ff); 055 buffer[nStartIndex + 6] = (byte) ((lValue >>> 8) & 0x0ff); 056 buffer[nStartIndex + 7] = (byte) lValue; 057 } 058 059 /** 060 * converts values from an integer array to a long 061 * @param buffer where to get the bytes 062 * @param nStartIndex index from where to read the data 063 * @return the 64bit integer 064 */ 065 public static long intArrayToLong(int[] buffer,int nStartIndex) { 066 return (((long) buffer[nStartIndex]) << 32) | (( buffer[nStartIndex + 1]) & 0x0ffffffffL); 067 } 068 069 /** 070 * converts a long to integers which are put into a given array 071 * @param lValue the 64bit integer to convert 072 * @param buffer the target buffer 073 * @param nStartIndex where to place the bytes in the buffer 074 */ 075 public static void longToIntArray(long lValue,int[] buffer,int nStartIndex) { 076 buffer[nStartIndex] = (int) (lValue >>> 32); 077 buffer[nStartIndex + 1] = (int) lValue; 078 } 079 080 /** 081 * makes a long from two integers (treated unsigned) 082 * @param nLo lower 32bits 083 * @param nHi higher 32bits 084 * @return the built long 085 */ 086 public static long makeLong(int nLo,int nHi) { 087 return (((long)nHi << 32) | (nLo & 0x00000000ffffffffL)); 088 } 089 090 /** 091 * gets the lower 32 bits of a long 092 * @param lVal the long integer 093 * @return lower 32 bits 094 */ 095 public static int longLo32(long lVal) { 096 return (int)lVal; 097 } 098 099 /** 100 * gets the higher 32 bits of a long 101 * @param lVal the long integer 102 * @return higher 32 bits 103 */ 104 public static int longHi32(long lVal) { 105 return (int)((lVal >>> 32)); 106 } 107 108 final static char[] HEXTAB = { '0', '1', '2', '3', '4', '5', '6', '7', 109 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 110 111 /** 112 * converts a byte array to a binhex string 113 * @param data the byte array 114 * @return the binhex string 115 */ 116 public static String bytesToBinHex(byte[] data) { 117 return bytesToBinHex(data, 0, data.length); 118 } 119 120 /** 121 * converts a byte array to a binhex string 122 * @param data the byte array 123 * @param nStartPos start index where to get the bytes 124 * @param nNumOfBytes number of bytes to convert 125 * @return the binhex string 126 */ 127 public static String bytesToBinHex(byte[] data,int nStartPos,int nNumOfBytes) { 128 StringBuilder sbuf = new StringBuilder(); 129 sbuf.setLength(nNumOfBytes << 1); 130 int nPos = 0; 131 for (int nI = 0; nI < nNumOfBytes; nI++) { 132 sbuf.setCharAt(nPos++, HEXTAB[(data[nI + nStartPos] >> 4) & 0x0f]); 133 sbuf.setCharAt(nPos++, HEXTAB[data[nI + nStartPos] & 0x0f]); 134 } 135 return sbuf.toString(); 136 } 137 138 /** 139 * converts a binhex string back into a byte array (invalid codes will be skipped) 140 * @param sBinHex binhex string 141 * @param data the target array 142 * @param nSrcPos from which character in the string the conversion should begin, 143 * remember that (nSrcPos modulo 2) should equals 0 normally 144 * @param nDstPos to store the bytes from which position in the array 145 * @param nNumOfBytes number of bytes to extract 146 * @return number of extracted bytes 147 */ 148 public static int binHexToBytes(String sBinHex,byte[] data,int nSrcPos,int nDstPos,int nNumOfBytes) { 149 // check for correct ranges 150 int nStrLen = sBinHex.length(); 151 int nAvailBytes = (nStrLen - nSrcPos) >> 1; 152 if (nAvailBytes < nNumOfBytes) 153 nNumOfBytes = nAvailBytes; 154 int nOutputCapacity = data.length - nDstPos; 155 if (nNumOfBytes > nOutputCapacity) 156 nNumOfBytes = nOutputCapacity; 157 // convert now 158 int nResult = 0; 159 for (int nI = 0; nI < nNumOfBytes; nI++) { 160 byte bActByte = 0; 161 boolean blConvertOK = true; 162 for (int nJ = 0; nJ < 2; nJ++) { 163 bActByte <<= 4; 164 char cActChar = sBinHex.charAt(nSrcPos++); 165 if ((cActChar >= 'a') && (cActChar <= 'f')) 166 bActByte |= (byte)(cActChar - 'a') + 10; 167 else if ((cActChar >= '0') && (cActChar <= '9')) 168 bActByte |= (byte)(cActChar - '0'); 169 else 170 blConvertOK = false; 171 } 172 if (blConvertOK) { 173 data[nDstPos++] = bActByte; 174 nResult++; 175 } 176 } 177 return nResult; 178 } 179 180 /** 181 * converts a byte array into an UNICODE string 182 * @param data the byte array 183 * @param nStartPos where to begin the conversion 184 * @param nNumOfBytes number of bytes to handle 185 * @return the string 186 */ 187 public static String byteArrayToUNCString(byte[] data,int nStartPos,int nNumOfBytes) { 188 // we need two bytes for every character 189 nNumOfBytes &= ~1; 190 // enough bytes in the buffer? 191 int nAvailCapacity = data.length - nStartPos; 192 if (nAvailCapacity < nNumOfBytes) 193 nNumOfBytes = nAvailCapacity; 194 StringBuilder sbuf = new StringBuilder(); 195 sbuf.setLength(nNumOfBytes >> 1); 196 int nSBufPos = 0; 197 while (nNumOfBytes > 0) { 198 sbuf.setCharAt(nSBufPos++, 199 (char)((data[nStartPos] << 8) | (data[nStartPos + 1] & 0x0ff))); 200 nStartPos += 2; 201 nNumOfBytes -= 2; 202 } 203 return sbuf.toString(); 204 } 205}