package com.lz.utils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.tools.ant.filters.StringInputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
/**
* Base64编码工具
*
* @author liuz
* @date 2017年8月31日 下午1:34:26
*/
public class Base64Utils {
/** Base64编码ascii码与字符值表 */
private static final char[] BASE64_CHAR_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
private static final char BASE64_COVER_CHAR = '=';
// 缓存块大小(可调优,1024*3可以 957毫秒编码53.6M数据,1896毫秒解码还原,大于1024*3后速度增长不明显)
private static final int BUFFER_SIZE = 1024 * 3;
private static Map<Byte,Byte> reMap; // 逆向映射表
static{
reMap = new HashMap<Byte,Byte>();
for(byte i = 0; i < BASE64_CHAR_MAP.length; i++){
reMap.put((byte)BASE64_CHAR_MAP[i], i);
}
}
/**
* Base64编码-流式处理
*
* @param is
* 输入流
* @param os
* 输出流
* @throws IOException
*/
public static void encode(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
Arrays.fill(buffer, (byte) 0x00);
int rlen = -1;
while ((rlen = is.read(buffer)) != -1) {
int coverSize = (3 - (rlen % 3)) % 3;
int byteSize = rlen + coverSize; // 总字节数
int asciiSize = byteSize * 8 / 6;
byte[] oBuffer = new byte[asciiSize];
// 每次取一个6bit的ascci
for (int i = 0; i < asciiSize; i++) {
byte k = getByte826(buffer, i);
oBuffer[i] = (byte) BASE64_CHAR_MAP[k];
}
Arrays.fill(buffer, (byte) 0x00);
if (coverSize == 1) {
oBuffer[asciiSize - 1] = BASE64_COVER_CHAR;
} else if (coverSize == 2) {
oBuffer[asciiSize - 1] = BASE64_COVER_CHAR;
oBuffer[asciiSize - 2] = BASE64_COVER_CHAR;
}
os.write(oBuffer);
}
}
/**
* Base64编码-字符串处理
*
* @param data
* @return
*/
public static String encode(String data) {
StringInputStream sis = new StringInputStream(data);
ByteOutputStream bos = new ByteOutputStream();
try {
encode(sis, bos);
} catch (IOException e) {
e.printStackTrace();
}
return bos.toString();
}
/**
* Base64加密 - byte数组实现
*
* @param data
* @return
*/
public static String encode(byte[] data) {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ByteOutputStream bos = new ByteOutputStream();
try {
encode(bis, bos);
} catch (IOException e) {
e.printStackTrace();
}
return bos.toString();
}
/**
* Base64解码 - 流式处理
*
* @param is
* 输入流
* @param os
* 输出流
* @throws IOException
*/
public static void decode(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE * 8 / 4];
Arrays.fill(buffer, (byte) 0x00);
int rlen = -1;
while ((rlen = is.read(buffer)) != -1) {
if (rlen % 4 != 0) {
throw new IOException("Base64 data stream EOF with error length");
}
int asciiSize = rlen / 4 * 3; // 4byte转成3byte
byte[] oBuffer = new byte[asciiSize];
// 每次取一个6bit的ascci
for (int i = 0; i < asciiSize; i++) {
Byte k = getByte628(buffer, i);
if (null != k) {
oBuffer[i] = k;
}
}
Arrays.fill(buffer, (byte) 0x00);
os.write(oBuffer);
}
}
/**
* Base64解码-字符串处理,返回byte[]
*
* @param data
* @return
*/
public static byte[] decode(String data) {
StringInputStream sis = new StringInputStream(data);
ByteOutputStream bos = new ByteOutputStream();
try {
decode(sis, bos);
} catch (IOException e) {
e.printStackTrace();
}
return bos.getBytes();
}
/**
* Base64解码-字符串处理,返回String
*
* @param data
* @param charset
* @return
*/
public static String decode2String(String data, String charset) {
byte[] bs = decode(data);
if (charset == null || charset.trim().isEmpty() || !Charset.isSupported(charset)) {
return new String(bs);
}
try {
return new String(bs, charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
/**
* 从缓存取中取出一个8bit的数据(4byte转成3byte)
*
* @param buffer
* @param index
* 8bit的index
* @return
*/
private static Byte getByte628(byte[] buffer, int index) {
int group8Count = index / 3; // 3个一组,对应base64的4个一组
int num = index % 3; // 分组中的几号位置(0:1-2,1:2-3,2:3-4)
int g6Index = group8Count * 4;
if (num == 0) {
Byte bs = reMap.get(buffer[g6Index]);
Byte be = reMap.get(buffer[g6Index + 1]);
if (bs == null) {
return null;
}
if (be == null) {
be = 0;
}
return (byte) ((bs << 2) | (be >> 4));
} else if (num == 1) {
Byte bs = reMap.get(buffer[g6Index + 1]);
Byte be = reMap.get(buffer[g6Index + 2]);
if (bs == null) {
return null;
}
if (be == null) {
be = 0;
}
return (byte) (((bs & 0x0f) << 4) | (be >> 2));
} else {
Byte bs = reMap.get(buffer[g6Index + 2]);
Byte be = reMap.get(buffer[g6Index + 3]);
if (bs == null) {
return null;
}
if (be == null) {
be = 0;
}
return (byte) (((bs & 0x03) << 6) | be);
}
}
/**
* 从缓存区中取出一个6bit的数据(3byte转成6byte)
*
* @param buffer
* @param index
* 6bit的index
* @return
*/
private static byte getByte826(byte[] buffer, int index) {
int startPos = index * 6;
int endPos = (index + 1) * 6 - 1;
int startAt = startPos / 8; // 在buffer中的位置
byte bs = buffer[startAt]; // 起点所在的字节
int bsi = bs & 0x000000ff;
// start8Pos : 0,6,4,2
int start8Pos = startPos % 8; // 在一个字节中的位置
if (start8Pos == 0 || start8Pos == 2) {
if (start8Pos == 0) {
return (byte) (bsi >> 2);
} else {
return (byte) (bsi & 0x3f);
}
} else {
int endAt = endPos / 8;
byte be = buffer[endAt];
int bei = be & 0x000000ff;
if (start8Pos == 6) {
int h2 = (bsi & 0x03) << 4;
int l4 = bei >> 4;
return (byte) (h2 | l4);
} else {
int h4 = (bsi & 0x0f) << 2;
int l2 = bei >> 6;
return (byte) (h4 | l2);
}
}
}
public static void main(String[] args) throws IOException {
String[] paths = new String[]{"F:/base64/file.doc","F:/base64/file.docx","F:/base64/file.png","F:/base64/file.jpg","F:/base64/file.bmp","F:/base64/AotainDamsPortal.war"};
for(String path : paths) {
File f = new File(path);
if(!f.exists()) {
continue;
}
InputStream is = new FileInputStream(f);
FileOutputStream os = new FileOutputStream(path+"_.txt");
long st = System.currentTimeMillis();
encode(is, os);
os.close();
is.close();
System.out.println(path+":"+(System.currentTimeMillis() - st));
}
for(String path : paths) {
File f = new File(path+"_.txt");
if(!f.exists()) {
continue;
}
InputStream is = new FileInputStream(f);
FileOutputStream os = new FileOutputStream(path.replace("base64", "base64/decode"));
long st = System.currentTimeMillis();
decode(is, os);
os.close();
is.close();
System.out.println(path+":"+(System.currentTimeMillis() - st));
}
}
}
liuzhao2011
- 粉丝: 0
- 资源: 4
最新资源
- 基于Tensorflow的深度学习全部资料+详细文档+优秀项目.zip
- 基于tensorflow的人脸识别全部资料+详细文档+优秀项目.zip
- 基于Tensorflow的中文分词模型全部资料+详细文档+优秀项目.zip
- 基于tensorflow的智能作曲全部资料+详细文档+优秀项目.zip
- 基于Tensorflow的文本内容安全审核全部资料+详细文档+优秀项目.zip
- 基于tensorflow对Marcel静态手势库进行手势识别全部资料+详细文档+优秀项目.zip
- 基于tensorflow的中文文本分类(复旦中文语料)全部资料+详细文档+优秀项目.zip
- 基于TensorFlow的自动化行人检测(人体检测)和监控(视频监控)系统全部资料+详细文档+优秀项目.zip
- 基于Tensorflow和Flask的衣服识别小工具全部资料+详细文档+优秀项目.zip
- 基于tensorflow基于CTPN+Densenet实现的中文文本检测和识别全部资料+详细文档+优秀项目.zip
- 基于TensorFlow和Keras的智能垃圾分类系统,全部资料+详细文档+优秀项目.zip
- 基于tensorflow深度学习的中文的命名实体识别全部资料+详细文档+优秀项目.zip
- 基于TensorFlow进行的视频图像转化照片风格转换全部资料+详细文档+优秀项目.zip
- 企业数字化转化-非结构化数据解决方案 ppt
- 游戏人物检测29-YOLO(v5至v11)、COCO、CreateML、Paligemma、TFRecord、VOC数据集合集.rar
- 基于TensorFlow实现CNN水果检测全部资料+详细文档+优秀项目.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈