【算法记录】Java - Base64编码解码源码
Base64编码表
索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 |
---|---|---|---|---|---|---|---|
0 | A | 17 | R | 34 | i | 51 | z |
1 | B | 18 | S | 35 | j | 52 | 0 |
2 | C | 19 | T | 36 | k | 53 | 1 |
3 | D | 20 | U | 37 | l | 54 | 2 |
4 | E | 21 | V | 38 | m | 55 | 3 |
5 | F | 22 | W | 39 | n | 56 | 4 |
6 | G | 23 | X | 40 | o | 57 | 5 |
7 | H | 24 | Y | 41 | p | 58 | 6 |
8 | I | 25 | Z | 42 | q | 59 | 7 |
9 | J | 26 | a | 43 | r | 60 | 8 |
10 | K | 27 | b | 44 | s | 61 | 9 |
11 | L | 28 | c | 45 | t | 62 | + |
12 | M | 29 | d | 46 | u | 63 | / |
13 | N | 30 | e | 47 | v | ||
14 | O | 31 | f | 48 | w | ||
15 | P | 32 | g | 49 | x | ||
16 | Q | 33 | h | 50 | y |
Base64基本原理
- 一、要编码的数据3个byte为一组,共3*8=24个bit
- 二、24个bit每6个一组,共分为四组
- 三、6位所表示数字的最大值为(2 ^ 6) - 1 = 63,刚好对应上面的编码表,即3个byte的原始数据编码后得到4个byte的数据
- 四、如果要编码的数据长度不是3的倍数,即最后一组数据凑不出24个bit,那么在最后面补位0
tips:
// 要编码的数据 String src = "mengxin"; // 对应的字节数组 byte[] src = new byte[]{109, 101, 110, 103, 120, 105, 110} // 要编码的数据长度为7,前面的[109, 101, 110, 103, 120, 105]正常编码,后面剩下一个110对应的二进制为01101110 // 补0后得到011011100000000000000000 // 每6位为一组,共四组 // (1) 011011:对应的数字为27,这一组含有原本的位,所以正常查找编码表 // (2) 100000:对应的数字为32,这一组含有原本的位,所以正常查找编码表 // (3) 000000:对应的数字为0,这一组完全是由补位得到的,所以填充“=” // (4) 000000:对应的数字为0,这一组完全是由补位得到的,所以填充“=” // 解码原理相同,逆推即可
这里有一个动画讲解教程:
【【动画密码学】Base64编码&解码算法】https://www.bilibili.com/video/BV1Hp4y1g7Ex/?share_source=copy_web&vd_source=2c801bab51441760fc5e8a76d502c656
这里是我练习的编码解码源代码,比较简陋,仅作为理解使用,开发环境还是使用别人开发好的
- 没有进行细节处理,不喜勿喷,我的算法能力确实比较差
import java.io.ByteArrayOutputStream; public class Base64 { private static final String Base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; public static void main(String[] args) throws Exception { System.out.println(Encode("mengxin".getBytes())); System.out.println(new String(Decode("bWVuZ3hpbg=="))); } /** * Base64编码 * @param src 要编码的数据 * @return Base64编码后的字符串 */ public static String Encode(byte[] src) { int paddings = src.length % 3; StringBuffer sb = new StringBuffer(); int i = 0; for (; i < src.length - paddings; i += 3) { sb.append(Base64EncodeChars.charAt(src[i] >> 2)); sb.append(Base64EncodeChars.charAt(((src[i] & 3) << 4) | (src[i + 1] >> 4))); sb.append(Base64EncodeChars.charAt(((src[i + 1] & 15) << 2) | (src[i + 2] >> 6))); sb.append(Base64EncodeChars.charAt(src[i + 2] & 63)); } if (paddings == 2) { sb.append(Base64EncodeChars.charAt(src[i] >> 2)); sb.append(Base64EncodeChars.charAt(((src[i] & 3) << 4) | (src[i + 1] >> 4))); sb.append(Base64EncodeChars.charAt((src[i + 1] & 15) << 2)); sb.append("="); } else if (paddings == 1) { sb.append(Base64EncodeChars.charAt(src[i] >> 2)); sb.append(Base64EncodeChars.charAt((src[i] & 3) << 4)); sb.append("="); sb.append("="); } return sb.toString(); } /** * Base64解码 * @param src 要解码的字符串 * @return Base64解码后的数据 */ public static byte[] Decode(String src) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i = 0; for (; i < src.length() - 4; i += 4) { int i1 = Base64EncodeChars.indexOf(src.charAt(i)); int i2 = Base64EncodeChars.indexOf(src.charAt(i + 1)); int i3 = Base64EncodeChars.indexOf(src.charAt(i + 2)); int i4 = Base64EncodeChars.indexOf(src.charAt(i + 3)); baos.write((i1 << 2) | (i2 >> 4)); baos.write(((i2 & 15) << 4) | (i3 >> 2)); baos.write(((i3 & 3) << 6) | i4); //System.out.println(i1 + "|" + i2 + "|" + i3 + "|" + i4); } int i1 = Base64EncodeChars.indexOf(src.charAt(i)) << 2 | (Base64EncodeChars.indexOf(src.charAt(i + 1)) >> 4); if ('=' == src.charAt(i + 2)){ baos.write(i1); } else { int i2 = (Base64EncodeChars.indexOf(src.charAt(i + 1)) << 4) | (Base64EncodeChars.indexOf(src.charAt(i + 2)) >> 2); if ('=' == src.charAt(i + 3)) { baos.write(i1); baos.write(i2); } else { baos.write(i1); baos.write(i2); baos.write((Base64EncodeChars.indexOf(src.charAt(i + 2)) << 6) | (Base64EncodeChars.indexOf(src.charAt(i + 3)))); } } return baos.toByteArray(); } }
分类:
编程语言 / 算法记录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理