Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
public class Base64Test { public static void main(String[] args) throws UnsupportedEncodingException { String str1 = "hello world"; String str2 = "床前明月光,疑是地上霜,举头望明月,低头思故乡"; String str3 = "好abcde"; String str4 = "qwertyuiopasfghjklzxcvbnm"; String r1 = toBase64(str1.getBytes("utf-8")); String r2 = toBase64(str2.getBytes("utf-8")); String r3 = toBase64(str3.getBytes("utf-8")); String r4 = toBase64(str4.getBytes("utf-8")); System.out.println(r1); System.out.println(r2); System.out.println(r3); System.out.println(r4); System.out.println("------------------------------------"); // spring util System.out.println(Base64Utils.encodeToString(str1.getBytes("utf-8"))); System.out.println(Base64Utils.encodeToString(str2.getBytes("utf-8"))); System.out.println(Base64Utils.encodeToString(str3.getBytes("utf-8"))); System.out.println(Base64Utils.encodeToString(str4.getBytes("utf-8"))); System.out.println("------------------------------------"); System.out.println(new String(base64Decode(r1),"utf-8")); System.out.println(new String(base64Decode(r2),"utf-8")); System.out.println(new String(base64Decode(r3),"utf-8")); System.out.println(new String(base64Decode(r4),"utf-8")); } public static String toBase64(byte[] bytes){ char base64Char[] = {'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','+','/'}; byte b1,b2,b3; StringBuilder sb = new StringBuilder(); for(int i=0;i<bytes.length;i+=3){ b1 = bytes[i]; sb.append(base64Char[(b1>>2&0x3f)]); if(i+1<bytes.length){ b2 = bytes[i+1]; sb.append(base64Char[(((b1<<4)|(b2>>4&0x0f))&0x3f)]); if(i+2<bytes.length){ b3 = bytes[i+2]; sb.append(base64Char[(((b2<<2)|(b3>>6&0x03))&0x3f)]); sb.append(base64Char[(b3&0x3f)]); }else{ sb.append(base64Char[((b2<<2)&0x3C)]); sb.append('='); } }else{ sb.append(base64Char[((b1<<4)&0x30)]); sb.append('='); sb.append('='); } } return sb.toString(); } public static byte[] base64Decode(String enCodeStr){ int len; int index = enCodeStr.indexOf('='); if(index<0){ len = enCodeStr.length()/4*3; }else{ int subLen = enCodeStr.substring(index).length(); if(subLen==1){ len = enCodeStr.length()/4*3-1; }else{ len = enCodeStr.length()/4*3-2; } } byte[] bytes = new byte[len]; for(int i=0;i<enCodeStr.length()/4;i++){ int a = getIntValue(enCodeStr.charAt(4*i)); int b = getIntValue(enCodeStr.charAt(4*i+1)); int c = getIntValue(enCodeStr.charAt(4*i+2)); int d = getIntValue(enCodeStr.charAt(4*i+3)); bytes[3*i] = (byte) ((a<<2)|(b>>4&0x03)); if(-1==c){// == break; }else{ bytes[3*i+1] = (byte) ((b<<4)|(c>>2&0x0f)); if(-1==d){// = break; } } bytes[3*i+2] = (byte) (c<<6|d); } return bytes; } public static int getIntValue(char c){ switch(c){ case 'A' : return 0; case 'B' : return 1; case 'C' : return 2; case 'D' : return 3; case 'E' : return 4; case 'F' : return 5; case 'G' : return 6; case 'H' : return 7; case 'I' : return 8; case 'J' : return 9; case 'K' : return 10; case 'L' : return 11; case 'M' : return 12; case 'N' : return 13; case 'O' : return 14; case 'P' : return 15; case 'Q' : return 16; case 'R' : return 17; case 'S' : return 18; case 'T' : return 19; case 'U' : return 20; case 'V' : return 21; case 'W' : return 22; case 'X' : return 23; case 'Y' : return 24; case 'Z' : return 25; case 'a' : return 26; case 'b' : return 27; case 'c' : return 28; case 'd' : return 29; case 'e' : return 30; case 'f' : return 31; case 'g' : return 32; case 'h' : return 33; case 'i' : return 34; case 'j' : return 35; case 'k' : return 36; case 'l' : return 37; case 'm' : return 38; case 'n' : return 39; case 'o' : return 40; case 'p' : return 41; case 'q' : return 42; case 'r' : return 43; case 's' : return 44; case 't' : return 45; case 'u' : return 46; case 'v' : return 47; case 'w' : return 48; case 'x' : return 49; case 'y' : return 50; case 'z' : return 51; case '0' : return 52; case '1' : return 53; case '2' : return 54; case '3' : return 55; case '4' : return 56; case '5' : return 57; case '6' : return 58; case '7' : return 59; case '8' : return 60; case '9' : return 61; case '+' : return 62; case '/' : return 63; case '=' : return -1; default : throw new RuntimeException("out of bound"); } } }