基本算法思维——Base64解码

emmm,分析的是其他大佬的代码,当时自己没有做出来!

 

问题:

给出base64编码后的字符串,有效输出原来的字符串,否则输出Invalid。

 

分析:

(1)明白base64编码的特性(建议手动查资料 )

(2)手动记录base64编码的映射规则,建议使用HashMap,按key-value存储后,查找效率高。

(3)java最小的基本类型为byte,需要使用Integer提供的方法奇妙达到处理位的目的。

  1、Integer.toBinaryString:将无符号整形数字转换为二进制形式忽略前导0.

  2、 Integer.parseInt :将制定进制形式的字符串恢复为整型。

  3、new Integer().byteValue:将整型转换为byte,只取低8位。

(4)巧妙运用char于byte之间的转换关系。

 

code:

 1 import java.util.HashMap;
 2 import java.util.Scanner;
 3 /*
 4 Base64编码的解析
 5  */
 6 public class Main {
 7     
 8 
 9         public static HashMap<Character, Integer> encodeTable = new HashMap<>();
10 
11         public static void main(String[] args) {
12             encodeTable = createEncodeTable();
13 
14             Scanner scanner = new Scanner(System.in);
15             int n = scanner.nextInt();
16             String[] strs = new String[n];
17 
18             for (int i = 0; i < n; i++) {
19                 strs[i] = scanner.next();
20             }
21             for (int i = 0; i < n; i++) {
22                 System.out.println(decode(strs[i]));
23             }
24             scanner.close();
25             
26             
27         }
28 
29         /**
30          * 记录Base64的映射表
31          * @return
32          */
33         public static HashMap<Character, Integer> createEncodeTable() {
34             HashMap<Character, Integer> table = new HashMap<>();
35             //0-63
36             int j = 0;
37             for (char i = '0'; i <= '9'; i++) {
38                 table.put(i, j++);
39             }
40             table.put('+', j++);
41             table.put('-', j++);
42             for (char i = 'a'; i <= 'z'; i++) {
43                 table.put(i, j++);
44             }
45             for (char i = 'A'; i <= 'Z'; i++) {
46                 table.put(i, j++);
47             }
48 
49             return table;
50         }
51 
52         /**
53          *     
54          * @param str
55          * @return
56          */
57         public static String decode(String str) {
58             StringBuilder end=new StringBuilder();
59             StringBuilder tmp=new StringBuilder();
60             
61             //不是64的倍数为非法
62             if (str.length() % 4 == 0) {
63                 while (str.contains("=")) {
64                     str = str.substring(0, str.length() - 1);
65                 }
66                 byte[] bytes = new byte[str.length()];
67                 char[] chars = str.toCharArray();
68                 for (int i = 0; i < str.length(); i++) {
69                     //将数字转换成对应的byte字节数组
70                     bytes[i]=encodeTable.get(chars[i]).byteValue();
71                     //将无符号整数以二进制形式表达,忽略前导0。
72                     StringBuilder stringBuilder=new StringBuilder(Integer.toBinaryString(bytes[i]));
73                     
74                     //补齐至6位,恢复到Base64分割前的状态 
75                     while (stringBuilder.length()<6){
76                         stringBuilder.insert(0,0);
77                     }
78                     tmp.append(stringBuilder);
79                 }
80 
81             } else {
82                 end.append("Invalid");
83             }
84             //恢复到原始数据,且自动忽略尾部添加的0(尾部只会添加4或2个0)
85             for (int i=0;i<=tmp.length()-8;i=i+8){
86                 char d= (char) Integer.parseInt(tmp.substring(i,i+8),2);
87                 end.append(d);
88             }
89 
90             return end.toString();
91         }
92         
93         
94 }

 

posted @ 2020-04-29 09:36  Yrc的楚门的世界  阅读(217)  评论(0)    收藏  举报