1 /* @(#) $Id: b64.c,v 1.2 2006/06/21 00:18:21 dcid Exp $ */
3 * Copyright (C), 2000-2004 by the monit project group.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 char *decode_base64(const char *src);
29 char *encode_base64(int size, char *src);
31 /* Private prototypes */
32 static int is_base64(char c);
33 static char encode(unsigned char u);
34 static unsigned char decode(char c);
38 * Implementation of base64 encoding/decoding.
40 * @author Jan-Henrik Haukeland, <hauk@tildeslash.com>
42 * @version \$Id: b64.c,v 1.2 2006/06/21 00:18:21 dcid Exp $
50 * Base64 encode and return size data in 'src'. The caller must free the
52 * @param size The size of the data in src
53 * @param src The data to be base64 encode
54 * @return encoded string otherwise NULL
56 char *encode_base64(int size, char *src) {
65 size= strlen((char *)src);
67 out = (char *)calloc(sizeof(char), size*4/3+4);
73 for(i = 0; i < size; i+=3) {
75 unsigned char b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0;
86 b5= ((b1&0x3)<<4)|(b2>>4);
87 b6= ((b2&0xf)<<2)|(b3>>6);
112 * Decode the base64 encoded string 'src' into the memory pointed to by
113 * 'dest'. The dest buffer is NUL terminated.
114 * Return NULL in case of error
116 char *decode_base64(const char *src)
122 int k, l = strlen(src)+1;
125 /* The size of the dest will always be less than
128 dest = (char *)calloc(sizeof(char), l + 13);
132 p = (unsigned char *)dest;
138 /* Ignore non base64 chars as per the POSIX standard */
139 for(k=0, l=0; src[k]; k++)
141 if(is_base64(src[k]))
149 char c1='A', c2='A', c3='A', c4='A';
150 unsigned char b1=0, b2=0, b3=0, b4=0;
172 *p++=((b1<<2)|(b2>>4) );
175 *p++=(((b2&0xf)<<4)|(b3>>2) );
179 *p++=(((b3&0x3)<<6)|b4 );
196 /* ----------------------------------------------------------------- Private */
198 static char encode(unsigned char u) {
200 if(u < 26) return 'A'+u;
201 if(u < 52) return 'a'+(u-26);
202 if(u < 62) return '0'+(u-52);
203 if(u == 62) return '+';
211 * Decode a base64 character
213 static unsigned char decode(char c) {
215 if(c >= 'A' && c <= 'Z') return(c - 'A');
216 if(c >= 'a' && c <= 'z') return(c - 'a' + 26);
217 if(c >= '0' && c <= '9') return(c - '0' + 52);
218 if(c == '+') return 62;
226 * Return TRUE if 'c' is a valid base64 character, otherwise FALSE
228 static int is_base64(char c) {
230 if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
231 (c >= '0' && c <= '9') || (c == '+') ||
232 (c == '/') || (c == '=')) {
244 int main(int argc, char **argv)
251 printf("%s string\n",argv[0]);
254 s = encode_base64(strlen(argv[1]), argv[1]);
256 printf("b64:\n%s\n",s);
259 d = decode_base64(s);
260 printf("decode:%s\n",d);