Base64 转换工具

核心代码:

  1 void EncodeBase64(unsigned char *ce, unsigned char *co)
  2 {
  3     unsigned char *p;
  4     unsigned int ocl; // 原串长度
  5     unsigned int ecl; // 加密后长度
  6     unsigned int t;   // ocl 除以 3 后的余数
  7     unsigned char *oend;
  8     unsigned char *eend;
  9     unsigned char *p1, *p2, *p3;
 10     unsigned char *pe;
 11     unsigned char Base64Table[68] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 12 
 13     for (p = co, ocl = 0; *p; ++p)
 14     {
 15         ++ocl;
 16     }
 17 
 18     ecl = ocl / 3 * 4; // 不用补0的部分
 19     t = ocl % 3;
 20     if (t)
 21         ecl += 4;      // 末尾4字节
 22 
 23     oend = co + ocl;
 24     eend = ce + ecl;
 25     *eend = '\0';
 26 
 27     p1 = co;
 28     p2 = co + 1;
 29     p3 = co + 2;
 30     pe = ce;
 31     while (p3 < oend) // 不用补0的部分
 32     {
 33         *pe++ = *p1 >> 2;
 34         *pe++ = (*p1 & 0x03) << 4 | *p2 >> 4;
 35         *pe++ = (*p2 & 0x0F) << 2 | *p3 >> 6;
 36         *pe++ = *p3 & 0x3F;
 37 
 38         p1 += 3;
 39         p2 += 3;
 40         p3 += 3;
 41     }
 42 
 43 
 44     /*
 45     末尾4字节
 46     t = 1:
 47     [1101 0101]
 48     00[110101] 00[010000] 40H pad    40H pad
 49     35H        10H        40H pad    40H pad
 50     31H '1'    51H 'Q'    3DH '='    3DH '='
 51 
 52     t = 2:
 53     [1101 0101] [1100 0101]
 54     00[110101] 00[011100] 00[010100] 40H pad
 55     35H        1CH        14H        40H pad
 56     31H '1'    62H 'c'    55H 'U'    3DH '='
 57     */
 58     switch (t)
 59     {
 60     case 1:
 61         *pe++ = *p1 >> 2;
 62         *pe++ = (*p1 & 0x03) << 4;
 63         *pe++ = 0x40;
 64         *pe = 0x40;
 65         break;
 66 
 67     case 2:
 68         *pe++ = *p1 >> 2;
 69         *pe++ = (*p1 & 0x03) << 4 | *p2 >> 4;
 70         *pe++ = (*p2 & 0x0F) << 2;
 71         *pe = 0x40;
 72         break;
 73 
 74     default:
 75         break;
 76     }
 77 
 78     // 已创建好索引值,开始转换
 79 
 80     /*
 81     Base 64 加密索引表
 82     一一对应关系,解密就是反过来
 83 
 84     000 ~ 025   026 ~ 051   052 ~ 061   062   063   064
 85     00H ~ 19H   1AH ~ 33H   34H ~ 3DH   3EH   3FH   40H
 86         ↓           ↓           ↓        ↓     ↓     ↓
 87     41H ~ 5AH   61H ~ 7AH   30H ~ 39H   2BH   2FH   3DH
 88     'A' ~ 'Z'   'a' ~ 'z'   '0' ~ '9'   '+'   '/'   '='
 89 
 90     for (p = ce; p < eend; ++p)
 91     {
 92         if (*p <= 0x19)
 93             *p += 0x41;
 94         else if (*p >= 0x1A && *p <= 0x33)
 95             *p += 0x61 - 0x1A;
 96         else if (*p >= 0x34 && *p <= 0x3D)
 97             *p -= 0x04;
 98         else if (*p == 0x3E)
 99             *p = 0x2B; // '+'
100         else if (*p == 0x3F)
101             *p = 0x2F; // '/'
102         else if (*p == 0x40)
103             *p = 0x3D; // '='
104     }
105     */
106     /*
107     查表法使用额外空间,减少代码长度,不再需要if判断分支
108     */
109     for (p = ce; p < eend; ++p)
110     {
111         *p = Base64Table[*p];
112     }
113 }
114 void DecodeBase64(unsigned char *co, unsigned char *ce)
115 {
116     unsigned char *p;
117     unsigned int ocl; // 原串长度
118     unsigned int ecl; // 加密串长度
119     unsigned int t;   // '='个数
120 
121     unsigned char *oend;
122     unsigned char *eend;
123     unsigned char *eendf; // 加密串中每4个字节计算,不含'='的部分的末尾
124     unsigned char *p1, *p2, *p3, *p4;
125     unsigned char *po;
126 
127     for (p = ce, ecl = 0; *p; ++p)
128     {
129         ++ecl;
130     }
131 
132     eendf = eend = ce + ecl;
133     for (t = 0, p = eend - 1; *p == '='; --p)
134     {
135         ++t;
136     }
137 
138     if (t)
139         eendf -= 4;
140 
141     ocl = ecl / 4 * 3 - t; // 合法加密串长度总是4的倍数,函数不做合法性检查
142     oend = co + ocl;
143     *oend = '\0';
144 
145     /*
146     还原为索引
147 
148     41H ~ 5AH   61H ~ 7AH   30H ~ 39H   2BH   2FH   3DH
149     'A' ~ 'Z'   'a' ~ 'z'   '0' ~ '9'   '+'   '/'   '='
150         ↓           ↓           ↓        ↓     ↓     ↓
151     00H ~ 19H   1AH ~ 33H   34H ~ 3DH   3EH   3FH   40H
152     */
153     for (p = ce; p < eend; ++p)
154     {
155         if (*p >= 'A' && *p <= 'Z')
156             *p -= 0x41;
157         else if (*p >= 'a' && *p <= 'z')
158             *p -= 0x61 - 0x1A;
159         else if (*p >= '0' && *p <= '9')
160             *p += 0x04;
161         else if (*p == '+')
162             *p = 0x3E;
163         else if (*p == '/')
164             *p = 0x3F;
165         else if (*p == '=')
166             *p = 0x40;
167     }
168 
169     // 合并字节
170     p1 = ce;
171     p2 = ce + 1;
172     p3 = ce + 2;
173     p4 = ce + 3;
174     po = co;
175     while (p1 < eendf)
176     {
177         *po++ = *p1 << 2 | *p2 >> 4;
178         *po++ = *p2 << 4 | *p3 >> 2;
179         *po++ = *p3 << 6 | *p4;
180 
181         p1 += 4;
182         p2 += 4;
183         p3 += 4;
184         p4 += 4;
185     }
186     /*
187     while (p1 < eendf)
188     {
189         *po++ = *p1 << 2 | (*p2 & 0x30) >> 4;
190         *po++ = *p2 << 4 | (*p3 & 0x3C) >> 2;
191         *po++ = *p3 << 6 | *p4 & 0x3F;
192 
193         p1 += 4;
194         p2 += 4;
195         p3 += 4;
196         p4 += 4;
197     }
198     */
199     /*
200     末尾4字节
201 
202     t = 1:
203     31H '1'    62H 'c'    55H 'U'    3DH '='
204     35H        1CH        14H        40H pad
205     00[110101] 00[011100] 00[010100] 40H pad
206     [1101 0101] [1100 0101]
207 
208     t = 2:
209     31H '1'    51H 'Q'    3DH '='    3DH '='
210     35H        10H        40H pad    40H pad
211     00[110101] 00[010000] 40H pad    40H pad
212     [1101 0101]
213     */
214     switch (t)
215     {
216     case 1:
217         *po++ = *p1 << 2 | *p2 >> 4;
218         *po = *p2 << 4 | *p3 >> 2;
219         break;
220 
221     case 2:
222         *po = *p1 << 2 | *p2 >> 4;
223         break;
224 
225     default:
226         break;
227     }
228 }
229 int DecodeBase64_safe(unsigned char *co, unsigned char *ce)
230 {
231     if (!IsBase64String(ce))
232         return 0;
233     else
234     {
235         DecodeBase64(co, ce);
236         return 1;
237     }
238 }

完整源码

posted @ 2015-10-09 20:13  WalkingSkeleton  阅读(4034)  评论(0编辑  收藏  举报