载入中...
搜索中...
未找到
b64.cpp
浏览该文件的文档.
1
2#include "b64.h"
3#include "Exception.h"
4
5#include <limits>
6#include <stdio.h>
7
8namespace eve
9{
10
11// Translation table as described in RFC1113
12static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13
14// Translation table to decode (created by Bob Trower)
15static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
16
20static void b64_encode_block(char in[3], char out[4], int len)
21{
22 out[0] = (char) cb64[(int)((in[0] & 0xfc) >> 2)];
23 out[1] = (char) cb64[(int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4))];
24 out[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '=');
25 out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '=');
26}
27
28char *b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen)
29{
30 if (linelen == 0)
31 linelen = std::numeric_limits<size_t>::max();
32
33 size_t blocksout = 0;
34 size_t srcpos = 0;
35
36 size_t adjustment = (srclen % 3) ? (3 - (srclen % 3)) : 0;
37 size_t paddedlen = ((srclen + adjustment) / 3) * 4;
38
39 dstlen = paddedlen + paddedlen / linelen;
40
41 if (dstlen == 0)
42 return nullptr;
43
44 char *dst = nullptr;
45 try
46 {
47 dst = new char[dstlen + 1];
48 }
49 catch (std::exception &)
50 {
51 throw eve::Exception("Out of memory.");
52 }
53
54 size_t dstpos = 0;
55
56 while (srcpos < srclen)
57 {
58 char in[3] = {0};
59 char out[4] = {0};
60
61 int len = 0;
62
63 for (int i = 0; i < 3; i++)
64 {
65 if (srcpos >= srclen)
66 break;
67
68 in[i] = src[srcpos++];
69 len++;
70 }
71
72 if (len > 0)
73 {
74 b64_encode_block(in, out, len);
75
76 for (int i = 0; i < 4 && dstpos < dstlen; i++, dstpos++)
77 dst[dstpos] = out[i];
78
79 blocksout++;
80 }
81
82 if (blocksout >= linelen / 4 || srcpos >= srclen)
83 {
84 if (blocksout > 0 && dstpos < dstlen)
85 dst[dstpos++] = '\n';
86
87 blocksout = 0;
88 }
89 }
90
91 dst[dstpos] = '\0';
92 return dst;
93}
94
95static void b64_decode_block(char in[4], char out[3])
96{
97 out[0] = (char)(in[0] << 2 | in[1] >> 4);
98 out[1] = (char)(in[1] << 4 | in[2] >> 2);
99 out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
100}
101
102char *b64_decode(const char *src, size_t srclen, size_t &size)
103{
104 size_t paddedsize = (srclen / 4) * 3;
105
106 char *dst = nullptr;
107 try
108 {
109 dst = new char[paddedsize];
110 }
111 catch (std::exception &)
112 {
113 throw eve::Exception("Out of memory.");
114 }
115
116 char *d = dst;
117
118 char in[4] = {0};
119 char out[3] = {0};
120 size_t i, len, srcpos = 0;
121
122 while (srcpos <= srclen)
123 {
124 for (len = 0, i = 0; i < 4 && srcpos <= srclen; i++)
125 {
126 char v = 0;
127
128 while (srcpos <= srclen && v == 0)
129 {
130 v = src[srcpos++];
131 v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
132 if (v != 0)
133 v = (char)((v == '$') ? 0 : v - 61);
134 }
135
136 if (srcpos <= srclen)
137 {
138 len++;
139 if (v != 0)
140 in[i] = (char)(v - 1);
141 }
142 else
143 in[i] = 0;
144 }
145
146 if (len)
147 {
148 b64_decode_block(in, out);
149 for (i = 0; i < len - 1; i++)
150 *(d++) = out[i];
151 }
152 }
153
154 size = (size_t)(ptrdiff_t) (d - dst);
155 return dst;
156}
157
158} // eve
int d
int v
Definition Build.cpp:11
char * b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen)
Base64-encode data.
Definition b64.cpp:28
char * b64_decode(const char *src, size_t srclen, size_t &size)
Decode base64 encoded data.
Definition b64.cpp:102