1 package com.genimen.djeneric.util; 2 3 public final class DjBase64 4 { 5 static private final int BASELENGTH = 255; 6 static private final int LOOKUPLENGTH = 64; 7 static private final int TWENTYFOURBITGROUP = 24; 8 static private final int EIGHTBIT = 8; 9 static private final int SIXTEENBIT = 16; 10 static private final int SIXBIT = 6; 11 static private final int FOURBYTE = 4; 12 static private final int SIGN = -128; 13 static private final char PAD = '='; 14 static final private byte[] base64Alphabet = new byte[BASELENGTH]; 15 static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; 16 17 static 18 { 19 20 for (int i = 0; i < BASELENGTH; i++) 21 { 22 base64Alphabet[i] = -1; 23 } 24 for (int i = 'Z'; i >= 'A'; i--) 25 { 26 base64Alphabet[i] = (byte) (i - 'A'); 27 } 28 for (int i = 'z'; i >= 'a'; i--) 29 { 30 base64Alphabet[i] = (byte) (i - 'a' + 26); 31 } 32 33 for (int i = '9'; i >= '0'; i--) 34 { 35 base64Alphabet[i] = (byte) (i - '0' + 52); 36 } 37 38 base64Alphabet['+'] = 62; 39 base64Alphabet['/'] = 63; 40 41 for (int i = 0; i <= 25; i++) 42 lookUpBase64Alphabet[i] = (char) ('A' + i); 43 44 for (int i = 26, j = 0; i <= 51; i++, j++) 45 lookUpBase64Alphabet[i] = (char) ('a' + j); 46 47 for (int i = 52, j = 0; i <= 61; i++, j++) 48 lookUpBase64Alphabet[i] = (char) ('0' + j); 49 lookUpBase64Alphabet[62] = (char) '+'; 50 lookUpBase64Alphabet[63] = (char) '/'; 51 52 } 53 54 protected static boolean isWhiteSpace(char octect) 55 { 56 return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); 57 } 58 59 protected static boolean isPad(char octect) 60 { 61 return (octect == PAD); 62 } 63 64 protected static boolean isData(char octect) 65 { 66 return (base64Alphabet[octect] != -1); 67 } 68 69 protected static boolean isBase64(char octect) 70 { 71 return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); 72 } 73 74 81 public static String encode(byte[] binaryData) 82 { 83 84 if (binaryData == null) return null; 85 86 int lengthDataBits = binaryData.length * EIGHTBIT; 87 if (lengthDataBits == 0) 88 { 89 return ""; 90 } 91 92 int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; 93 int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; 94 int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; 95 int numberLines = (numberQuartet - 1) / 19 + 1; 96 char encodedData[] = null; 97 98 encodedData = new char[numberQuartet * 4 + numberLines]; 99 100 byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; 101 102 int encodedIndex = 0; 103 int dataIndex = 0; 104 int i = 0; 105 106 for (int line = 0; line < numberLines - 1; line++) 107 { 108 for (int quartet = 0; quartet < 19; quartet++) 109 { 110 b1 = binaryData[dataIndex++]; 111 b2 = binaryData[dataIndex++]; 112 b3 = binaryData[dataIndex++]; 113 114 l = (byte) (b2 & 0x0f); 115 k = (byte) (b1 & 0x03); 116 117 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); 118 119 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); 120 byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); 121 122 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; 123 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; 124 encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; 125 encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; 126 127 i++; 128 } 129 encodedData[encodedIndex++] = 0xa; 130 } 131 132 for (; i < numberTriplets; i++) 133 { 134 b1 = binaryData[dataIndex++]; 135 b2 = binaryData[dataIndex++]; 136 b3 = binaryData[dataIndex++]; 137 138 l = (byte) (b2 & 0x0f); 139 k = (byte) (b1 & 0x03); 140 141 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); 142 143 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); 144 byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); 145 146 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; 147 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; 148 encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; 149 encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; 150 } 151 152 if (fewerThan24bits == EIGHTBIT) 154 { 155 b1 = binaryData[dataIndex]; 156 k = (byte) (b1 & 0x03); 157 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); 158 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; 159 encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; 160 encodedData[encodedIndex++] = PAD; 161 encodedData[encodedIndex++] = PAD; 162 } 163 else if (fewerThan24bits == SIXTEENBIT) 164 { 165 b1 = binaryData[dataIndex]; 166 b2 = binaryData[dataIndex + 1]; 167 l = (byte) (b2 & 0x0f); 168 k = (byte) (b1 & 0x03); 169 170 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); 171 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); 172 173 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; 174 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; 175 encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; 176 encodedData[encodedIndex++] = PAD; 177 } 178 179 encodedData[encodedIndex] = 0xa; 180 181 return new String (encodedData); 182 } 183 184 191 public static byte[] decode(String encoded) 192 { 193 194 if (encoded == null) return null; 195 196 char[] base64Data = encoded.toCharArray(); 197 int len = removeWhiteSpace(base64Data); 199 200 if (len % FOURBYTE != 0) 201 { 202 return null; } 204 205 int numberQuadruple = (len / FOURBYTE); 206 207 if (numberQuadruple == 0) return new byte[0]; 208 209 byte decodedData[] = null; 210 byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; 211 char d1 = 0, d2 = 0, d3 = 0, d4 = 0; 212 213 int i = 0; 214 int encodedIndex = 0; 215 int dataIndex = 0; 216 decodedData = new byte[(numberQuadruple) * 3]; 217 218 for (; i < numberQuadruple - 1; i++) 219 { 220 221 if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) 222 || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) return null; 224 b1 = base64Alphabet[d1]; 225 b2 = base64Alphabet[d2]; 226 b3 = base64Alphabet[d3]; 227 b4 = base64Alphabet[d4]; 228 229 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 230 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 231 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); 232 } 233 234 if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) 235 { 236 return null; } 238 239 b1 = base64Alphabet[d1]; 240 b2 = base64Alphabet[d2]; 241 242 d3 = base64Data[dataIndex++]; 243 d4 = base64Data[dataIndex++]; 244 if (!isData((d3)) || !isData((d4))) 245 { if (isPad(d3) && isPad(d4)) 247 { if ((b2 & 0xf) != 0) return null; 250 byte[] tmp = new byte[i * 3 + 1]; 251 System.arraycopy(decodedData, 0, tmp, 0, i * 3); 252 tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 253 return tmp; 254 } 255 else if (!isPad(d3) && isPad(d4)) 256 { b3 = base64Alphabet[d3]; 258 if ((b3 & 0x3) != 0) return null; 260 byte[] tmp = new byte[i * 3 + 2]; 261 System.arraycopy(decodedData, 0, tmp, 0, i * 3); 262 tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 263 tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 264 return tmp; 265 } 266 else 267 { 268 return null; } 271 } 272 else 273 { b3 = base64Alphabet[d3]; 275 b4 = base64Alphabet[d4]; 276 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 277 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 278 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); 279 280 } 281 282 return decodedData; 283 } 284 285 292 protected static int removeWhiteSpace(char[] data) 293 { 294 if (data == null) return 0; 295 296 int newSize = 0; 298 int len = data.length; 299 for (int i = 0; i < len; i++) 300 { 301 if (!isWhiteSpace(data[i])) data[newSize++] = data[i]; 302 } 303 return newSize; 304 } 305 } | Popular Tags |