001    package railo.runtime.crypt;
002    
003    public final class BinConverter {
004    
005      /**
006        * gets bytes from an array into a long
007        * @param buffer where to get the bytes
008        * @param nStartIndex index from where to read the data
009        * @return the 64bit integer
010        */
011      public static long byteArrayToLong(byte[] buffer,int nStartIndex) {
012    
013        return (((long)buffer[nStartIndex]) << 56) |
014               ((buffer[nStartIndex + 1] & 0x0ffL) << 48) |
015               ((buffer[nStartIndex + 2] & 0x0ffL) << 40) |
016               ((buffer[nStartIndex + 3] & 0x0ffL) << 32) |
017               ((buffer[nStartIndex + 4] & 0x0ffL) << 24) |
018               ((buffer[nStartIndex + 5] & 0x0ffL) << 16) |
019               ((buffer[nStartIndex + 6] & 0x0ffL) << 8) |
020               ((long)buffer[nStartIndex + 7] & 0x0ff);
021    
022      }
023    
024      /**
025        * converts a long o bytes which are put into a given array
026        * @param lValue the 64bit integer to convert
027        * @param buffer the target buffer
028        * @param nStartIndex where to place the bytes in the buffer
029        */
030      public static void longToByteArray(long lValue,byte[] buffer,int nStartIndex) {
031        buffer[nStartIndex] = (byte) (lValue >>> 56);
032        buffer[nStartIndex + 1] = (byte) ((lValue >>> 48) & 0x0ff);
033        buffer[nStartIndex + 2] = (byte) ((lValue >>> 40) & 0x0ff);
034        buffer[nStartIndex + 3] = (byte) ((lValue >>> 32) & 0x0ff);
035        buffer[nStartIndex + 4] = (byte) ((lValue >>> 24) & 0x0ff);
036        buffer[nStartIndex + 5] = (byte) ((lValue >>> 16) & 0x0ff);
037        buffer[nStartIndex + 6] = (byte) ((lValue >>> 8) & 0x0ff);
038        buffer[nStartIndex + 7] = (byte) lValue;
039      }
040    
041      /**
042        * converts values from an integer array to a long
043        * @param buffer where to get the bytes
044        * @param nStartIndex index from where to read the data
045        * @return the 64bit integer
046        */
047      public static long intArrayToLong(int[] buffer,int nStartIndex) {
048        return (((long) buffer[nStartIndex]) << 32) | (( buffer[nStartIndex + 1]) & 0x0ffffffffL);
049      }
050    
051      /**
052        * converts a long to integers which are put into a given array
053        * @param lValue the 64bit integer to convert
054        * @param buffer the target buffer
055        * @param nStartIndex where to place the bytes in the buffer
056        */
057      public static void longToIntArray(long lValue,int[] buffer,int nStartIndex) {
058        buffer[nStartIndex]     = (int) (lValue >>> 32);
059        buffer[nStartIndex + 1] = (int) lValue;
060      }
061    
062      /**
063        * makes a long from two integers (treated unsigned)
064        * @param nLo lower 32bits
065        * @param nHi higher 32bits
066        * @return the built long
067        */
068      public static long makeLong(int nLo,int nHi) {
069        return (((long)nHi << 32) | (nLo & 0x00000000ffffffffL));
070      }
071    
072      /**
073        * gets the lower 32 bits of a long
074        * @param lVal the long integer
075        * @return lower 32 bits
076        */
077      public static int longLo32(long lVal) {
078        return (int)lVal;
079      }
080    
081      /**
082        * gets the higher 32 bits of a long
083        * @param lVal the long integer
084        * @return higher 32 bits
085        */
086      public static int longHi32(long lVal) {
087        return (int)((lVal >>> 32));
088      }
089    
090      final static char[] HEXTAB = { '0', '1', '2', '3', '4', '5', '6', '7',
091                                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
092    
093      /**
094        * converts a byte array to a binhex string
095        * @param data the byte array
096        * @return the binhex string
097        */
098      public static String bytesToBinHex(byte[] data) {
099        return bytesToBinHex(data, 0, data.length);
100      }
101    
102      /**
103        * converts a byte array to a binhex string
104        * @param data the byte array
105        * @param nStartPos start index where to get the bytes
106        * @param nNumOfBytes number of bytes to convert
107        * @return the binhex string
108        */
109      public static String bytesToBinHex(byte[] data,int nStartPos,int nNumOfBytes) {
110        StringBuffer sbuf = new StringBuffer();
111        sbuf.setLength(nNumOfBytes << 1);
112        int nPos = 0;
113        for (int nI = 0; nI < nNumOfBytes; nI++) {
114          sbuf.setCharAt(nPos++, HEXTAB[(data[nI + nStartPos] >> 4) & 0x0f]);
115          sbuf.setCharAt(nPos++, HEXTAB[data[nI + nStartPos] & 0x0f]);
116        }
117        return sbuf.toString();
118      }
119    
120      /**
121        * converts a binhex string back into a byte array (invalid codes will be skipped)
122        * @param sBinHex binhex string
123        * @param data the target array
124        * @param nSrcPos from which character in the string the conversion should begin,
125        *                remember that (nSrcPos modulo 2) should equals 0 normally
126        * @param nDstPos to store the bytes from which position in the array
127        * @param nNumOfBytes number of bytes to extract
128        * @return number of extracted bytes
129        */
130      public static int binHexToBytes(String sBinHex,byte[] data,int nSrcPos,int nDstPos,int nNumOfBytes) {
131        // check for correct ranges
132        int nStrLen = sBinHex.length();
133        int nAvailBytes = (nStrLen - nSrcPos) >> 1;
134        if (nAvailBytes < nNumOfBytes)
135          nNumOfBytes = nAvailBytes;
136        int nOutputCapacity = data.length - nDstPos;
137        if (nNumOfBytes > nOutputCapacity)
138          nNumOfBytes = nOutputCapacity;
139        // convert now
140        int nResult = 0;
141        for (int nI = 0; nI < nNumOfBytes; nI++) {
142          byte bActByte = 0;
143          boolean blConvertOK = true;
144          for (int nJ = 0; nJ < 2; nJ++) {
145            bActByte <<= 4;
146            char cActChar = sBinHex.charAt(nSrcPos++);
147            if ((cActChar >= 'a') && (cActChar <= 'f'))
148              bActByte |= (byte)(cActChar - 'a') + 10;
149            else if ((cActChar >= '0') && (cActChar <= '9'))
150                bActByte |= (byte)(cActChar - '0');
151              else
152                blConvertOK = false;
153          }
154          if (blConvertOK) {
155            data[nDstPos++] = bActByte;
156            nResult++;
157          }
158        }
159        return nResult;
160      }
161    
162      /**
163        * converts a byte array into an UNICODE string
164        * @param data the byte array
165        * @param nStartPos where to begin the conversion
166        * @param nNumOfBytes number of bytes to handle
167        * @return the string
168        */
169      public static String byteArrayToUNCString(byte[] data,int nStartPos,int nNumOfBytes) {
170        // we need two bytes for every character
171        nNumOfBytes &= ~1;
172        // enough bytes in the buffer?
173        int nAvailCapacity = data.length - nStartPos;
174        if (nAvailCapacity < nNumOfBytes)
175          nNumOfBytes = nAvailCapacity;
176        StringBuffer sbuf = new StringBuffer();
177        sbuf.setLength(nNumOfBytes >> 1);
178        int nSBufPos = 0;
179        while (nNumOfBytes > 0) {
180          sbuf.setCharAt(nSBufPos++,
181                         (char)((data[nStartPos] << 8) | (data[nStartPos + 1] & 0x0ff)));
182          nStartPos += 2;
183          nNumOfBytes -= 2;
184        }
185        return sbuf.toString();
186      }
187    }