1 11 package org.eclipse.ui.internal.preferences; 12 13 18 class Base64 { 19 20 private static final byte equalSign = (byte) '='; 21 22 static char digits[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 26 27 35 public static byte[] decode(byte[] data) { 36 if (data.length == 0) { 37 return data; 38 } 39 int lastRealDataIndex = data.length - 1; 40 while (data[lastRealDataIndex] == equalSign) { 41 lastRealDataIndex--; 42 } 43 int padBytes = data.length - 1 - lastRealDataIndex; 45 int byteLength = data.length * 6 / 8 - padBytes; 46 byte[] result = new byte[byteLength]; 47 int dataIndex = 0; 49 int resultIndex = 0; 50 int allBits = 0; 51 int resultChunks = (lastRealDataIndex + 1) / 4; 53 for (int i = 0; i < resultChunks; i++) { 54 allBits = 0; 55 for (int j = 0; j < 4; j++) { 57 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 58 } 59 for (int j = resultIndex + 2; j >= resultIndex; j--) { 61 result[j] = (byte) (allBits & 0xff); allBits = allBits >>> 8; 63 } 64 resultIndex += 3; } 66 switch (padBytes) { 69 case 1 : 70 allBits = 0; 74 for (int j = 0; j < 3; j++) { 76 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 77 } 78 allBits = allBits << 6; 83 allBits = allBits >>> 8; 85 for (int j = resultIndex + 1; j >= resultIndex; j--) { 87 result[j] = (byte) (allBits & 0xff); allBits = allBits >>> 8; 90 } 91 break; 92 case 2 : 93 allBits = 0; 97 for (int j = 0; j < 2; j++) { 99 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 100 } 101 allBits = allBits << 6; 106 allBits = allBits << 6; 107 allBits = allBits >>> 8; 109 allBits = allBits >>> 8; 110 result[resultIndex] = (byte) (allBits & 0xff); break; 114 } 115 return result; 116 } 117 118 124 static int decodeDigit(byte data) { 125 char charData = (char) data; 126 if (charData <= 'Z' && charData >= 'A') { 127 return charData - 'A'; 128 } 129 if (charData <= 'z' && charData >= 'a') { 130 return charData - 'a' + 26; 131 } 132 if (charData <= '9' && charData >= '0') { 133 return charData - '0' + 52; 134 } 135 switch (charData) { 136 case '+' : 137 return 62; 138 case '/' : 139 return 63; 140 default : 141 throw new IllegalArgumentException ("Invalid char to decode: " + data); } 143 } 144 145 152 public static byte[] encode(byte[] data) { 153 int sourceChunks = data.length / 3; 154 int len = ((data.length + 2) / 3) * 4; 155 byte[] result = new byte[len]; 156 int extraBytes = data.length - (sourceChunks * 3); 157 int dataIndex = 0; 159 int resultIndex = 0; 160 int allBits = 0; 161 for (int i = 0; i < sourceChunks; i++) { 162 allBits = 0; 163 for (int j = 0; j < 3; j++) { 165 allBits = (allBits << 8) | (data[dataIndex++] & 0xff); 166 } 167 for (int j = resultIndex + 3; j >= resultIndex; j--) { 169 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 173 } 174 resultIndex += 4; } 176 switch (extraBytes) { 179 case 1 : 180 allBits = data[dataIndex++]; allBits = allBits << 8; allBits = allBits << 8; for (int j = resultIndex + 3; j >= resultIndex; j--) { 185 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 189 } 190 result[result.length - 1] = (byte) '='; 192 result[result.length - 2] = (byte) '='; 193 break; 194 case 2 : 195 allBits = data[dataIndex++]; allBits = (allBits << 8) | (data[dataIndex++] & 0xff); allBits = allBits << 8; for (int j = resultIndex + 3; j >= resultIndex; j--) { 201 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 205 } 206 result[result.length - 1] = (byte) '='; 208 break; 209 } 210 return result; 211 } 212 } 213 | Popular Tags |