Base64 编码原理详解
Base64 是一种将 二进制数据编码为 ASCII 字符串 的方法,主要用于在需要传输文本的场合中安全地传输二进制数据(如图片、音频、文件等)。
编码原理
- 每 3 字节(24 位) 的原始数据被分为 4 组 6 位数据块
- 每组 6 位(二进制范围 0~63)通过查表转换成一个 Base64 字符
- 如果原始数据不足 3 字节,会补 0,再使用
=作为填充标识符
Base64 字符表(共 64 个字符)
| 编号范围 | 字符 |
|---|---|
| 0 - 25 | A - Z |
| 26 - 51 | a - z |
| 52 - 61 | 0 - 9 |
| 62 | + |
| 63 | / |
Base64 输出只使用这 64 个字符 +
=(用于填充)
Base64 编码中不足3字节时的处理方式
在 Base64 编码中,数据以每 3 个字节(24 位) 为一组进行编码,转换为 4 个 6 位字符。
不足3字节的补位规则
| 剩余字节数 | 需要补零 | 编码后有效字符数 | 末尾填充的 = 数量 |
|---|---|---|---|
| 1 字节 | 补 16 位 0 | 2 个 | 2 个 = |
| 2 字节 | 补 8 位 0 | 3 个 | 1 个 = |
Base64 编码结果的长度总是 4 的倍数,必要时通过
=补齐。
编码示例
fun test_base64() {
val originalText = "A"
val utf8ByteArray = originalText.toByteArray(Charsets.UTF_8)
println("UTF8 byte array group by 6 digit: ${utf8ByteArray.toBinaryString().chunked(8)}")
// UTF8 byte array group by 6 digit: [01000001]
val encoded = Base64.encodeToByteArray(utf8ByteArray)
println("base64 encode byte array group by 6 digit: ${encoded.toBinaryString().chunked(8)}")
// base64 encode byte array group by 6 digit: [01010001, 01010001, 00111101, 00111101]
//
// 01000001 // ASCII 'A' = 0x41
// 不足 3 字节 → 补16个0:
// 01000001 00000000 00000000
// 分组成 4 个 6 位:
// 010000 010000 000000 000000
// 16 16 0 0
// 查 Base64 表:
// Q Q A A -> Q Q = = (补两个=)
// 01010001 01010001 00111101 00111101
}
private fun ByteArray.toBinaryString() =
this.joinToString("") { it.toString(2).padStart(8, '0') } fun test_base64() {
val originalText = "Aa"
val utf8ByteArray = originalText.toByteArray(Charsets.UTF_8)
println("UTF8 byte array group by 6 digit: ${utf8ByteArray.toBinaryString().chunked(8)}")
// UTF8 byte array group by 6 digit: [01000001, 01100001]
val encoded = Base64.encodeToByteArray(utf8ByteArray)
println("base64 encode byte array group by 6 digit: ${encoded.toBinaryString().chunked(8)}")
// base64 encode byte array group by 6 digit: [01010001, 01010111, 01000101, 00111101]
//
// 01000001, 01100001 // ASCII 'Aa'
// 不足 3 字节 → 补8个0:
// 01000001 01100001 00000000
// 分组成 4 个 6 位:
// 010000 010110 000100 000000
// 16 22 4 0
// 查 Base64 表:
// Q W E A -> Q W E = (补一个=)
// 01010001 01010111 01000101 00111101
}
private fun ByteArray.toBinaryString() =
this.joinToString("") { it.toString(2).padStart(8, '0') }