1 11 package org.eclipse.osgi.internal.verifier; 12 13 public class Base64 { 14 15 private static final byte equalSign = (byte) '='; 16 17 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', '+', '/'}; 21 22 30 public static byte[] decode(byte[] data) { 31 if (data.length == 0) 32 return data; 33 int lastRealDataIndex = data.length - 1; 34 while (data[lastRealDataIndex] == equalSign) 35 lastRealDataIndex--; 36 int padBytes = data.length - 1 - lastRealDataIndex; 38 int byteLength = data.length * 6 / 8 - padBytes; 39 byte[] result = new byte[byteLength]; 40 int dataIndex = 0; 42 int resultIndex = 0; 43 int allBits = 0; 44 int resultChunks = (lastRealDataIndex + 1) / 4; 46 for (int i = 0; i < resultChunks; i++) { 47 allBits = 0; 48 for (int j = 0; j < 4; j++) 50 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 51 for (int j = resultIndex + 2; j >= resultIndex; j--) { 53 result[j] = (byte) (allBits & 0xff); allBits = allBits >>> 8; 55 } 56 resultIndex += 3; } 58 switch (padBytes) { 61 case 1 : 62 allBits = 0; 66 for (int j = 0; j < 3; j++) 68 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 69 allBits = allBits << 6; 74 allBits = allBits >>> 8; 76 for (int j = resultIndex + 1; j >= resultIndex; j--) { 78 result[j] = (byte) (allBits & 0xff); allBits = allBits >>> 8; 81 } 82 break; 83 case 2 : 84 allBits = 0; 88 for (int j = 0; j < 2; j++) 90 allBits = (allBits << 6) | decodeDigit(data[dataIndex++]); 91 allBits = allBits << 6; 96 allBits = allBits << 6; 97 allBits = allBits >>> 8; 99 allBits = allBits >>> 8; 100 result[resultIndex] = (byte) (allBits & 0xff); break; 104 } 105 return result; 106 } 107 108 114 static int decodeDigit(byte data) { 115 char charData = (char) data; 116 if (charData <= 'Z' && charData >= 'A') 117 return charData - 'A'; 118 if (charData <= 'z' && charData >= 'a') 119 return charData - 'a' + 26; 120 if (charData <= '9' && charData >= '0') 121 return charData - '0' + 52; 122 switch (charData) { 123 case '+' : 124 return 62; 125 case '/' : 126 return 63; 127 default : 128 throw new IllegalArgumentException ("Invalid char to decode: " + data); } 130 } 131 132 139 public static byte[] encode(byte[] data) { 140 int sourceChunks = data.length / 3; 141 int len = ((data.length + 2) / 3) * 4; 142 byte[] result = new byte[len]; 143 int extraBytes = data.length - (sourceChunks * 3); 144 int dataIndex = 0; 146 int resultIndex = 0; 147 int allBits = 0; 148 for (int i = 0; i < sourceChunks; i++) { 149 allBits = 0; 150 for (int j = 0; j < 3; j++) 152 allBits = (allBits << 8) | (data[dataIndex++] & 0xff); 153 for (int j = resultIndex + 3; j >= resultIndex; j--) { 155 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 159 } 160 resultIndex += 4; } 162 switch (extraBytes) { 165 case 1 : 166 allBits = data[dataIndex++]; allBits = allBits << 8; allBits = allBits << 8; for (int j = resultIndex + 3; j >= resultIndex; j--) { 171 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 175 } 176 result[result.length - 1] = (byte) '='; 178 result[result.length - 2] = (byte) '='; 179 break; 180 case 2 : 181 allBits = data[dataIndex++]; allBits = (allBits << 8) | (data[dataIndex++] & 0xff); allBits = allBits << 8; for (int j = resultIndex + 3; j >= resultIndex; j--) { 187 result[j] = (byte) digits[(allBits & 0x3f)]; allBits = allBits >>> 6; 191 } 192 result[result.length - 1] = (byte) '='; 194 break; 195 } 196 return result; 197 } 198 } | Popular Tags |