]>
Commit | Line | Data |
---|---|---|
836c3244 | 1 | /* |
94439e4e | 2 | * $Id: base64.c,v 1.17 2001/01/07 23:36:36 hno Exp $ |
836c3244 | 3 | */ |
164f7660 | 4 | |
0c05d982 | 5 | #include "config.h" |
6 | ||
7 | #if HAVE_STDIO_H | |
8 | #include <stdio.h> | |
9 | #endif | |
10 | #if HAVE_STDLIB_H | |
11 | #include <stdlib.h> | |
12 | #endif | |
13 | ||
f5b8bbc4 | 14 | static void base64_init(void); |
0673c0ba | 15 | |
0c05d982 | 16 | static int base64_initialized = 0; |
7ce19a4b | 17 | #define BASE64_VALUE_SZ 256 |
18 | #define BASE64_RESULT_SZ 8192 | |
19 | int base64_value[BASE64_VALUE_SZ]; | |
d5aa0e3b | 20 | const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
0c05d982 | 21 | |
f86a22c5 | 22 | |
b8d8561b | 23 | static void |
0673c0ba | 24 | base64_init(void) |
0c05d982 | 25 | { |
26 | int i; | |
27 | ||
7ce19a4b | 28 | for (i = 0; i < BASE64_VALUE_SZ; i++) |
0c05d982 | 29 | base64_value[i] = -1; |
30 | ||
31 | for (i = 0; i < 64; i++) | |
32 | base64_value[(int) base64_code[i]] = i; | |
33 | base64_value['='] = 0; | |
34 | ||
35 | base64_initialized = 1; | |
36 | } | |
37 | ||
b8d8561b | 38 | char * |
0ee4272b | 39 | base64_decode(const char *p) |
0c05d982 | 40 | { |
7ce19a4b | 41 | static char result[BASE64_RESULT_SZ]; |
42 | int j; | |
43 | unsigned int k; | |
0c05d982 | 44 | int c; |
45 | long val; | |
0c05d982 | 46 | if (!p) |
0ee4272b | 47 | return NULL; |
0c05d982 | 48 | if (!base64_initialized) |
49 | base64_init(); | |
0c05d982 | 50 | val = c = 0; |
7ce19a4b | 51 | for (j = 0; *p && j + 3 < BASE64_RESULT_SZ; p++) { |
52 | k = (int) *p % BASE64_VALUE_SZ; | |
53 | if (base64_value[k] < 0) | |
54 | continue; | |
55 | val <<= 6; | |
56 | val += base64_value[k]; | |
57 | if (++c < 4) | |
58 | continue; | |
59 | /* One quantum of four encoding characters/24 bit */ | |
60 | result[j++] = val >> 16; /* High 8 bits */ | |
61 | result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */ | |
62 | result[j++] = val & 0xff; /* Low 8 bits */ | |
63 | val = c = 0; | |
0c05d982 | 64 | } |
7ce19a4b | 65 | result[j] = 0; |
66 | return result; | |
0c05d982 | 67 | } |
f86a22c5 | 68 | |
69 | /* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */ | |
70 | const char * | |
71 | base64_encode(const char *decoded_str) | |
72 | { | |
7ce19a4b | 73 | static char result[BASE64_RESULT_SZ]; |
f86a22c5 | 74 | int bits = 0; |
75 | int char_count = 0; | |
76 | int out_cnt = 0; | |
77 | int c; | |
78 | ||
79 | if (!decoded_str) | |
80 | return decoded_str; | |
81 | ||
82 | if (!base64_initialized) | |
83 | base64_init(); | |
84 | ||
f6aaeace | 85 | while ((c = *decoded_str++) && out_cnt < sizeof(result) - 1) { |
86 | bits += c; | |
87 | char_count++; | |
88 | if (char_count == 3) { | |
89 | result[out_cnt++] = base64_code[bits >> 18]; | |
90 | result[out_cnt++] = base64_code[(bits >> 12) & 0x3f]; | |
91 | result[out_cnt++] = base64_code[(bits >> 6) & 0x3f]; | |
92 | result[out_cnt++] = base64_code[bits & 0x3f]; | |
93 | bits = 0; | |
94 | char_count = 0; | |
f86a22c5 | 95 | } else { |
f6aaeace | 96 | bits <<= 8; |
f86a22c5 | 97 | } |
98 | } | |
99 | if (char_count != 0) { | |
f6aaeace | 100 | bits <<= 16 - (8 * char_count); |
101 | result[out_cnt++] = base64_code[bits >> 18]; | |
102 | result[out_cnt++] = base64_code[(bits >> 12) & 0x3f]; | |
103 | if (char_count == 1) { | |
104 | result[out_cnt++] = '='; | |
105 | result[out_cnt++] = '='; | |
f86a22c5 | 106 | } else { |
f6aaeace | 107 | result[out_cnt++] = base64_code[(bits >> 6) & 0x3f]; |
108 | result[out_cnt++] = '='; | |
f86a22c5 | 109 | } |
110 | } | |
f6aaeace | 111 | result[out_cnt] = '\0'; /* terminate */ |
f86a22c5 | 112 | return result; |
113 | } | |
94439e4e | 114 | |
115 | /* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */ | |
116 | const char * | |
117 | base64_encode_bin(const char *data, int len) | |
118 | { | |
119 | static char result[BASE64_RESULT_SZ]; | |
120 | int bits = 0; | |
121 | int char_count = 0; | |
122 | int out_cnt = 0; | |
123 | int c; | |
124 | ||
125 | if (!data) | |
126 | return data; | |
127 | ||
128 | if (!base64_initialized) | |
129 | base64_init(); | |
130 | ||
131 | while (len-- && out_cnt < sizeof(result) - 1) { | |
132 | c = (unsigned char) *data++; | |
133 | bits += c; | |
134 | char_count++; | |
135 | if (char_count == 3) { | |
136 | result[out_cnt++] = base64_code[bits >> 18]; | |
137 | result[out_cnt++] = base64_code[(bits >> 12) & 0x3f]; | |
138 | result[out_cnt++] = base64_code[(bits >> 6) & 0x3f]; | |
139 | result[out_cnt++] = base64_code[bits & 0x3f]; | |
140 | bits = 0; | |
141 | char_count = 0; | |
142 | } else { | |
143 | bits <<= 8; | |
144 | } | |
145 | } | |
146 | if (char_count != 0) { | |
147 | bits <<= 16 - (8 * char_count); | |
148 | result[out_cnt++] = base64_code[bits >> 18]; | |
149 | result[out_cnt++] = base64_code[(bits >> 12) & 0x3f]; | |
150 | if (char_count == 1) { | |
151 | result[out_cnt++] = '='; | |
152 | result[out_cnt++] = '='; | |
153 | } else { | |
154 | result[out_cnt++] = base64_code[(bits >> 6) & 0x3f]; | |
155 | result[out_cnt++] = '='; | |
156 | } | |
157 | } | |
158 | result[out_cnt] = '\0'; /* terminate */ | |
159 | return result; | |
160 | } |