git ssb

8+

cel / sbotc



Tree: e1e1c56a064cee691025d3117030ea74cc5e8354

Files: e1e1c56a064cee691025d3117030ea74cc5e8354 / base64.c

2365 bytesRaw
1/*
2
3 This code is public domain software.
4
5*/
6
7#include "base64.h"
8
9#include <stdlib.h>
10#include <string.h>
11#include <errno.h>
12
13
14// single base64 character conversion
15//
16static int POS(char c)
17{
18 if (c>='A' && c<='Z') return c - 'A';
19 if (c>='a' && c<='z') return c - 'a' + 26;
20 if (c>='0' && c<='9') return c - '0' + 52;
21 if (c == '+') return 62;
22 if (c == '/') return 63;
23 if (c == '=') return -1;
24 return -2;
25}
26
27// base64 decoding
28//
29// s: base64 string
30// str_len size of the base64 string
31// data: output buffer for decoded data
32// data_len expected size of decoded data
33// return: 0 on success, -1 on failure
34//
35int base64_decode(const char* s, size_t str_len, void *data, size_t data_len)
36{
37 const char *p, *str_end;
38 unsigned char *q, *end;
39 int n[4] = { 0, 0, 0, 0 };
40
41 if (str_len % 4) { errno = EBADMSG; return -1; }
42 q = (unsigned char*) data;
43 end = q + data_len;
44 str_end = s + str_len;
45
46 for (p = s; p < str_end; ) {
47 n[0] = POS(*p++);
48 n[1] = POS(*p++);
49 n[2] = POS(*p++);
50 n[3] = POS(*p++);
51
52 if (n[0] == -2 || n[1] == -2 || n[2] == -2 || n[3] == -2)
53 { errno = EBADMSG; return -1; }
54
55 if (n[0] == -1 || n[1] == -1)
56 { errno = EBADMSG; return -1; }
57
58 if (n[2] == -1 && n[3] != -1)
59 { errno = EBADMSG; return -1; }
60
61 if (q >= end) { errno = EMSGSIZE; return -1; }
62 q[0] = (n[0] << 2) + (n[1] >> 4);
63 if (n[2] != -1) {
64 if (q+1 >= end) { errno = EMSGSIZE; return -1; }
65 q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
66 }
67 if (n[3] != -1) {
68 if (q+2 >= end) { errno = EMSGSIZE; return -1; }
69 q[2] = ((n[2] & 3) << 6) + n[3];
70 }
71 q += 3;
72 }
73
74 return 0;
75}
76
77int base64_encode(const void* buf, size_t size, char *str, size_t out_size) {
78 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
79
80 char* p = str;
81 const unsigned char* q = (const unsigned char*) buf;
82 size_t i = 0;
83
84 if ((size+3)*4/3 + 1 > out_size) {
85 errno = EMSGSIZE;
86 return -1;
87 }
88
89 while (i < size) {
90 int c = q[i++];
91 c *= 256;
92 if (i < size)
93 c += q[i];
94 i++;
95
96 c *= 256;
97 if (i < size)
98 c += q[i];
99 i++;
100
101 *p++ = base64[(c & 0x00fc0000) >> 18];
102 *p++ = base64[(c & 0x0003f000) >> 12];
103
104 if (i > size + 1)
105 *p++ = '=';
106 else
107 *p++ = base64[(c & 0x00000fc0) >> 6];
108
109 if (i > size)
110 *p++ = '=';
111 else
112 *p++ = base64[c & 0x0000003f];
113 }
114
115 *p = 0;
116
117 return 0;
118}
119

Built with git-ssb-web