base64加密原理代码实现
发布日期:2021-06-30 18:40:03 浏览次数:3 分类:技术文章

本文共 10476 字,大约阅读时间需要 34 分钟。

/*Conversion.java*/import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;/** * @创建者 CSDN_LQR * @创建时间 2016-5-19 下午9:06:43 * @描述 base64加密原理代码实现 */public class Conversion {
private static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; public static String byteToHexString(byte b) { int n = b; if (n < 0) n = 256 + n; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } //######################### 以下是base64加密原理实现 begin ############################## public static String byteArrayToHexString(byte[] b) { String result = ""; for (int i = 0; i < b.length; ++i) result += byteToHexString(b[i]); return result; } // 创建base64对应的map public static Map
base64Map = new HashMap
(); static { // 前26个 for (int i = 0; i < 26; i++) { base64Map.put(i, String.valueOf(Character.valueOf((char) ('A' + i)))); } // 再26个 int j = 0; for (int i = 0; i < 26; i++) { base64Map.put(26 + i, String.valueOf(Character.valueOf((char) ('a' + j++)))); } // 再10个数字 j = 0; for (int i = 0; i < 10; i++) { base64Map.put(52 + i, String.valueOf(Character.valueOf((char) ('0' + j++)))); } // 最后添加2个符号 base64Map.put(62, "+"); base64Map.put(63, "/"); } /** * 将byte转成bit[] * * @param b * @return */ public static byte[] byteToBitArr(byte b) { byte[] bitArr = new byte[8]; for (int i = 0; i < 8; i++) { bitArr[i] = (byte) ((b >> 7 - i) & 0x1); } return bitArr; } /** * 将byte[]转成bit[] * * @param bArr * @return */ public static byte[] byteArrToBitArr(byte[] bArr) { ArrayList
list = new ArrayList
(); for (int i = 0; i < bArr.length; i++) { byte[] bitArr = byteToBitArr(bArr[i]); list.add(bitArr); } byte[] bitAtt = new byte[list.size() * 8]; for (int i = 0; i < list.size(); i++) { // 得到要填充的起始位置 int begin = 8 * i; byte[] bs = list.get(i); for (int j = 0; j < bs.length; j++) { bitAtt[begin++] = bs[j]; } } return bitAtt; } /** * 把二进制字节数组转按Base64进行编码 * * @param b * 二进制字节数组 * @return 按Base64编码的字符串 */ public static String byteArrayToBase64String(byte[] b) { // ===================1、计算有效的base64字符的个数 ===================== // 得到二进制数的全部位数 int len = b.length * 8; // 记录原先位数除6得到的整数,如果有余数,说明长度要补位,base64正确转换次数要加1 int changeCount; if (len % 6 != 0) { changeCount = len / 6 + 1; } else { changeCount = len / 6; } // System.out // .println("1、计算最后有效的base64字符的个数为:changeCount = " + changeCount); // ===================2、计算当前需要补充的bit位的个数,及位数总长 ===================== // 得到要被6整除的需要补多少位 int temp = len; while (temp % 6 != 0) { temp += 8; } // System.out.println("2、计算当前需要补充的bit位的个数为:" + (temp - len) // + ",当前总的位数是:temp = " + temp); // ===================3、计算最终经base64编码后会得到的字符数 ===================== // 记录得到补位后能整除6的数 int nowCount = temp / 6; // System.out.println("3,计算补位后,最终经base64编码后会得到的字符数为:nowCount = " // + nowCount); // ===================4、创建对应补位后长度的字节数组,补充最后补位字节为0 ===================== // 创建新的二进制数组(已经补位) byte[] b1 = new byte[temp / 8]; // System.out.println("4、因为总的bit有" + temp + "位,所以创建一个存放" + temp / 8 // + "个字节的byte[],然后对该byte[]进行原数据填充及补位0数据填充"); // 填充该二进制数组数据 for (int i = 0; i < b.length; i++) { b1[i] = b[i]; } for (int i = b.length; i < temp / 8; i++) { b1[i] = 0; } // System.out.println(); // System.out.println("\t#####原先字节数组的数据#####"); // System.out.print("\t"); for (byte b2 : b) { // System.out.print(b2 + " "); } // System.out.println("对应的bit为:"); // System.out.print("\t"); for (int i = 0; i < byteArrToBitArr(b).length; i++) { byte b2 = byteArrToBitArr(b)[i]; // System.out.print(b2 + ""); if ((i + 1) % 8 == 0) { // System.out.print(" "); } } // System.out.println("\n"); // System.out.println("\t#####新的字节数组的数据#####"); // System.out.print("\t"); for (byte b2 : b1) { // System.out.print(b2 + " "); } // System.out.println("对应的bit为:"); // System.out.print("\t"); for (int i = 0; i < byteArrToBitArr(b1).length; i++) { byte b2 = byteArrToBitArr(b1)[i]; // System.out.print(b2 + ""); if ((i + 1) % 8 == 0) { // System.out.print(" "); } } // System.out.println("\n"); // ===================5、根据所有的bit,每6位计算值后,对表查值(base64核心),最后拼接成加密后的字符串===================== byte[] byteArrToBitArr = byteArrToBitArr(b1); String base64Str = ""; // System.out.println("5、循环" + nowCount + "次,每次计算6个bit的总值"); for (int i = 0; i < nowCount; i++) { int begin = 6 * i; // System.out.println("\t>>循环第" + i + "次,起始位置是:" + begin); int sixCount = 0; if (i < changeCount) { for (int j = 0; j < 6; j++) { sixCount += (byteArrToBitArr[begin++]) << (5 - j); } base64Str += base64Map.get(sixCount); // System.out.println("\t得到当前6个bit的总值(sixCount)是:" + sixCount // + ",对表查值结果为:" + base64Map.get(sixCount)); } else { base64Str += "="; // System.out.println("\t这次是补位部分,结果为:="); } } // System.out.println(); // System.out.println("得到的总的base64加密的字符串为:base64Str为: \"" + base64Str // + "\""); return base64Str; } /** * 把Base64字符转换为字节数组 * * @param s * 按照Base64编码的字符 * @return 二进制字节数组 */ public static byte[] base64StringToByteArray(String s) { // 记录=号的个数 int equalCount = 0; // 存放bit[]的集合 ArrayList
list = new ArrayList
(); // ===================1、对传入字条串进行字符拆分 ===================== // 把字符串切割成多个单个的Char char[] charArray = s.toCharArray(); // System.out.print("1、对" + s + "进行字符拆分,结果为:"); for (int i = 0; i < charArray.length; i++) { // System.out.print(charArray[i] + " "); } // ===================2、对每个字符进行对表查键 ===================== // System.out.println(); // System.out.println("2、对每个字符进行对表查键"); // 遍历每个char for (int i = 0; i < charArray.length; i++) { // 如果是=就equalCount加1 if (charArray[i] == '=') { equalCount++; // System.out.println("\t>>当前字符是=号,=号计数器(equalCount)加1"); // 如果是别的char } else { // 则遍历map,得到char对应map中的key for (Entry
entry : base64Map.entrySet()) { if (entry.getValue().equals(String.valueOf(charArray[i]))) { int key = entry.getKey(); // 把key转成byte byte bK = (byte) key; // 再把byte转成bit[],并添加到bit[]集合中 list.add(byteToBitArr(bK)); // System.out.println("\t>>当前字符是" + charArray[i] // + ",对表查键结果为:" + key); } } } } // System.out.println(); // ===================3、根据字符数组长度 * 6,计算出总的bit位数 ===================== // 计算所有bit的个数 int allCount = charArray.length * 6; // 创建一个存放bit的数组 byte[] bArr = new byte[allCount]; // System.out.println("3、根据字符数组长度 * 6,计算出总的bit位数为:" + allCount // + ",创建对应长度的bit数组bArr"); // ===============4、把有效的字符转换成bit数组,保存到bit数组bArr中 ================= // 把list中的bit[]遍历后,取后6位保存到bArr中 // System.out.println("4、把上面对表查键得到的" + list.size() + "个键转换成" + // list.size() // + " * 6位的bit,依次填充到bit数组中"); for (int i = 0; i < list.size(); i++) { byte[] cs = list.get(i); int begin = 6 * i; for (int j = 0; j < cs.length - 2; j++) { bArr[begin++] = cs[2 + j]; } } // ===============5、根据=号的个数,用0填充完bit数组bArr ================= // 再根据=号的个数,把后面的0填充上 for (int i = 0; i < equalCount * 6; i++) { bArr[allCount - 1 - i] = 0; } // System.out.println("5,根据=号的个数,用" + (equalCount * 6) + "个0填充完bit数组"); // System.out.println(); // System.out.println("\t#####填充完得到的bit数组是:#####"); // System.out.print("\t"); for (int i = 0; i < bArr.length; i++) { // System.out.print(bArr[i]); if ((i + 1) % 8 == 0) { // System.out.print(" "); } } // ============6、根据=号的个数,计算未加密原字节数组的bit位数,并创建bit数组tempArr ============== // 未经base64编码前的字节个数 int byteCount = (bArr.length - equalCount * 8) / 8; byte[] tempArr = new byte[bArr.length - equalCount * 8]; // System.out.println("\n"); // System.out.println("6、因为=号有" + equalCount + "个,说明之前多补充了" + equalCount // + "个字节(" + equalCount * 8 + "个bit位)。计算出原先只有" // + (bArr.length - equalCount * 8) + "位,即" + byteCount // + "个字节,故创建一个长度为" + (bArr.length - equalCount * 8) // + "的bit数组tempArr"); // ============7、用bit数组bArr中前面所有有效的bit填充bit数组tempArr ============== for (int i = 0; i < tempArr.length; i++) { tempArr[i] = bArr[i]; } // System.out.println("7、将bit数组bArr的前" + (bArr.length - equalCount * 8) // + "位存入到bit数组finalArr中"); // System.out.println(); // System.out.println("\t#####填充完得到的最终bit数组finalArr是:#####"); // System.out.print("\t"); for (int i = 0; i < tempArr.length; i++) { // System.out.print(tempArr[i]); if ((i + 1) % 8 == 0) { // System.out.print(" "); } } // System.out.println(); // ============8、对bit数组tempArr进行每8位计算总值后保存到字节数组finalArr中 ============== byte[] finalArr = new byte[byteCount]; // System.out.println(); // System.out.println("8、循环" + byteCount + "次,每次计算8个bit的总值"); for (int i = 0; i < byteCount; i++) { int begin = 8 * i; // System.out.print("\t>>循环第" + i + "次,起始位置是:" + begin); byte eightCount = 0; for (int j = 0; j < 8; j++) { eightCount += (tempArr[begin++]) << (7 - j); } // System.out.println(",结果为:" + eightCount); finalArr[i] = eightCount; } return finalArr; } public static void main(String[] args) { // base64加密解密演示 String str = "X"; System.out .println("######################################进行Base64加密######################################"); String base64String = byteArrayToBase64String(str.getBytes()); for (int i = 0; i < 4; i++) { System.out.println(); } System.out .println("######################################进行Base64解密######################################"); base64StringToByteArray(base64String); }}

转载地址:https://linqiarui.blog.csdn.net/article/details/51457082 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截
下一篇:用NotificationCompat创建Notification

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月26日 02时27分22秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

MySQL 2019-04-30
Redis 2019-04-30
JVM 2019-04-30
Java开发中的23种设计模式详解 2019-04-30
java面试高频知识点 2019-04-30
Java多线程 2019-04-30
Java虚拟机 2019-04-30
Java异常 2019-04-30
Java基础 2019-04-30
JavaStream 2019-04-30
查找算法 2019-04-30
二叉树 2019-04-30
红黑树 2019-04-30
基本数据结构 2019-04-30
排序算法 2019-04-30
常用数据结构特点 2019-04-30
图算法 2019-04-30
字符串相关 2019-04-30
Elasticsearch 2019-04-30
ElasticSearch:Kibana中DevTools的使用 2019-04-30