1. Base64Utils.java
package password;
import java.io.UnsupportedEncodingException;/**
* Base64Utils 用于对字符串,或者byte数组编码解码。
*
* Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位
* 高位0,组成四个8Bit的字节。其中,每76个字符加一个换行符,原字符串不足三个8Bit字节需进行补齐。
*
* @author QinJiang
*/
public class Base64Utils {
// 默认的字符集
private final static String DEFAULT_CHARSET = "UTF-8";
// 定义一个私有的静态内部类,直接取编码或解码的返回值
private static class Base64UtilsWrapper {
private static Base64Utils instance = new Base64Utils();
}
public static Base64Utils getInstance() {
return Base64UtilsWrapper.instance;
}
private Base64Utils() {
}
// base64码表
private char[] b64CharTable = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/' };
// base64码表的反向表,得到base64 char对应的byte
private final byte chartable[] = new byte[256];
// 构造之前初始化chartable[]中对应的byte
{
for (int i = 0; i < 255; i++) {
chartable[i] = -1;
}
for (int j = 0; j < b64CharTable.length; j++) {
chartable[b64CharTable[j]] = (byte) j;
}
}
/**
* 对未加入盐值的str进行编码。
*
* @param str
* 待编码字符串
* @return 已编码字符串
*/
public static String encodeStr(String str) {
return getInstance().encode(str);
}
/**
* 对指定的字符串照默认的字符集编码。
*
* @param srcString
* 待编码字符串
* @return 已编码字符串
*/
public String encode(String srcString) {
try {
return encode(srcString, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
// 因为UTF-8是存在的,所以肯定不会出现该异常
return "";
}
}
/**
* 对指定的字符串,按照指定的字符集编码。
*
* @param srcString
* 待编码字符串
* @param charset
* 传入的字符集
* @return 已编码字符串
* @throws UnsupportedEncodingException
* 不支持的字符集异常
*/
public String encode(String srcString, String charset)
throws UnsupportedEncodingException {
if ("".equals(srcString) || srcString == null)
return "";
return encode(srcString.getBytes(charset));
}
/**
* 对指定的byte[]编码。
*
* @param srcBytes
* 传入的字节数组
* @return 编码过的字符串
*/
public String encode(byte[] srcBytes) {
try {
return new String(encodeTobyteArray(srcBytes), DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
// 因为UTF-8是存在的,所以肯定不会出现该错误
return "";
}
}
/**
* 对指定的byte[] 编码,返回一个字节数组.
*
* @param srcBytes
* 传入的字节数组
* @return String 编码过的字符串
* @throws UnsupportedEncodingException
* 不支持的字符集
*/
private byte[] encodeTobyteArray(byte[] srcBytes) {
int size = srcBytes.length / 3 * 4 + 4 + srcBytes.length / 38 + 2
+ (srcBytes.length / 3 * 4) / 76;
byte[] tmpBuf = new byte[size];
int destOff = 0, tmpOff = 0;
int col = 0;
int[] inbuf = new int[3];
for (int i = 0; i < srcBytes.length; i++) {
inbuf[tmpOff++] = srcBytes[i];
if (tmpOff == 3) {
tmpBuf[destOff++] = (byte) (b64CharTable[(inbuf[0] & 0xFC) >>> 2]);
tmpBuf[destOff++] = (byte) (b64CharTable[((inbuf[0] & 0x03) << 4)
| ((inbuf[1] & 0xF0) >>> 4)]);
tmpBuf[destOff++] = (byte) (b64CharTable[((inbuf[1] & 0x0F) << 2)
| ((inbuf[2] & 0xC0) >>> 6)]);
tmpBuf[destOff++] = (byte) (b64CharTable[inbuf[2] & 0x3F]);
col += 4;
tmpOff = 0;
if (col >= 76) {
tmpBuf[destOff++] = '\r';
tmpBuf[destOff++] = '\n';
col = 0;
}
}
}
if (tmpOff == 1) {
tmpBuf[destOff++] = (byte) (b64CharTable[(inbuf[0] & 0xFC) >>> 2]);
tmpBuf[destOff++] = (byte) (b64CharTable[(inbuf[0] & 0x03) << 4]);
tmpBuf[destOff++] = '=';
tmpBuf[destOff++] = '=';
} else if (tmpOff == 2) {
tmpBuf[destOff++] = (byte) (b64CharTable[(inbuf[0] & 0xFC) >>> 2]);
tmpBuf[destOff++] = (byte) (b64CharTable[((inbuf[0] & 0x03) << 4)
| ((inbuf[1] & 0xF0) >>> 4)]);
tmpBuf[destOff++] = (byte) (b64CharTable[((inbuf[1]) << 2) & 63]);
tmpBuf[destOff++] = '=';
}
byte[] tmp = new byte[destOff];
System.arraycopy(tmpBuf, 0, tmp, 0, destOff);
return tmp;
}
/**
* 对未加入盐值的字符进行解码。
*
* @param target
* 待解码字符串
* @return 已解码字符串
* @throws Exception
*/
public static String decodeStr(String target) {
try {
String decodeStr = getInstance().decode(target);
return decodeStr;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 对指定的字符串,按照默认的字符集解码。
*
* @param b64String
* 待解码字符串
* @return String 已解码字符串
* @throws UnsupportedEncodingException
* 不支持的字符集
*/
public String decode(String b64String) throws UnsupportedEncodingException {
if ("".equals(b64String) || b64String == null)
return "";
return new String(decode(b64String.getBytes()), DEFAULT_CHARSET);
}
/**
* 对指定的字符串,按照指定的字符集解码。
*
* @param b64String
* 待解码字符串
* @param charset
* 字符集
* @return String 已解码字符串
* @throws UnsupportedEncodingException
* 不支持的字符集
*/
public String decode(String b64String, String charset)
throws UnsupportedEncodingException {
if ("".equals(b64String) || b64String == null)
return "";
return new String(decode(b64String.getBytes()), charset);
}
/**
* 对指定的byte数组,按照指定的字符集编码。
*
* @param b64Bytes
* 待解码字符串
* @return byte[] 已解码的byte数组
*/
public byte[] decode(byte[] b64Bytes) {
// if (b64Bytes == null || b64Bytes.length < 4) {
// throw new InvalidEncodedStrException("The encoded byte is invalid!");
// }
int size = b64Bytes.length / 4 * 3 + 3;
byte[] destBuf = new byte[size];
int destOff = 0;
int bucket = 0;
int available = 0;
for (int i = 0; i < b64Bytes.length; i++) {
// if (!((b64Bytes[i] >= 65 && b64Bytes[i] <= 90) || (b64Bytes[i] >=
// 97 && b64Bytes[i] < 123)
// || (b64Bytes[i] >= 48 && b64Bytes[i] < 58) || (b64Bytes[i] ==
// '+') || (b64Bytes[i] == '/')
// || (b64Bytes[i] == '=') || (b64Bytes[i] == '\n') || (b64Bytes[i]
// == '\r') || (b64Bytes[i] == '\t') || (b64Bytes[i] == ' '))) {
// throw new InvalidEncodedStrException("Illegal encoded
// character!");
// }
int data = chartable[b64Bytes[i]];
if (data >= 0) {
bucket = (bucket << 6) | data;
if (available >= 2) {
available -= 2;
destBuf[destOff++] = (byte) ((bucket >>> available) & 0xFF);
} else {
available += 6;
}
}
}
byte[] rtBuf = new byte[destOff];
System.arraycopy(destBuf, 0, rtBuf, 0, destOff);
return rtBuf;
}
/**
* 对str加入盐值进行编码,使相同的密码拥有不同的hash值。
*
* @param str
* 待解码字符串
* @param salt
* 盐值
* @return 已解码字符串
*/
public static String encodeSalt(String str, String salt) {
return getInstance().encode(str + salt);
}
/**
* 对加入盐值的字符进行解码,使相同的密码拥有不同的hash值
*
* @param target
* 待解码字符串
* @param salt
* 盐值
* @return 已解码字符串
* @throws Exception
*/
public static String decodeSalt(String target, String salt) {
try {
String decodeStr = getInstance().decode(target);
return decodeStr.substring(0, decodeStr.indexOf(salt));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
2. Test.java
package password;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//对账号和密码进行编解码
String pCode = Base64Utils.encodeStr("!QAZ");
System.out.println(pCode);
String pStr = Base64Utils.decodeStr(pCode);
System.out.println(pStr);
}
}