斌斌 (给我写信) 原创博文(http://blog.csdn.net/binbinxyz),转载请注明出处!
一. 背景
最近一段时间,我在学习比特币、区块链相关的技术。我在里面见到了很多加解密的技术,比如椭圆曲线加密算法、Base58编码算法、SHA256哈希算法、RIPEMD-160哈希算法等。本着学习的态度,我打算花时间好好研究一下这些技术,看看这些加解密技术到底在干什么?又能干什么?同时,我也想记录下自己的学习历程,一方面算是为自己留下点什么,另一方面也算是督促自己进步吧!
二. 引言
学习比特币,接触最多的肯定要属比特币地址了。它是一长串的字母和数字组合,例如:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
。其实,比特币的地址使用了一种变形的Base64编码(实际是Base58编码)。Base64是网络上最常见的用于传输的编码方式之一,那么,我们就从研究Base64开始吧!
三. 正文
其实,严格来说,Base64是一种编码方式,并不是真正意义上的加密解密。不过,它也是把数据变为人不会用肉眼能分辨其真实性的角度来说。如果从这个角度来考虑的话,它也属于加密解密的范畴。
那么,Base64是什么东东呢?根据RFC2045的定义,Base64的定义是:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(#6.8>Base64 Content-Transfer-Encoding: The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
四. 编码原理
1. 编码
Base64编码按字符串长度进行处理。
1. 每3个8bit的字符分为一组。
2. 针对每组,先获取每个字符的ASCII编码,得到3个ASCII编码。
3. 将ASCII编码转换成8bit的二进制,得到一组二进制字节,长度是3*8=24bit。
4. 将24bit划分为4个6bit的字节,并在每个6bit的字节前面填充两个高位0,得到4个8bit的字节。
5. 将这4个8bit的字节转换成十进制。
6. 对照Base64编码表(参考表一),得到对应编码字符。
7. 依次将各组查表所得字符合并即得到编码结果。
表一 Base64编码表
Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding |
---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | W | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | J | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
2. 填充
如果编码的字节数不能被三整除(即如果最后24位字节的输入只有一个或两个字节),进行以下处理:用零值填充额外的字节,以达到三字节,然后执行Base64转换。如果输入只有一个字节,只有前两个Base64位有值(12bits);如果输入只有两个字节,只有前三个Base64位有值(18bits)。字符’=’可能被填充到最后一块以满足四个Base64位。
“==”表示最后一组只包含一个字节,”=”表示最后一组包含两个字节。
3.解码
学会了编码,我想你肯定也和我一样早就知道怎样解码了吧?是的,解码过程其实就是一个反向的编码过程,这里就不再赘述啦~
五.示例
1. 例一
字符cat长度能被3整除,所以Base64(cat)=Y2F0
。也就是说,cat的 Base64编码结果为Y2F0。
2. 例二
字符home长度不能被3整除。由于home只有4个字母,所以按3个一组的话,第二组还有两个空位,所以需要用0来填充。需要注意,因为是需要填充而出现的0,所以转化成十进制的时候就不能按常规用Base64编码表来对应,所以结尾不是a,而是=。
六. 结语
通过学习上面记录的这些内容,我已经充分了解了Base64的编码原理,你肯定也都懂了吧?如果你再用自己熟悉的任何语言编写一个程序来实现上述编码、解码过程,那么你一定会印象更加深刻的。
七. 参考文献
- wiki Base64: https://en.wikipedia.org/wiki/Base64
- RFC2045: https://tools.ietf.org/html/rfc2045
- The Base16, Base32, and Base64 Data Encodings: https://tools.ietf.org/html/rfc4648
- org.apache.commons.codec.binary.Base64: http://commons.apache.org/proper/commons-codec/