001 /* 002 003 $Id: Base64.java,v 1.2 2003/05/08 10:34:22 culdesac Exp $ 004 005 */ 006 007 package sharpster.common; 008 009 public class Base64 { 010 public static String encode(byte[] raw) { 011 StringBuffer encoded = new StringBuffer(); 012 for (int i = 0; i < raw.length; i += 3) { 013 encoded.append(encodeBlock(raw, i)); 014 } 015 return encoded.toString(); 016 } 017 018 protected static char[] encodeBlock(byte[] raw, int offset) { 019 int block = 0; 020 int slack = raw.length - offset - 1; 021 int end = (slack >= 2) ? 2 : slack; 022 for (int i = 0; i <= end; i++) { 023 byte b = raw[offset + i]; 024 int neuter = (b < 0) ? b + 256 : b; 025 block += neuter << (8 * (2 - i)); 026 } 027 char[] base64 = new char[4]; 028 for (int i = 0; i < 4; i++) { 029 int sixbit = (block >>> (6 * (3 - i))) & 0x3f; 030 base64[i] = getChar(sixbit); 031 } 032 if (slack < 1) base64[2] = '='; 033 if (slack < 2) base64[3] = '='; 034 return base64; 035 } 036 037 protected static char getChar(int sixBit) { 038 if (sixBit >= 0 && sixBit <= 25) 039 return (char)('A' + sixBit); 040 if (sixBit >= 26 && sixBit <= 51) 041 return (char)('a' + (sixBit - 26)); 042 if (sixBit >= 52 && sixBit <= 61) 043 return (char)('0' + (sixBit - 52)); 044 if (sixBit == 62) return '+'; 045 if (sixBit == 63) return '/'; 046 return '?'; 047 } 048 049 public static byte[] decode(String base64) { 050 int pad = 0; 051 for (int i = base64.length() - 1; base64.charAt(i) == '='; i--) 052 pad++; 053 int length = base64.length() * 6 / 8 - pad; 054 byte[] raw = new byte[length]; 055 int rawIndex = 0; 056 for (int i = 0; i < base64.length(); i += 4) { 057 int block = (getValue(base64.charAt(i)) << 18) 058 + (getValue(base64.charAt(i + 1)) << 12) 059 + (getValue(base64.charAt(i + 2)) << 6) 060 + (getValue(base64.charAt(i + 3))); 061 for (int j = 0; j < 3 && rawIndex + j < raw.length; j++) 062 raw[rawIndex + j] = (byte)((block >> (8 * (2 - j))) & 0xff); 063 rawIndex += 3; 064 } 065 return raw; 066 } 067 068 protected static int getValue(char c) { 069 if (c >= 'A' && c <= 'Z') return c - 'A'; 070 if (c >= 'a' && c <= 'z') return c - 'a' + 26; 071 if (c >= '0' && c <= '9') return c - '0' + 52; 072 if (c == '+') return 62; 073 if (c == '/') return 63; 074 if (c == '=') return 0; 075 return -1; 076 } 077 }