root/src/utils/noit_b64.c

Revision f1321aca809330f906e8a5d508e18c0373566554, 4.0 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

implement base64 decoding/encoding, refs #26

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2005-2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *    * Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    * Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *    * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *      of its contributors may be used to endorse or promote products
17  *      derived from this software without specific prior written
18  *      permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_config.h"
34 #include "noit_b64.h"
35 #include <ctype.h>
36
37 static const char __b64[] = {
38   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
39   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
40   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
41   'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
42   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 0x00 };
43
44 int
45 noit_b64_decode(const char *src, size_t src_len,
46                 unsigned char *dest, size_t dest_len) {
47   const unsigned char *cp = (unsigned char *)src;
48   unsigned char *dcp = dest;
49   unsigned char ch, in[4], out[3];
50   int ib = 0, ob = 3, needed = (((src_len / 4) * 3) - 2);
51
52   if(dest_len < needed) return 0;
53   while(cp <= ((unsigned char *)src+src_len)) {
54     if((*cp >= 'A') && (*cp <= 'Z')) ch = *cp - 'A';
55     else if((*cp >= 'a') && (*cp <= 'z')) ch = *cp - 'a' + 26;
56     else if((*cp >= '0') && (*cp <= '9')) ch = *cp - '0' + 52;
57     else if(*cp == '+') ch = 62;
58     else if(*cp == '/') ch = 63;
59     else if(*cp == '=') ch = 0xff;
60     else if(isspace((int)*cp)) { cp++; continue; }
61     else break;
62     cp++;
63     if(ch == 0xff) {
64       if(ib == 0) break;
65       if(ib == 1 || ib == 2) ob = 1;
66       else ob = 2;
67       ib = 3;
68     }
69     in[ib++] = ch;
70     if(ib == 4) {
71       out[0] = (in[0] << 2) | ((in[1] & 0x30) >> 4);
72       out[1] = ((in[1] & 0x0f) << 4) | ((in[2] & 0x3c) >> 2);
73       out[2] = ((in[2] & 0x03) << 6) | (in[3] & 0x3f);
74       for(ib = 0; ib < ob; ib++)
75         *dcp++ = out[ib];
76       ib = 0;
77     }
78   }
79   return dcp - (unsigned char *)dest;
80 }
81
82 int
83 noit_b64_encode(const unsigned char *src, size_t src_len,
84                 char *dest, size_t dest_len) {
85   const unsigned char *bptr = src;
86   char *eptr = dest;
87   int len = src_len;
88   int n = (((src_len + 2) / 3) * 4);
89
90   if(dest_len < n) return 0;
91
92   while(len > 2) {
93     *eptr++ = __b64[bptr[0] >> 2];
94     *eptr++ = __b64[((bptr[0] & 0x03) << 4) + (bptr[1] >> 4)];
95     *eptr++ = __b64[((bptr[1] & 0x0f) << 2) + (bptr[2] >> 6)];
96     *eptr++ = __b64[bptr[2] & 0x3f];
97     bptr += 3;
98     len -= 3;
99   }
100   if(len != 0) {
101     *eptr++ = __b64[bptr[0] >> 2];
102     if(len > 1) {
103       *eptr++ = __b64[((bptr[0] & 0x03) << 4) + (bptr[1] >> 4)];
104       *eptr++ = __b64[(bptr[1] & 0x0f) << 2];
105       *eptr++ = '=';
106     } else {
107       *eptr++ = __b64[(bptr[0] & 0x03) << 4];
108       *eptr++ = '=';
109       *eptr++ = '=';
110     }
111   }
112   return n;
113 }
114
Note: See TracBrowser for help on using the browser.