Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
      3  * Please refer to the LICENSE.txt for licensing details.
      4  */
      5 package ch.ethz.ssh2.crypto;
      6 
      7 import java.io.CharArrayWriter;
      8 import java.io.IOException;
      9 
     10 /**
     11  * Basic Base64 Support.
     12  *
     13  * @author Christian Plattner
     14  * @version 2.50, 03/15/10
     15  */
     16 public class Base64
     17 {
     18 	static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
     19 
     20 	public static char[] encode(byte[] content)
     21 	{
     22 		CharArrayWriter cw = new CharArrayWriter((4 * content.length) / 3);
     23 
     24 		int idx = 0;
     25 
     26 		int x = 0;
     27 
     28 		for (int i = 0; i < content.length; i++)
     29 		{
     30 			if (idx == 0)
     31 				x = (content[i] & 0xff) << 16;
     32 			else if (idx == 1)
     33 				x = x | ((content[i] & 0xff) << 8);
     34 			else
     35 				x = x | (content[i] & 0xff);
     36 
     37 			idx++;
     38 
     39 			if (idx == 3)
     40 			{
     41 				cw.write(alphabet[x >> 18]);
     42 				cw.write(alphabet[(x >> 12) & 0x3f]);
     43 				cw.write(alphabet[(x >> 6) & 0x3f]);
     44 				cw.write(alphabet[x & 0x3f]);
     45 
     46 				idx = 0;
     47 			}
     48 		}
     49 
     50 		if (idx == 1)
     51 		{
     52 			cw.write(alphabet[x >> 18]);
     53 			cw.write(alphabet[(x >> 12) & 0x3f]);
     54 			cw.write('=');
     55 			cw.write('=');
     56 		}
     57 
     58 		if (idx == 2)
     59 		{
     60 			cw.write(alphabet[x >> 18]);
     61 			cw.write(alphabet[(x >> 12) & 0x3f]);
     62 			cw.write(alphabet[(x >> 6) & 0x3f]);
     63 			cw.write('=');
     64 		}
     65 
     66 		return cw.toCharArray();
     67 	}
     68 
     69 	public static byte[] decode(char[] message) throws IOException
     70 	{
     71 		byte buff[] = new byte[4];
     72 		byte dest[] = new byte[message.length];
     73 
     74 		int bpos = 0;
     75 		int destpos = 0;
     76 
     77 		for (int i = 0; i < message.length; i++)
     78 		{
     79 			int c = message[i];
     80 
     81 			if ((c == '\n') || (c == '\r') || (c == ' ') || (c == '\t'))
     82 				continue;
     83 
     84 			if ((c >= 'A') && (c <= 'Z'))
     85 			{
     86 				buff[bpos++] = (byte) (c - 'A');
     87 			}
     88 			else if ((c >= 'a') && (c <= 'z'))
     89 			{
     90 				buff[bpos++] = (byte) ((c - 'a') + 26);
     91 			}
     92 			else if ((c >= '0') && (c <= '9'))
     93 			{
     94 				buff[bpos++] = (byte) ((c - '0') + 52);
     95 			}
     96 			else if (c == '+')
     97 			{
     98 				buff[bpos++] = 62;
     99 			}
    100 			else if (c == '/')
    101 			{
    102 				buff[bpos++] = 63;
    103 			}
    104 			else if (c == '=')
    105 			{
    106 				buff[bpos++] = 64;
    107 			}
    108 			else
    109 			{
    110 				throw new IOException("Illegal char in base64 code.");
    111 			}
    112 
    113 			if (bpos == 4)
    114 			{
    115 				bpos = 0;
    116 
    117 				if (buff[0] == 64)
    118 					break;
    119 
    120 				if (buff[1] == 64)
    121 					throw new IOException("Unexpected '=' in base64 code.");
    122 
    123 				if (buff[2] == 64)
    124 				{
    125 					int v = (((buff[0] & 0x3f) << 6) | ((buff[1] & 0x3f)));
    126 					dest[destpos++] = (byte) (v >> 4);
    127 					break;
    128 				}
    129 				else if (buff[3] == 64)
    130 				{
    131 					int v = (((buff[0] & 0x3f) << 12) | ((buff[1] & 0x3f) << 6) | ((buff[2] & 0x3f)));
    132 					dest[destpos++] = (byte) (v >> 10);
    133 					dest[destpos++] = (byte) (v >> 2);
    134 					break;
    135 				}
    136 				else
    137 				{
    138 					int v = (((buff[0] & 0x3f) << 18) | ((buff[1] & 0x3f) << 12) | ((buff[2] & 0x3f) << 6) | ((buff[3] & 0x3f)));
    139 					dest[destpos++] = (byte) (v >> 16);
    140 					dest[destpos++] = (byte) (v >> 8);
    141 					dest[destpos++] = (byte) (v);
    142 				}
    143 			}
    144 		}
    145 
    146 		byte[] res = new byte[destpos];
    147 		System.arraycopy(dest, 0, res, 0, destpos);
    148 
    149 		return res;
    150 	}
    151 }
    152