简介
咱们晓得计算机中的文件能够分为两种,一种是人肉眼可读的文本类文件,一种是肉眼不可读的二进制文件。一般来说二进制文件如果用文本编辑器关上的话会显示乱码,并且二进制文件和文本文件的存储和传输方式是不一样的,那么有没有什么方法将二进制文件转换成为文本文件进行传输或者存储呢?答案是必定的。
这种编码方式就是咱们明天要讲到的Base64编码。
Base64和它的编码原理
Base64是一种将二进制编码格局转换为text编码的一种模式。咱们晓得二进制编码是0和1的模式,它的单位通常是一个字节,也就是8bits,每个bit示意的是0或者1。
而文本编码的格局有很多种,最早也就是最简略的编码格局就是ASCII编码,ASCII编码的全称是American Standard Code for Information Interchange,也就是美国信息替换规范代码,它次要示意的是罕用的一些西欧字符。
ASCII的编码范畴是0x00-0x7F,用十进制来示意就是0-127,总共128个字符,刚好是7bits示意的范畴。
ASCII编码中蕴含了33个控制字符和95个可打印的字符,如下所示:
ASCII码 | 含意 | ASCII码 | 含意 | |||||
---|---|---|---|---|---|---|---|---|
16进制 | 10进制 | 2进制 | 16进制 | 10进制 | 2进制 | |||
0x00 | 0 | 0 | NUL 空 | 0x40 | 64 | 1000000 | @ | |
0x01 | 1 | 1 | SOH 题目开始 | 0x41 | 65 | 1000001 | A | |
0x02 | 2 | 10 | STX 注释开始 | 0x42 | 66 | 1000010 | B | |
0x03 | 3 | 11 | ETX 注释完结 | 0x43 | 67 | 1000011 | C | |
0x04 | 4 | 100 | EOT 传输完结 | 0x44 | 68 | 1000100 | D | |
0x05 | 5 | 101 | ENQ 询问字符 | 0x45 | 69 | 1000101 | E | |
0x06 | 6 | 110 | ACK 抵赖 | 0x46 | 70 | 1000110 | F | |
0x07 | 7 | 111 | BEL 报警 | 0x47 | 71 | 1000111 | G | |
0x08 | 8 | 1000 | BS 退一格 | 0x48 | 72 | 1001000 | H | |
0x09 | 9 | 1001 | HT 横向制表 | 0x49 | 73 | 1001001 | I | |
0x0A | 10 | 1010 | LF 换行 | 0x4A | 74 | 1001010 | J | |
0x0B | 11 | 1011 | VT 垂直制表 | 0x4B | 75 | 1001011 | K | |
0x0C | 12 | 1100 | FF 走纸管制 | 0x4C | 76 | 1001100 | L | |
0x0D | 13 | 1101 | CR 回车 | 0x4D | 77 | 1001101 | M | |
0x0E | 14 | 1110 | SO 移位输入 | 0x4E | 78 | 1001110 | N | |
0x0F | 15 | 1111 | SI 移位输出 | 0x4F | 79 | 1001111 | O | |
0x10 | 16 | 10000 | DLE 数据链路本义 | 0x50 | 80 | 1010000 | P | |
0x11 | 17 | 10001 | DC1 设施管制1 | 0x51 | 81 | 1010001 | Q | |
0x12 | 18 | 10010 | DC2 设施管制2 | 0x52 | 82 | 1010010 | R | |
0x13 | 19 | 10011 | DC3 设施管制3 | 0x53 | 83 | 1010011 | S | |
0x14 | 20 | 10100 | DC4 设施管制4 | 0x54 | 84 | 1010100 | T | |
0x15 | 21 | 10101 | NAK 否定 | 0x55 | 85 | 1010101 | U | |
0x16 | 22 | 10110 | SYN 空转同步 | 0x56 | 86 | 1010110 | V | |
0x17 | 23 | 10111 | ETB 信息组传送完结 | 0x57 | 87 | 1010111 | W | |
0x18 | 24 | 11000 | CAN 作废 | 0x58 | 88 | 1011000 | X | |
0x19 | 25 | 11001 | EM 纸尽 | 0x59 | 89 | 1011001 | Y | |
0x1A | 26 | 11010 | SUB 换置 | 0x5A | 90 | 1011010 | Z | |
0x1B | 27 | 11011 | ESC 换码 | 0x5B | 91 | 1011011 | [ | |
0x1C | 28 | 11100 | FS 文字分隔符 | 0x5C | 92 | 1011100 | \ | |
0x1D | 29 | 11101 | GS 组分隔符 | 0x5D | 93 | 1011101 | ] | |
0x1E | 30 | 11110 | RS 记录分隔符 | 0x5E | 94 | 1011110 | ^ | |
0x1F | 31 | 11111 | US 单元分隔符 | 0x5F | 95 | 1011111 | _ | |
0x20 | 32 | 100000 | (space) | 0x60 | 96 | 1100000 | ` | |
0x21 | 33 | 100001 | ! | 0x61 | 97 | 1100001 | a | |
0x22 | 34 | 100010 | ” | 0x62 | 98 | 1100010 | b | |
0x23 | 35 | 100011 | # | 0x63 | 99 | 1100011 | c | |
0x24 | 36 | 100100 | $ | 0x64 | 100 | 1100100 | d | |
0x25 | 37 | 100101 | % | 0x65 | 101 | 1100101 | e | |
0x26 | 38 | 100110 | & | 0x66 | 102 | 1100110 | f | |
0x27 | 39 | 100111 | ' | 0x67 | 103 | 1100111 | g | |
0x28 | 40 | 101000 | ( | 0x68 | 104 | 1101000 | h | |
0x29 | 41 | 101001 | ) | 0x69 | 105 | 1101001 | i | |
0x2A | 42 | 101010 | * | 0x6A | 106 | 1101010 | j | |
0x2B | 43 | 101011 | + | 0x6B | 107 | 1101011 | k | |
0x2C | 44 | 101100 | , | 0x6C | 108 | 1101100 | l | |
0x2D | 45 | 101101 | - | 0x6D | 109 | 1101101 | m | |
0x2E | 46 | 101110 | . | 0x6E | 110 | 1101110 | n | |
0x2F | 47 | 101111 | / | 0x6F | 111 | 1101111 | o | |
0x30 | 48 | 110000 | 0 | 0x70 | 112 | 1110000 | p | |
0x31 | 49 | 110001 | 1 | 0x71 | 113 | 1110001 | q | |
0x32 | 50 | 110010 | 2 | 0x72 | 114 | 1110010 | r | |
0x33 | 51 | 110011 | 3 | 0x73 | 115 | 1110011 | s | |
0x34 | 52 | 110100 | 4 | 0x74 | 116 | 1110100 | t | |
0x35 | 53 | 110101 | 5 | 0x75 | 117 | 1110101 | u | |
36 | 54 | 110110 | 6 | 0x76 | 118 | 1110110 | v | |
0x37 | 55 | 110111 | 7 | 0x77 | 119 | 1110111 | w | |
0x38 | 56 | 111000 | 8 | 0x78 | 120 | 1111000 | x | |
0x39 | 57 | 111001 | 9 | 0x79 | 121 | 1111001 | y | |
0x3A | 58 | 111010 | : | 0x7A | 122 | 1111010 | z | |
0x3B | 59 | 111011 | ; | 0x7B | 123 | 1111011 | { | |
0x3C | 60 | 111100 | < | 0x7C | 124 | 1111100 | \ | |
0x3D | 61 | 111101 | = | 0x7D | 125 | 1111101 | } | |
0x3E | 62 | 111110 | > | 0x7E | 126 | 1111110 | ~ | |
0x3F | 63 | 111111 | ? | 0x7F | 127 | 1111111 | DEL 删除 |
Base64就是从ASCII编码中挑选出64个字符和二进制一个字节8bits进行映射,这也就是Base64中64的含意。为什么要抉择ASCII编码呢?这是因为ASCII编码是最早呈现的编码模式,简直所有的计算机利用都对其齐全反对,不会呈现数据传输过程中的内容转换,十分的平安。
当然Base64编码也有多种编码模式,比方在MIME中,Base64抉择的是A-Z, a-z, 和 0-9 总共62个字符,再加上其余自选的两个字符组成了64个编码字符。
64个字符用二进制示意是6bits,而罕用的二进制应用一个字节来示意,也就是8bits,那么问题来了,怎么将8bits的二进制用6bits的Base64字符来示意呢?
很简略,咱们只须要将3个8bits连接起来,变成24bits,这样就能够用4个Base64来示意了。
为什么必须对二进制进行转换呢?这是因为互联网中的某些传输协定只反对某些特定的字符集,如果是其余的字符集是不反对的。比如说罕用的发送电子邮件的附件。因为SMTP协定最开始设计的时候是反对7 位 ASCII 字符,所以如果要传输文件的话,咱们须要对文件进行编码之后再进行传输。
另外Base64的一种用法就是在HTML中将图片嵌入到网页中,从而实现图片的展现。
尽管Base64很好用,然而因为其只能应用6bits的字符映射集,所以会造成数据映射的损失,从而导致二进制文件编码过后文件体积变大的毛病。
Base64的变体
Base64简略点说就是bit到bit之间的映射,那么必定不止一种映射形式,咱们来看下Base64编码方式的各种变体,通常来说前62位基本上是一样的,不同之处在前面两个字符,以及用于填充的字符(这在某些协定中可能是强制性的,或者在其余协定中可能被删除)。
下表是常见的Base64编码的变体:
编码名称 | 编码字符 | 编码字符 | 编码字符 |
---|---|---|---|
第62位 | 第63位 | 补全符 | |
RFC 1421: Base64 for Privacy-Enhanced Mail (deprecated) | + | / | = mandatory |
RFC 2045: Base64 transfer encoding for MIME | + | / | = mandatory |
RFC 2152: Base64 for UTF-7 | + | / | No |
RFC 3501: Base64 encoding for IMAP mailbox names | + | , | No |
RFC 4648: base64 (standard) | + | / | = optional |
RFC 4648: base64url (URL- and filename-safe standard) | - | _ | = optional |
RFC 4880: Radix-64 for OpenPGP | + | / | = mandatory |
Base64的编码细节
上一节咱们讲到了Base64编码的根本准则和一些常见的变体,那么到底是如何进行映射的呢?
本节咱们会以Base64的规范模式RFC 4648为例来进行具体的解说。
RFC 4648抉择+和/这两个字符作为编码中的第62位和63位,并且抉择=作为补全字符。
首先来察看一下RFC 4648的映射表:
索引 | 二进制 | 字符 | 索引 | 二进制 | Char | 索引 | 二进制 | Char | 索引 | 二进制 | Char |
0 | 000000 | A | 16 | 010000 | Q | 32 | 100000 | g | 48 | 110000 | w |
1 | 000001 | B | 17 | 010001 | R | 33 | 100001 | h | 49 | 110001 | x |
2 | 000010 | C | 18 | 010010 | S | 34 | 100010 | i | 50 | 110010 | y |
3 | 000011 | D | 19 | 010011 | T | 35 | 100011 | j | 51 | 110011 | z |
4 | 000100 | E | 20 | 010100 | U | 36 | 100100 | k | 52 | 110100 | 0 |
5 | 000101 | F | 21 | 010101 | V | 37 | 100101 | l | 53 | 110101 | 1 |
6 | 000110 | G | 22 | 010110 | W | 38 | 100110 | m | 54 | 110110 | 2 |
7 | 000111 | H | 23 | 010111 | X | 39 | 100111 | n | 55 | 110111 | 3 |
8 | 001000 | I | 24 | 011000 | Y | 40 | 101000 | o | 56 | 111000 | 4 |
9 | 001001 | J | 25 | 011001 | Z | 41 | 101001 | p | 57 | 111001 | 5 |
10 | 001010 | K | 26 | 011010 | a | 42 | 101010 | q | 58 | 111010 | 6 |
11 | 001011 | L | 27 | 011011 | b | 43 | 101011 | r | 59 | 111011 | 7 |
12 | 001100 | M | 28 | 011100 | c | 44 | 101100 | s | 60 | 111100 | 8 |
13 | 001101 | N | 29 | 011101 | d | 45 | 101101 | t | 61 | 111101 | 9 |
14 | 001110 | O | 30 | 011110 | e | 46 | 101110 | u | 62 | 111110 | + |
15 | 001111 | P | 31 | 011111 | f | 47 | 101111 | v | 63 | 111111 | / |
补全符 | = |
咱们来以单词man为例,来察看一下Base64的编码流程。
man这个单词在ASCII中别离用77, 97和110示意,转换成为二进制就是01001101, 01100001 和 01101110。
将下面的三个二进制合并在一起就成了:010011010110000101101110, 总共24-bit,从下面的表中抉择出对应的字符,所以咱们能够失去man通过base64编码之后失去:TWFu。
下面的例子中,man刚好是3个字符,也就是24个bits,能够用base64残缺的示意。如果咱们只有ma这两个字符,应该怎么进行编码呢?
和下面一样,ma的二进制别离是01001101, 01100001,合并起来就是0100110101100001。
然而下面的bits只有16位,因为一个base64是6bits,所以能够用3个base64来示意,因为原始的bits少了两位,所以用0来补全:
0100110101100001+00 = 010011010110000100。
010011010110000100转换成为base64就是TWE,因为base64编码须要4个字符,所以最初的字符用=来补全,也就是说me通过base64之后变成TWE=。
总结
以上就是Base64的根本含意和转换规则,其实协定很简略,将要转换的数据变成二进制,而后对照转换表格进行转换和补全即可。
本文已收录于 http://www.flydean.com/18-base64-encoding/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」,懂技术,更懂你!