public final class Base64 {

static private final int     BASELENGTH           = 128;

static private final int     LOOKUPLENGTH         = 64;

static private final int     TWENTYFOURBITGROUP   = 24;

static private final int     EIGHTBIT             = 8;

static private final int     SIXTEENBIT           = 16;

static private final int     FOURBYTE             = 4;

static private final int     SIGN                 = -128;

static private final char    PAD                  = '=';

static private final boolean fDebug               = false;

static final private byte[]  base64Alphabet       = new byte[BASELENGTH];

static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];

static {

for (int i = 0; i < BASELENGTH; ++i) {

base64Alphabet[i] = -1;

}

for (int i = 'Z'; i >= 'A'; i--) {

base64Alphabet[i] = (byte) (i - 'A');

}

for (int i = 'z'; i >= 'a'; i--) {

base64Alphabet[i] = (byte) (i - 'a' + 26);

}

for (int i = '9'; i >= '0'; i--) {

base64Alphabet[i] = (byte) (i - '0' + 52);

}

base64Alphabet['+'] = 62;

base64Alphabet['/'] = 63;

for (int i = 0; i <= 25; i++) {

lookUpBase64Alphabet[i] = (char) ('A' + i);

}

for (int i = 26, j = 0; i <= 51; i++, j++) {

lookUpBase64Alphabet[i] = (char) ('a' + j);

}

for (int i = 52, j = 0; i <= 61; i++, j++) {

lookUpBase64Alphabet[i] = (char) ('0' + j);

}

lookUpBase64Alphabet[62] = (char) '+';

lookUpBase64Alphabet[63] = (char) '/';

}

private static boolean isWhiteSpace(char octect) {

return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);

}

private static boolean isPad(char octect) {

return (octect == PAD);

}

private static boolean isData(char octect) {

return (octect < BASELENGTH && base64Alphabet[octect] != -1);

}

/**

* Encodes hex octects into Base64

*

* @param binaryData Array containing binaryData

* @return Encoded Base64 array

*/

public static String encode(byte[] binaryData) {

if (binaryData == null) {

return null;

}

int lengthDataBits = binaryData.length * EIGHTBIT;

if (lengthDataBits == 0) {

return "";

}

int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;

int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;

int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;

char encodedData[] = null;

encodedData = new char[numberQuartet * 4];

byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;

int encodedIndex = 0;

int dataIndex = 0;

if (fDebug) {

System.out.println("number of triplets = " + numberTriplets);

}

for (int i = 0; i < numberTriplets; i++) {

b1 = binaryData[dataIndex++];

b2 = binaryData[dataIndex++];

b3 = binaryData[dataIndex++];

if (fDebug) {

System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);

}

l = (byte) (b2 & 0x0f);

k = (byte) (b1 & 0x03);

byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);

byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);

byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);

if (fDebug) {

System.out.println("val2 = " + val2);

System.out.println("k4   = " + (k << 4));

System.out.println("vak  = " + (val2 | (k << 4)));

}

encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];

encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];

encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];

encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];

}

// form integral number of 6-bit groups

if (fewerThan24bits == EIGHTBIT) {

b1 = binaryData[dataIndex];

k = (byte) (b1 & 0x03);

if (fDebug) {

System.out.println("b1=" + b1);

System.out.println("b1<<2 = " + (b1 >> 2));

}

byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);

encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];

encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];

encodedData[encodedIndex++] = PAD;

encodedData[encodedIndex++] = PAD;

} else if (fewerThan24bits == SIXTEENBIT) {

b1 = binaryData[dataIndex];

b2 = binaryData[dataIndex + 1];

l = (byte) (b2 & 0x0f);

k = (byte) (b1 & 0x03);

byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);

byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);

encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];

encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];

encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];

encodedData[encodedIndex++] = PAD;

}

return new String(encodedData);

}

/**

* Decodes Base64 data into octects

*

* @param encoded string containing Base64 data

* @return Array containind decoded data.

*/

public static byte[] decode(String encoded) {

if (encoded == null) {

return null;

}

char[] base64Data = encoded.toCharArray();

// remove white spaces

int len = removeWhiteSpace(base64Data);

if (len % FOURBYTE != 0) {

return null;//should be divisible by four

}

int numberQuadruple = (len / FOURBYTE);

if (numberQuadruple == 0) {

return new byte[0];

}

byte decodedData[] = null;

byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;

char d1 = 0, d2 = 0, d3 = 0, d4 = 0;

int i = 0;

int encodedIndex = 0;

int dataIndex = 0;

decodedData = new byte[(numberQuadruple) * 3];

for (; i < numberQuadruple - 1; i++) {

if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))

|| !isData((d3 = base64Data[dataIndex++]))

|| !isData((d4 = base64Data[dataIndex++]))) {

return null;

}//if found "no data" just return null

b1 = base64Alphabet[d1];

b2 = base64Alphabet[d2];

b3 = base64Alphabet[d3];

b4 = base64Alphabet[d4];

decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);

decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));

decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);

}

if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {

return null;//if found "no data" just return null

}

b1 = base64Alphabet[d1];

b2 = base64Alphabet[d2];

d3 = base64Data[dataIndex++];

d4 = base64Data[dataIndex++];

if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters

if (isPad(d3) && isPad(d4)) {

if ((b2 & 0xf) != 0)//last 4 bits should be zero

{

return null;

}

byte[] tmp = new byte[i * 3 + 1];

System.arraycopy(decodedData, 0, tmp, 0, i * 3);

tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);

return tmp;

} else if (!isPad(d3) && isPad(d4)) {

b3 = base64Alphabet[d3];

if ((b3 & 0x3) != 0)//last 2 bits should be zero

{

return null;

}

byte[] tmp = new byte[i * 3 + 2];

System.arraycopy(decodedData, 0, tmp, 0, i * 3);

tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);

tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));

return tmp;

} else {

return null;

}

} else { //No PAD e.g 3cQl

b3 = base64Alphabet[d3];

b4 = base64Alphabet[d4];

decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);

decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));

decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);

}

return decodedData;

}

/**

* remove WhiteSpace from MIME containing encoded Base64 data.

*

* @param data  the byte array of base64 data (with WS)

* @return      the new length

*/

private static int removeWhiteSpace(char[] data) {

if (data == null) {

return 0;

}

// count characters that's not whitespace

int newSize = 0;

int len = data.length;

for (int i = 0; i < len; i++) {

if (!isWhiteSpace(data[i])) {

data[newSize++] = data[i];

}

}

return newSize;

}

}

Base64(3)的更多相关文章

  1. linux shell 不同进制数据转换(二进制,八进制,十六进制,base64) (转)

    shell可以在不调用第3方命令,表示不同进制数据.这里总结以下表示方法.shell 脚本默认数值是由10 进制数处理,除非这个数字某种特殊的标记法或前缀开头. 才可以表示其它进制类型数值.如:以 0 ...

  2. 将上传图片转成base64(转)

    效果如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"><titl ...

  3. js转base64(数字)

    var name='测试文字'; var t_name=encodeURIComponent(name); t_name=window.btoa(t_name); console.log(t_name ...

  4. hdu 5237 Base64(模拟)

    Base64 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  5. Base64(2)

    import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncoding ...

  6. WebSocket协议探究(一)

    一 复习和目标 1 复习 上一节使用wireshark抓包分析了WebSocket流量 包含连接的建立:HTTP协议升级WebSocket协议 使用建立完成的WebSocket协议发送数据 2 目标 ...

  7. cookie规范(RFC6265)翻译

    来源:https://github.com/renaesop/blog/issues/4 RFC 6265 要点翻译 1.简介 本文档定义了HTTP Cookie以及HTTP头的Set-Cookie字 ...

  8. (iOS)Base64加密和DES加密、以及JAVA和iOS中DES加密统一性问题

    我们在项目中为了安全方面的考虑,通常情况下会选择一种加密方式对需要安全性的文本进行加密,而Base64加密和DES64加密是常用的加密算法.我记得我在前一个项目中使用的就是这两种加密算法的结合:Bas ...

  9. Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC

    Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC 博客分类: Java/Security Javabase64macmd5sha     加密解密,曾经是我一 ...

随机推荐

  1. SQL进阶系列之9用SQL处理数列

    写在前面 关系模型的数据结构里,并没有顺序的概念,但SQL处理有序集合也有坚实的理论基础 生成连续编号 --生成连续编号 CREATE TABLE Digits (digit INTEGER PRIM ...

  2. py3+requests+json+xlwt,爬取拉勾招聘信息

    在拉勾搜索职位时,通过谷歌F12抓取请求信息 发现请求是一个post请求,参数为: 返回的是json数据 有了上面的基础,我们就可以构造请求了 然后对获取到的响应反序列化,这样就获取到了json格式的 ...

  3. 创建django项目完整实例

    虚拟环境搭配 安装和配置 安装虚拟环境的命令: 1)sudo pip install virtualenv #安装虚拟环境 2)sudo pip install virtualenvwrapper # ...

  4. Tips on Java

    1.JAVA种数组的两种定义方式. int[] nums; int nums[]. 2.整型默认为int,如果需要long,须加l或L.小数默认double,d或D可省略,但如果需要float,须加f ...

  5. zzulioj - 2619: 小新的信息统计

    题目链接:http://acm.zzuli.edu.cn/problem.php?id=2619 题目描述        马上就要新生赛了,QQ群里正在统计所有人的信息,每个人需要从群里下载文件,然后 ...

  6. telegraf 学习二 几个概念

    telegraf 自身包好了自己处理metrics 的数据模型,以及出炉方法 metrics Telegraf指标是用于在处理期间对数据建模的内部表示.这些指标完全基于InfluxDB的数据模型,包含 ...

  7. gj的zabbix客户端开机自启动设置

    查看是否自启动 配置chkconfig 启动服务

  8. RookeyFrame bin 目录

    如果把bin目录删掉,重新生成的话,还需要加载很多东西哦,具体可以对比一下下载下来的文件

  9. 使用 css/less 动态更换主题色(换肤功能)

    前言 说起换肤功能,前端肯定不陌生,其实就是颜色值的更换,实现方式有很多,也各有优缺点 一.看需求是什么 一般来说换肤的需求分为两种: 1. 一种是几种可供选择的颜色/主题样式,进行选择切换,这种可供 ...

  10. 58、Spark Streaming: DStream的output操作以及foreachRDD详解

    一.output操作 1.output操作 DStream中的所有计算,都是由output操作触发的,比如print().如果没有任何output操作,那么,压根儿就不会执行定义的计算逻辑. 此外,即 ...