]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/base64.c
Major rewrite of proxy authentication to support other schemes than
[thirdparty/squid.git] / lib / base64.c
CommitLineData
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 14static void base64_init(void);
0673c0ba 15
0c05d982 16static int base64_initialized = 0;
7ce19a4b 17#define BASE64_VALUE_SZ 256
18#define BASE64_RESULT_SZ 8192
19int base64_value[BASE64_VALUE_SZ];
d5aa0e3b 20const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0c05d982 21
f86a22c5 22
b8d8561b 23static void
0673c0ba 24base64_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 38char *
0ee4272b 39base64_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 */
70const char *
71base64_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 */
116const char *
117base64_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}