1 : /******************************************************************************
2 : * $Id: cpl_base64.cpp 21954 2011-03-13 18:18:20Z warmerdam $
3 : *
4 : * Project: Common Portability Library
5 : * Purpose: Encoding/Decoding Base64 strings
6 : * Author: Paul Ramsey <pramsey@cleverelephant.ca>
7 : * Dave Blasby <dblasby@gmail.com>
8 : * René Nyffenegger
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 2008 Paul Ramsey
12 : * Copyright (c) 2002 Refractions Research
13 : * Copyright (C) 2004-2008 René Nyffenegger
14 : *
15 : * (see also part way down the file for license terms for René's code)
16 : *
17 : * Permission is hereby granted, free of charge, to any person obtaining a
18 : * copy of this software and associated documentation files (the "Software"),
19 : * to deal in the Software without restriction, including without limitation
20 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 : * and/or sell copies of the Software, and to permit persons to whom the
22 : * Software is furnished to do so, subject to the following conditions:
23 : *
24 : * The above copyright notice and this permission notice shall be included in
25 : * all copies of this Software or works derived from this Software.
26 : *
27 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 : * DEALINGS IN THE SOFTWARE.
34 : ****************************************************************************/
35 :
36 : #include "cpl_string.h"
37 :
38 : CPL_CVSID("$Id: cpl_base64.cpp 21954 2011-03-13 18:18:20Z warmerdam $");
39 :
40 : /* Derived from MapServer's mappostgis.c */
41 :
42 : /*
43 : ** Decode a base64 character.
44 : */
45 : static const unsigned char CPLBase64DecodeChar[256] = {
46 : /* not Base64 characters */
47 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
48 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
49 : 64,64,64,64,64,64,64,64,64,64,64,
50 : /* + */
51 : 62,
52 : /* not Base64 characters */
53 : 64,64,64,
54 : /* / */
55 : 63,
56 : /* 0-9 */
57 : 52,53,54,55,56,57,58,59,60,61,
58 : /* not Base64 characters */
59 : 64,64,64,64,64,64,64,
60 : /* A-Z */
61 : 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
62 : /* not Base64 characters */
63 : 64,64,64,64,64,64,
64 : /* a-z */
65 : 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
66 : /* not Base64 characters */
67 : 64,64,64,64,64,
68 : /* not Base64 characters (upper 128 characters) */
69 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
70 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
71 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
72 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
73 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
74 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
75 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
76 : 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
77 : };
78 :
79 : /************************************************************************/
80 : /* CPLBase64DecodeInPlace() */
81 : /* */
82 : /* Decode base64 string "pszBase64" (null terminated) in place */
83 : /* Returns length of decoded array or 0 on failure. */
84 : /************************************************************************/
85 :
86 2 : int CPLBase64DecodeInPlace(GByte* pszBase64)
87 : {
88 2 : if (pszBase64 && *pszBase64) {
89 :
90 2 : unsigned char *p = pszBase64;
91 : int i, j, k;
92 :
93 : /* Drop illegal chars first */
94 82 : for (i=0, j=0; pszBase64[i]; i++) {
95 80 : unsigned char c = pszBase64[i];
96 80 : if ( (CPLBase64DecodeChar[c] != 64) || (c == '=') ) {
97 80 : pszBase64[j++] = c;
98 : }
99 : }
100 :
101 22 : for (k=0; k<j; k+=4) {
102 : register unsigned char b1, b2, b3, b4, c3, c4;
103 :
104 20 : b1 = CPLBase64DecodeChar[pszBase64[k]];
105 :
106 20 : if (k+3<j) {
107 20 : b2 = CPLBase64DecodeChar[pszBase64[k+1]];
108 20 : c3 = pszBase64[k+2];
109 20 : c4 = pszBase64[k+3];
110 : }
111 0 : else if (k+2<j) {
112 0 : b2 = CPLBase64DecodeChar[pszBase64[k+1]];
113 0 : c3 = pszBase64[k+2];
114 0 : c4 = 'A';
115 : }
116 0 : else if (k+1<j) {
117 0 : b2 = CPLBase64DecodeChar[pszBase64[k+1]];
118 0 : c3 = 'A';
119 0 : c4 = 'A';
120 : }
121 : else
122 : {
123 0 : b2 = 0;
124 0 : c3 = 'A';
125 0 : c4 = 'A';
126 : }
127 :
128 20 : b3 = CPLBase64DecodeChar[c3];
129 20 : b4 = CPLBase64DecodeChar[c4];
130 :
131 20 : *p++=((b1<<2)|(b2>>4) );
132 20 : if (c3 != '=') {
133 20 : *p++=(((b2&0xf)<<4)|(b3>>2) );
134 : }
135 20 : if (c4 != '=') {
136 18 : *p++=(((b3&0x3)<<6)|b4 );
137 : }
138 : }
139 2 : return(p-pszBase64);
140 : }
141 0 : return 0;
142 : }
143 :
144 : /*
145 : * This function was extracted from the base64 cpp utility published by
146 : * René Nyffenegger. The code was modified into a form suitable for use in
147 : * CPL. The original code can be found at
148 : * http://www.adp-gmbh.ch/cpp/common/base64.html.
149 : *
150 : * The following is the original notice of this function.
151 : *
152 : * base64.cpp and base64.h
153 : *
154 : * Copyright (C) 2004-2008 René Nyffenegger
155 : *
156 : * This source code is provided 'as-is', without any express or implied
157 : * warranty. In no event will the author be held liable for any damages
158 : * arising from the use of this software.
159 : *
160 : * Permission is granted to anyone to use this software for any purpose,
161 : * including commercial applications, and to alter it and redistribute it
162 : * freely, subject to the following restrictions:
163 : *
164 : * 1. The origin of this source code must not be misrepresented; you must not
165 : * claim that you wrote the original source code. If you use this source code
166 : * in a product, an acknowledgment in the product documentation would be
167 : * appreciated but is not required.
168 : *
169 : * 2. Altered source versions must be plainly marked as such, and must not be
170 : * misrepresented as being the original source code.
171 : *
172 : * 3. This notice may not be removed or altered from any source distribution.
173 : *
174 : * René Nyffenegger rene.nyffenegger@adp-gmbh.ch
175 : */
176 :
177 : /************************************************************************/
178 : /* CPLBase64Encode() */
179 : /************************************************************************/
180 :
181 8 : char *CPLBase64Encode( int nDataLen, const GByte *pabyBytesToEncode )
182 :
183 : {
184 8 : static const std::string base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
185 :
186 8 : int i = 0;
187 8 : int j = 0;
188 8 : std::string result("");
189 : unsigned char charArray3[3];
190 : unsigned char charArray4[4];
191 :
192 3744 : while( nDataLen-- )
193 : {
194 3728 : charArray3[i++] = *(pabyBytesToEncode++);
195 :
196 3728 : if( i == 3 )
197 : {
198 1240 : charArray4[0] = (charArray3[0] & 0xfc) >> 2;
199 1240 : charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
200 1240 : charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
201 1240 : charArray4[3] = charArray3[2] & 0x3f;
202 :
203 6200 : for( i = 0; i < 4; i++ )
204 : {
205 4960 : result += base64Chars[charArray4[i]];
206 : }
207 :
208 1240 : i = 0;
209 : }
210 : }
211 :
212 8 : if( i )
213 : {
214 8 : for( j = i; j < 3; j++ )
215 : {
216 4 : charArray3[j] = '\0';
217 : }
218 :
219 4 : charArray4[0] = (charArray3[0] & 0xfc) >> 2;
220 4 : charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
221 4 : charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
222 4 : charArray4[3] = charArray3[2] & 0x3f;
223 :
224 16 : for ( j = 0; j < (i + 1); j++ )
225 : {
226 12 : result += base64Chars[charArray4[j]];
227 : }
228 :
229 12 : while( i++ < 3 )
230 4 : result += '=';
231 : }
232 :
233 8 : return (CPLStrdup(result.c_str()));
234 : }
235 :
|