记录一下最近项目中用到的关于 字符串压缩解压 和 Base64加密 的相关内容
需求是后台 socket 传回来的数据是经过压缩和Base64加密的
1、Base64解密(这里介绍三种方式)
- JDK 中 sun.misc 套件下的 BASE64Encoder 和 BASE64Decoder
- Apache Commons Codec 提供的 Base64的编码与解码功能,用到 org.apache.commons.codec.binary 包下的Base64类
- Java 8 之后,在 Java.util 包中提供了 Base64 解码的类
第一种:
/*sun.misc 解密*/
public static final String sunDecode(String str) throws Exception {
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = decoder.decodeBuffer(str);
return new String(decompress(bytes));
}
第二种:
// Apache 解码
public static String decode(String str) throws IOException {
final Base64 base64 = new Base64();
/*final byte[] textByte = str.getBytes();
//编码
final String encodedText = base64.encodeToString(textByte);*/
//解码
return new String(decompress(base64.decodeBase64(str)));
}
第三种:
final Base64.Decoder decoder = Base64.getDecoder();
new String(decoder.decode(“需要解密的字符串”), "UTF-8")
第一种方法效率太低,不建议使用
第三种方法需要 Android 系统版本在 Android O及以上,从适配的角度来看,在目前也不是个理想的处理方式
所以采用第二种是我目前觉得比较好的。但是 Android 中使用包需要注意一点,编译的时候会报错,原因是 “org.apache.commons.codec.binary.Base64” 与 Android FrameWork 中的包名一样导致冲突。(我的解决方法是修改 commons codec 包的包名,通过 jarjar.jar 这个软件就可以实现,具体操作大家可以自行百度,这里就不贴步骤了)
2、关于字符串压缩和解压(背景:后台压缩用的是 php 的 gzdeflate() 方法,这个方法第三个参数接收一个控制压缩格式的参数
ZLIB_ENCODING_RAW 对应于纯DEFLATE格式;
ZLIB_ENCODING_GZIP 对应于GZIP格式;
ZLIB_ENCODING_DEFLATE 对应于ZLIB格式)
(注意:解压时要用对应格式的解压方法,否则解压完会是乱码)下面附上 GZIP 和 ZLIB 的解压代码
/* GZIP 解压*/
public static String unCompress(String str) throws IOException {
if (null == str || str.length() <= 0) {
return str;
}
// 创建一个新的 byte 数组输出流
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组
ByteArrayInputStream in = new ByteArrayInputStream(str
.getBytes("UTF-8")); //ISO-8859-1
// 使用默认缓冲区大小创建新的输入流
GZIPInputStream gzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n = 0;
while ((n = gzip.read(buffer)) >= 0) {// 将未压缩数据读入字节数组
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte数组输出流
out.write(buffer, 0, n);
}
// 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串
return out.toString("UTF-8");
}
/*zlib 解压*/
//解压缩 字节数组
public static byte[] decompress(byte[] data) {
byte[] output = new byte[0];
Inflater decompresser = new Inflater();
decompresser.reset();
decompresser.setInput(data);
ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!decompresser.finished()) {
int i = decompresser.inflate(buf);
o.write(buf, 0, i);
}
output = o.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
decompresser.end();
return output;
}