前言
在写HTTP服务器的过程中,需要解析表单信息,表单里的中文可能会被以十六进制编码,也可能会以base64编码,总之就是需要解码,顺便写了几个编码和解码器
一、二进制编码类
用来把单个byte或者byte数组转成8位2进制字符串(11110000)的形式输出
/**
* @author ARCO
*/
public class BinaryCoder {
public static String byteToBinary(byte b) {
StringBuffer sb = new StringBuffer(8);
for(int i = 0; i < 8; i++) {
int tmpb = b & 0x01;
b = (byte) (b >> 1);
sb.append(tmpb);
}
return new String(sb.reverse());
}
public static String byteArrayToBinary(byte[] barray) {
StringBuffer sb = new StringBuffer(barray.length * 9);
for(int i = 0; i < barray.length; i++) {
StringBuffer tmpsb = new StringBuffer(9);
for(int j = 0; j < 8; j++) {
int tmpb = barray[i] & 0x01;
barray[i] = (byte) (barray[i] >> 1);
tmpsb.append(tmpb);
}
tmpsb.reverse();
tmpsb.append(" ");
sb.append(tmpsb);
}
return new String(sb);
}
}
二、Base64编码类
对JDK提供的Base64编码工具简单的封装了一下
import java.io.UnsupportedEncodingException;
import java.util.Base64;
public class Base64Coder {
private static String charset = "UTF-8";
//这个方法用来修改编码字符集,默认字符集是UTF-8
public static void setCharset(String cs) {
charset = cs;
}
public static String defaultEncode(String str) throws UnsupportedEncodingException {
Base64.Encoder encoder = Base64.getEncoder();
//将字符串按UTF-8解码,然后返回一个byte数组
byte[] codeArray = encoder.encode(str.getBytes(charset));
//将byte数组重建成String
String codeStr = new String(codeArray, charset);
return codeStr;
}
public static String urlEncode(String str) throws UnsupportedEncodingException {
Base64.Encoder encoder = Base64.getUrlEncoder();
//或者直接利用Base64类提供的encodeToString方法
String codeStr = encoder.encodeToString(str.getBytes(charset));
return codeStr;
}
public static String mimeEncode(String str) throws UnsupportedEncodingException {
Base64.Encoder encoder = Base64.getMimeEncoder();
String codeStr = encoder.encodeToString(str.getBytes(charset));
return codeStr;
}
public static String defaultDecode(String code) throws UnsupportedEncodingException {
Base64.Decoder decoder = Base64.getDecoder();
//解码的结果是个byte数组,用String的构造方法,以UTF-8编码对其重建
String res = new String(decoder.decode(code), charset);
return res;
}
public static String urlDecode(String code) throws UnsupportedEncodingException {
Base64.Decoder decoder = Base64.getUrlDecoder();
String res = new String(decoder.decode(code), charset);
return res;
}
public static String mimeDecode(String code) throws UnsupportedEncodingException {
Base64.Decoder decoder = Base64.getMimeDecoder();
String res = new String(decoder.decode(code), charset);
return res;
}
}
三、十六进制编码类
用来解析表单中用十六进制格式(%E4这样的)表示的中文,字符集为UTF-8。可以将%E4%B8%AD%E6%96%87这种类型的编码解析为中文,也可以将中文解析成这种类型的编码。
import java.io.UnsupportedEncodingException;
/**
* @author ARCO
*/
public class HexCoder {
public static String urlHexToString(String hexString) throws UnsupportedEncodingException {
String s = hexString.replaceAll("%", "");
//创建存储解码所得byte的数组
byte[] resArray = new byte[s.length() / 2];
for(int i = 0; i < s.length(); i += 2) {
byte b1, b2;
b1 = (byte) Character.getNumericValue(s.charAt(i));
b2 = (byte) Character.getNumericValue(s.charAt(i + 1));
//b1是字节的高四位
resArray[i / 2] = (byte)((b1 << 4) + b2);
}
return new String(resArray, "UTF-8");
}
public static String urlStringToHEX(String str) throws UnsupportedEncodingException {
int value;
byte[] utf8Array = str.getBytes("UTF-8");
StringBuffer sb = new StringBuffer(utf8Array.length);
//newArray的一位包括两位十六进制,为了方便添加%分隔符
for(int i = 0; i < utf8Array.length; i++) {
value = (256 + utf8Array[i]);
//首先添加分隔符
sb.append("%");
sb.append(Integer.toHexString(value).toUpperCase());
}
//生成String对象
String res = new String(sb);
return res;
}
}
四、GZIP压缩类
传入文件路径,可以返回一个gzip压缩后的byte数组,也可以直接在指定路径生成压缩后的文件。
package coder;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
/**
* @author ARCO
*/
public class GZIPCoder {
public static byte[] compressToByteArray(String url) throws IOException {
byte[] fileArray;
byte[] gzipArray;
//打开目标文件
File file = new File(url);
fileArray = new byte[(int)file.length()];
//把目标文件读到byte数组
FileInputStream fis = new FileInputStream(file);
fis.read(fileArray);
fis.close();
//创建GZIP输出流,把fileArray写到GZIP流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(fileArray);
//必须关闭GZIP输出流,不然压缩会出问题
gzos.close();
gzipArray = baos.toByteArray();
return gzipArray;
}
public static void compressToFile(String source, String target) throws IOException {
byte[] gzipArray = compressToByteArray(source);
FileOutputStream fos = new FileOutputStream(target);
fos.write(gzipArray);
fos.close();
}
}