base64 自定义码表 实现加密解密
2015-03-30 13:16
357 查看
简介:
base64 是在加密过程对byte转换为string的一个过程,解密过程则是对string转换为byte的过程。算法:
byte转换:
1、将原byte 由3个,3个分成一组, 不足3个的为一组2、将3个byte,一次统一右移两位,然后高位补两个0 , 剩下的补上前一个字节移出来的字符(2个 4个或者6个bit)。这样3个byte一组会统一转成4个byte一组。
3、不足3个的一组 出来的 在4个byte中以‘=’的byte值填充。
4个一组的byte 到 string的转换:
1、构造码表(加密表与解密表)2、加密表构造原则:加密表的长度是64,加密表的值(ascii码值)是解密表的索引
3、解密表构造原则:长度一般为128,解密表的值是加密表的索引
4、根据4个一组(由于前两位为0,所以最大值是 2^6 - 1)的byte值 用加密表得到字母值
5、通过字母值作为索引用解密表 得到4个一组的byte
6、将4个一组的byte 逆变换会 3个一组的byte
7、然后byte再到其他数据结构如(字符串,文件等等)
实现一套简易的带自定义码表和移位操作的base64:
package base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; /** * Created by hp on 15-3-29. */ public class NewBase64 { private Logger logger = LoggerFactory.getLogger(NewBase64.class); private static final int RANGE = 0xff; //自定义码表 可随意变换字母排列顺序,然后会自动生成解密表 private static final char[] Base64ByteToStr = new char[] { 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',// 0 ~ 9 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',// 10 ~ 19 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',// 20 ~ 29 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',// 30 ~ 39 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',// 40 ~ 49 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',// 50 ~ 59 '8', '9', '+', '/'// 60 ~ 63 }; private static byte[] StrToBase64Byte = new byte[128]; private void generateDecoder() throws Exception { 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; } } 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 = ""; } } } private String Base64Encode(byte[] bytes) throws Exception { StringBuilder res = new StringBuilder(); //per 3 bytes scan and switch to 4 bytes for(int i = 0; i <= bytes.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) <= bytes.length - 1) { enBytes[k] = (byte) (((((int) bytes[i + k] & RANGE) >>> (2 + 2 * k))) | (int)tmp);//note , we only get 0 ~ 127 ??? tmp = (byte) (((((int) bytes[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('='); } } } return res.toString(); } private byte[] Base64Decode(String val) throws Exception { ByteArrayOutputStream bos = new ByteArrayOutputStream();//destination bytes, valid string that we want byte[] srcBytes = val.getBytes(); byte[] base64bytes = new byte[srcBytes.length]; //get the base64 bytes (the value is -1 or 0 ~ 63) for(int i = 0; i <= srcBytes.length - 1; i++) { int ind = (int) srcBytes[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(); } public static void main(String[] args) throws Exception { NewBase64 nb = new NewBase64(); nb.generateDecoder(); //String srcStr = "testfewa,./;'p[097&^%$$##!@#FDGSERH中国测试中文"; // String srcStr = "{\\\"name\\\":\\\"vicken\\\",\\\"age\\\":20 }"; String srcStr = "中文输入"; System.out.println(" source:" + srcStr); String enStr = nb.Base64Encode(srcStr.getBytes()); System.out.println("encoder:" + enStr); String deStr = new String(nb.Base64Decode(enStr)); System.out.println("decoder:" + deStr); } }
相关文章推荐
- 利用java自带的base64实现加密、解密
- go语言/golang实现base64加密解密
- JS实现的3des+base64加密解密算法完整示例
- Base64实现加密、解密
- 用SQL实现的BASE64加密及解密函数(SQL2005以上有效)
- base64加密解密算法 C实现(转载)
- Java实现Base64给文件加密、解密
- 基于Java实现的Base64加密、解密原理代码
- 用C#实现Base64处理,加密解密,编码解码
- 利用java自带的base64实现加密、解密
- C# 下base64加密解密实现
- Base64加密解密原理以及代码实现
- base64加密,解密,encode,decode,编码详解+实现
- base64加密与解密Java实现
- JS实现base64加密解密
- C# 下base64加密解密实现
- Python 实现base64加密和解密
- ASP.NET 实现Base64加密和解密
- Base64加密解密原理以及代码实现
- 实现BASE64加密、解密算法