public class Base64{

/**
* how we separate lines, e.g. \n, \r\n, \r etc.
*/
private String lineSeparator = System.getProperty("line.separator");

/**
* max chars per line, excluding lineSeparator. A multiple of 4.
*/
private int lineLength = 72;

/* constructor */
public Base64 (){
}

/**
* Encode an arbitrary array of bytes as Base64 printable ASCII.
* It will be broken into lines of 72 chars each. The last line is not
* terminated with a line separator.
* The output will always have an even multiple of data characters,
* exclusive of \n. It is padded out with =.
*/
public String encode (byte[] b){
// Each group or partial group of 3 bytes becomes four chars
// covered quotient
int outputLength = ((b.length + 2) / 3) * 4;

// account for trailing newlines, on all but the very last line
if (lineLength != 0){
int lines = (outputLength + lineLength - 1) / lineLength - 1;
if (lines > 0){

outputLength += lines * lineSeparator.length();
}
}

// must be local for recursion to work.
StringBuffer sb = new StringBuffer(outputLength);

// must be local for recursion to work.
int linePos = 0;

// first deal with even multiples of 3 bytes.
int len = (b.length / 3) * 3;
int leftover = b.length - len;
for (int i = 0;i < len;i += 3){
// Start a new line if next 4 chars won't fit on the current line
// We can't encapsulete the following code since the variable need to
// be local to this incarnation of encode.
linePos += 4;
if (linePos > lineLength){
if (lineLength != 0){
sb.append(lineSeparator);
}
linePos = 4;
}

// get next three bytes in unsigned form lined up,
// in big-endian order
int combined = b[i + 0] & 0xff;
combined <<= 8;
combined |= b[i + 1] & 0xff;
combined <<= 8;
combined |= b[i + 2] & 0xff;

// break those 24 bits into a 4 groups of 6 bits,
// working LSB to MSB.
int c3 = combined & 0x3f;
combined >>>= 6;
int c2 = combined & 0x3f;
combined >>>= 6;
int c1 = combined & 0x3f;
combined >>>= 6;
int c0 = combined & 0x3f;

// Translate into the equivalent alpha character
// emitting them in big-endian order.
sb.append(valueToChar[c0]);
sb.append(valueToChar[c1]);
sb.append(valueToChar[c2]);
sb.append(valueToChar[c3]);
}

// deal with leftover bytes
switch (leftover){
case 0:
default:

// nothing to do
break;

case 1:

// One leftover byte generates xx==
// Start a new line if next 4 chars won't fit on the current line
linePos += 4;
if (linePos > lineLength){

if (lineLength != 0){
sb.append(lineSeparator);
}
linePos = 4;
}
// Handle this recursively with a faked complete triple.
// Throw away last two chars and replace with ==
sb.append(encode(new byte[]{b[len],0,0}
).substring(0,2));
sb.append("==");
break;

case 2:

// Two leftover bytes generates xxx=
// Start a new line if next 4 chars won't fit on the current line
linePos += 4;
if (linePos > lineLength){
if (lineLength != 0){
sb.append(lineSeparator);
}
linePos = 4;
}
// Handle this recursively with a faked complete triple.
// Throw away last char and replace with =
sb.append(encode(new byte[]{b[len],b[len + 1],0}
).substring(0,3));
sb.append("=");
break;

} // end switch;

if (outputLength != sb.length()){
System.out.println("oops: minor program flaw: output length mis-estimated");
System.out.println("estimate:" + outputLength);
System.out.println("actual:" + sb.length());
}
return sb.toString();
} // end encode

/**
* decode a well-formed complete Base64 string back into an array of bytes.
* It must have an even multiple of 4 data characters (not counting \n),
* padded out with = as needed.
*/
public byte[] decode (String s){

// estimate worst case size of output array, no embedded newlines.
byte[] b = new byte[(s.length() / 4) * 3];

// tracks where we are in a cycle of 4 input chars.
int cycle = 0;

// where we combine 4 groups of 6 bits and take apart as 3 groups of 8.
int combined = 0;

// how many bytes we have prepared.
int j = 0;
// will be an even multiple of 4 chars, plus some embedded \n
int len = s.length();
int dummies = 0;
for (int i = 0;i < len;i++){

int c = s.charAt(i);
int value = (c <= 255) ? charToValue[c] : IGNORE;
// there are two magic values PAD (=) and IGNORE.
switch (value){
case IGNORE:

// e.g. \n, just ignore it.
break;

case PAD:
value = 0;
dummies++;
// fallthrough
default:

/* regular value character */
switch (cycle){
case 0:
combined = value;
cycle = 1;
break;

case 1:
combined <<= 6;
combined |= value;
cycle = 2;
break;

case 2:
combined <<= 6;
combined |= value;
cycle = 3;
break;

case 3:
combined <<= 6;
combined |= value;
// we have just completed a cycle of 4 chars.
// the four 6-bit values are in combined in big-endian order
// peel them off 8 bits at a time working lsb to msb
// to get our original 3 8-bit bytes back

b[j + 2] = (byte)combined;
combined >>>= 8;
b[j + 1] = (byte)combined;
combined >>>= 8;
b[j] = (byte)combined;
j += 3;
cycle = 0;
break;
}
break;
}
} // end for
if (cycle != 0){
throw new ArrayIndexOutOfBoundsException(
"Input to decode not an even multiple of 4 characters; pad with =.");
}
j -= dummies;
if (b.length != j){
byte[] b2 = new byte[j];
System.arraycopy(b,0,b2,0,j);
b = b2;
}
return b;

} // end decode

/**
* determines how long the lines are that are generated by encode.
* Ignored by decode.
* @param length 0 means no newlines inserted. Must be a multiple of 4.
*/
public void setLineLength (int length){
this.lineLength = (length / 4) * 4;
}

/**
* How lines are separated.
* Ignored by decode.
* @param lineSeparator may be "" but not null.
* Usually contains only a combination of chars \n and \r.
* Could be any chars not in set A-Z a-z 0-9 + /.
*/
public void setLineSeparator (String lineSeparator){
this.lineSeparator = lineSeparator;
}

/**
* letter of the alphabet used to encode binary values 0..63
*/
static final char[] valueToChar = new char[64];

/**
* binary value encoded by a given letter of the alphabet 0..63
*/
static final int[] charToValue = new int[256];

/**
* Marker value for chars we just ignore, e.g. \n \r high ascii
*/
static final int IGNORE = -1;

/**
* Marker for = trailing pad
*/
static final int PAD = -2;

static
/* initialise valueToChar and charToValue tables */{
// build translate valueToChar table only once.
// 0..25 -> 'A'..'Z'
for (int i = 0;i <= 25;i++){
valueToChar[i] = (char)('A' + i);
// 26..51 -> 'a'..'z'
}
for (int i = 0;i <= 25;i++){
valueToChar[i + 26] = (char)('a' + i);
// 52..61 -> '0'..'9'
}
for (int i = 0;i <= 9;i++){
valueToChar[i + 52] = (char)('0' + i);
}
valueToChar[62] = '+';
valueToChar[63] = '/';

// build translate charToValue table only once.
for (int i = 0;i < 256;i++){
charToValue[i] = IGNORE; // default is to ignore
}

for (int i = 0;i < 64;i++){
charToValue[valueToChar[i]] = i;
}

charToValue['='] = PAD;
}

/**
* used to disable test driver
*/
private static final boolean debug = false;

/**
* debug display array
*/
public static void show (byte[] b){
for (int i = 0;i < b.length;i++){
System.out.print(Integer.toHexString(b[i] & 0xff) + " ");
}
System.out.println();
}

/**
* debug display array
*/
public static void display (byte[] b){
for (int i = 0;i < b.length;i++){
System.out.print((char)b[i]);
}
System.out.println();
}

/**
* test driver
*/
public static void main (String[] args){
if (debug){
byte[] a = {(byte)0xfc,(byte)0x0f,(byte)0xc0};
byte[] b = {(byte)0x03,(byte)0xf0,(byte)0x3f};
byte[] c = {(byte)0x00,(byte)0x00,(byte)0x00};
byte[] d = {(byte)0xff,(byte)0xff,(byte)0xff};
byte[] e = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1};
byte[] f = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2};
byte[] g = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2,(byte)3};
byte[] h = "AAAAAAAAAAB".getBytes();

show(a);
show(b);
show(c);
show(d);
show(e);
show(f);
show(g);
show(h);
Base64 b64 = new Base64();
show(b64.decode(b64.encode(a)));
show(b64.decode(b64.encode(b)));
show(b64.decode(b64.encode(c)));
show(b64.decode(b64.encode(d)));
show(b64.decode(b64.encode(e)));
show(b64.decode(b64.encode(f)));
show(b64.decode(b64.encode(g)));
show(b64.decode(b64.encode(h)));
b64.setLineLength(8);
show((b64.encode(h)).getBytes());
}
} // end main

} // end Base64

base64类的更多相关文章

  1. 使用Apache的Base64类实现Base64加解密

    包名称:org.apache.commons.codec.binary 类名称:org.apache.commons.codec.binary.Base64 1.Base64加密 public sta ...

  2. Java Base64 类

    package org.yp.ypfinancing.core.service.payV2.domain.service.Sdp.utils; public final class Base64 { ...

  3. ios客户端base64上传图片到java服务器遇到的问题

    由于base64位包含了“+”和“\”两个特殊符号,导致ios编码后上传图片到服务器,服务器解码以后的值会不一致,导致图片损坏. 解决办法:重写Base64类,用“(”和“)”替换“+”和“\”两个特 ...

  4. C++实现base64编码

    将昨天的php代码改造成C++ /*base_64.h文件*/ #ifndef BASE_64_H #define BASE_64_H /** * Base64 编码/解码 * @author lir ...

  5. MD5加密算法(信息摘要算法)、Base64算法

    1 什么是MD5 信息摘要算法,可以将字符进行加密,每个加密对象在进行加密后都是等长的 应用场景:将用户密码经过MD5加密后再存储到数据库中,这样即使是超级管理员也没有能力知道用户的具体密码是多少:因 ...

  6. java8版本base64加密解密

    首先,先是加密,这里我使用了base64类 try { String asB64 = Base64.getEncoder().encodeToString("http://www.baidu ...

  7. Java8 Base64

    转自:https://www.runoob.com/java/java8-base64.html 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编 ...

  8. Java 8 新特性-菜鸟教程 (9) -Java8 Base64

    Java8 Base64 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编码的编码器和解码器. Base64工具类提供了一套静态方法获取下面三种B ...

  9. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

随机推荐

  1. CodeForces 723F【DFS瞎搞】

    题意: 给你一幅图,你要用这些边构造一个树, s和t两个节点的度数不能超过ds dt 而且图是保证没有环 思路: 树的性质是:无环(已经保证),无向(保证),连通(还要判断) 首先把S,T点从图里剥离 ...

  2. 正向渲染路径细节 Forward Rendering Path Details

    http://www.ceeger.com/Components/RenderTech-ForwardRendering.html This page describes details of For ...

  3. 慕课笔记-Java入门第一季

    [初步复习Java编程基础,记录知识盲点和遗漏点] 1.switch语法 switch(表达式){ case 值1: 执行代码块1; break; case 值2: 执行代码块12; break; c ...

  4. JDBC连接池一 自定义连接池

    package com.mozq.jdbc; import java.io.IOException; import java.io.InputStream; import java.sql.Conne ...

  5. struts2与struts1的比较

    struts2相对于struts1来说简单了很多,并且功能强大了很多,我们可以从几个方面来看: 从体系结构来看:struts2大量使用拦截器来出来请求,从而允许与业务逻辑控制器 与 servlet-a ...

  6. 测试 | 单元测试工具 | JUnit

    http://junit.sourceforge.net/javadoc/org/junit/Assert.html 使用: 新建测试类: 在预测试的类上点击右键--->NEW--->Ju ...

  7. Web之localStorage

    localStorage: 1.localStorage拓展了cookie的4K限制 2.localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库 ...

  8. UWP 播放媒体控件

    最近我的uwp需要有一个有声朗读的功能,like this 点击声音按钮就可以有声朗读了.这里主要是用了媒体播放的控件. 一般我们把需求分为两种: 一种是不需要呈现播放器的样子,只需要用户点击一下别的 ...

  9. Hadoop启动datanode失败,clusterId有问题

    问题: 搭建伪Hadoop集群的时候,运行命令: hdfs namenode -format 格式化或者说初始化namenode. 然后用命令: start-dfs.sh 来启动hdfs时,jps发现 ...

  10. 关于 ie8不兼容的一些方法

    ie8 不兼容的方法 $(function(){ //添加数组IndexOf方法 if (!Array.prototype.indexOf){ Array.prototype.indexOf = fu ...