public class MyBase64 implements Codec {
private final static Logger LOGGER = LoggerFactory.getLogger(MyBase64.class);
private final static String STANDARD_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
private static final int RANGE = 0xff;
private final String alphabet;
private char[] base64ByteToStr;
private byte[] strToBase64Byte = new byte[128];
public MyBase64(String alphabet) {
this.alphabet = alphabet;
init();
}
private void init() {
base64ByteToStr = alphabet.toCharArray();
for (int i = 0; i <= strToBase64Byte.length - 1; i++) {
strToBase64Byte[i] = -1;
}
for (int i = 0; i <= base64ByteToStr.length - 1; i++) {
strToBase64Byte[base64ByteToStr[i]] = (byte) i;
}
}
/**
* 加密
*
* @param bytesToEncode
* @return
*/
@Override
public byte[] encode(byte[] bytesToEncode) {
StringBuilder res = new StringBuilder();
//per 3 bytes scan and switch to 4 bytes
for (int i = 0; i <= bytesToEncode.length - 1; i += 3) {
byte[] enBytes = new byte[4];
byte tmp = (byte) 0x00;// save the right move bit to next position's bit
//3 bytes to 4 bytes
for (int k = 0; k <= 2; k++) {// 0 ~ 2 is a line
if ((i + k) <= bytesToEncode.length - 1) {
enBytes[k] = (byte) (((((int) bytesToEncode[i + k] & RANGE) >>> (2 + 2 * k))) | (int) tmp);//note , we only get 0 ~ 127 ???
tmp = (byte) (((((int) bytesToEncode[i + k] & RANGE) << (2 + 2 * (2 - k))) & RANGE) >>> 2);
} else {
enBytes[k] = tmp;
tmp = (byte) 64;//if tmp > 64 then the char is '=' hen '=' -> byte is -1 , so it is EOF or not print char
}
}
enBytes[3] = tmp;//forth byte
//4 bytes to encode string
for (int k = 0; k <= 3; k++) {
if ((int) enBytes[k] <= 63) {
res.append(base64ByteToStr[(int) enBytes[k]]);
} else {
res.append('=');
}
}
}
try {
return res.toString().getBytes(CharsetUtil.UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* 解密
*
* @param bytesEncoded
* @return
*/
@Override
public byte[] decode(byte[] bytesEncoded) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();//destination bytes, valid string that we want
byte[] base64bytes = new byte[bytesEncoded.length];
//get the base64 bytes (the value is -1 or 0 ~ 63)
for (int i = 0; i <= bytesEncoded.length - 1; i++) {
int ind = (int) bytesEncoded[i];
base64bytes[i] = strToBase64Byte[ind];
}
//base64 bytes (4 bytes) to normal bytes (3 bytes)
for (int i = 0; i <= base64bytes.length - 1; i += 4) {
byte[] deBytes = new byte[3];
int delen = 0;// if basebytes[i] = -1, then debytes not append this value
byte tmp;
for (int k = 0; k <= 2; k++) {
if ((i + k + 1) <= base64bytes.length - 1 && base64bytes[i + k + 1] >= 0) {
tmp = (byte) (((int) base64bytes[i + k + 1] & RANGE) >>> (2 + 2 * (2 - (k + 1))));
deBytes[k] = (byte) ((((int) base64bytes[i + k] & RANGE) << (2 + 2 * k) & RANGE) | (int) tmp);
delen++;
}
}
for (int k = 0; k <= delen - 1; k++) {
bos.write((int) deBytes[k]);
}
}
return bos.toByteArray();
}
private void showDecoder() throws Exception {
String str = "";
for (int i = 1; i <= strToBase64Byte.length; i++) {
str += (int) strToBase64Byte[i - 1] + ",";
if (i % 10 == 0 || i == strToBase64Byte.length) {
LOGGER.info(str);
str = "";
}
}
}
/**
* 随机一个 Alphabet
*
* @return
*/
public static String randomAlphabet() {
StringBuilder temp = new StringBuilder(STANDARD_ALPHABET);
StringBuilder out = new StringBuilder();
while (true) {
int size = temp.length();
if (size <= 0) {
break;
}
int index = RandomUtil.randomInt(size);
out.append(temp.charAt(index));
temp.deleteCharAt(index);
}
return out.toString();
}
}
java自定义base64
最新推荐文章于 2024-08-13 10:21:34 发布