1+ pragma solidity ^ 0.4.25 ;
2+
3+ library LibBase64 {
4+
5+ bytes constant private base64stdchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= " ;
6+
7+ /**
8+ * 字符串 base64 编码
9+ *
10+ * @ param data 要解码的数据
11+ * @ return 经 base64 返回的编码数据
12+ *
13+ **/
14+ function encode (string memory data ) internal pure returns (string memory ) {
15+ uint i = 0 ;
16+ uint j = 0 ;
17+
18+ uint padlen = bytes (data).length ;
19+ if (padlen % 3 != 0 )
20+ padlen += (3 - (padlen % 3 ));
21+
22+ bytes memory _bs = bytes (data);
23+ bytes memory _ms = new bytes (padlen);
24+
25+ for (i = 0 ; i < _bs.length ; i++ ) {
26+ _ms[i] = _bs[i];
27+ }
28+
29+ // 计算编码后的字符长度
30+ uint res_length = (padlen / 3 ) * 4 ;
31+ bytes memory res = new bytes (res_length);
32+ for (i = 0 ; i < padlen; i += 3 ) {
33+ // 取第一字符 _ms[i] 的前 6 比特位作为 base64 字符 0 的索引
34+ uint c0 = uint (uint8 (_ms[i])) >> 2 ;
35+ // 取 _ms[i] 的后2位,在末尾补 _ms[i+1] 的前 4 位作为 base64 字符 1 的索引
36+ uint c1 = (uint (uint8 (_ms[i])) & 3 ) << 4 | uint (uint8 (_ms[i+1 ])) >> 4 ;
37+ // 取 _ms[i+1] 的后 4 位,在末尾补 _ms[i+2] 的前 2 位作为 base64 字符 2 的索引
38+ uint c2 = (uint (uint8 (_ms[i+1 ])) & 15 ) << 2 | uint (uint8 (_ms[i+2 ])) >> 6 ;
39+ // 取 _ms[i+2] 的后 6 位作为 base64 字符 3 的索引
40+ uint c3 = (uint (uint8 (_ms[i+2 ])) & 63 );
41+
42+ res[j] = base64stdchars[c0];
43+ res[j+1 ] = base64stdchars[c1];
44+ res[j+2 ] = base64stdchars[c2];
45+ res[j+3 ] = base64stdchars[c3];
46+
47+ j += 4 ;
48+ }
49+
50+ // 判断是否要补位,即 + 0 ,补位则设置索引为 64,对应 ‘=’ 字符
51+ if ((padlen - bytes (data).length ) >= 1 ) {
52+ res[j-1 ] = base64stdchars[64 ];
53+ }
54+ if ((padlen - bytes (data).length ) >= 2 ) {
55+ res[j-2 ] = base64stdchars[64 ];
56+ }
57+
58+ return string (res);
59+ }
60+
61+ /**
62+ * 字符串 base64 解码
63+ *
64+ * @ param data 要解码的数据
65+ * @ return 返回的解码数据
66+ *
67+ **/
68+ function decode (string memory data ) internal pure returns (string memory ) {
69+ require ((bytes (data).length % 4 ) == 0 , "Length not multiple of 4 " );
70+ bytes memory _bs = bytes (data);
71+
72+ uint i = 0 ;
73+ uint j = 0 ;
74+ uint dec_length = (_bs.length / 4 ) * 3 ;
75+ bytes memory dec = new bytes (dec_length);
76+
77+ for (; i< _bs.length ; i+= 4 ) {
78+ (dec[j], dec[j+1 ], dec[j+2 ]) = dencode4 (
79+ bytes1 (_bs[i]),
80+ bytes1 (_bs[i+1 ]),
81+ bytes1 (_bs[i+2 ]),
82+ bytes1 (_bs[i+3 ])
83+ );
84+ j += 3 ;
85+ }
86+ while (dec[-- j]== 0 ) {}
87+
88+ bytes memory res = new bytes (j+1 );
89+ for (i= 0 ; i<= j; i++ )
90+ res[i] = dec[i];
91+
92+ return string (res);
93+ }
94+
95+ // 将4个base64编码字符解码为原3个字符
96+ function dencode4 (
97+ bytes1 b0 ,
98+ bytes1 b1 ,
99+ bytes1 b2 ,
100+ bytes1 b3
101+ )
102+ private
103+ pure
104+ returns (bytes1 a0 , bytes1 a1 , bytes1 a2 )
105+ {
106+ uint pos0 = charpos (b0);
107+ uint pos1 = charpos (b1);
108+ uint pos2 = charpos (b2) % 64 ;
109+ uint pos3 = charpos (b3) % 64 ;
110+
111+ // 取 b0 + b1 的前2位组成 8 比特位即 1 字节
112+ a0 = bytes1 (uint8 ((pos0 << 2 | pos1 >> 4 )));
113+ // 取 b1 后 4 位 + b2 的前 4 位组成 8 比特位即 1 字节
114+ a1 = bytes1 (uint8 (((pos1 & 15 ) << 4 | pos2 >> 2 )));
115+ // 取 b2 前 2 位 + b3 组成 8 比特位即 1 字节
116+ a2 = bytes1 (uint8 (((pos2 & 3 ) << 6 | pos3)));
117+ }
118+
119+ // 检查是否是 base64 字符,返回字符索引
120+ function charpos (bytes1 char ) private pure returns (uint pos ) {
121+ for (; base64stdchars[pos] != char; pos++ ) {}
122+ require (base64stdchars[pos] == char, "Illegal char in string " );
123+ return pos;
124+ }
125+
126+ }
0 commit comments