]>
git.proxmox.com Git - mirror_frr.git/blob - lib/base64.c
1 // SPDX-License-Identifier: NONE
3 * This is part of the libb64 project, and has been placed in the public domain.
4 * For details, see http://sourceforge.net/projects/libb64
13 static const int CHARS_PER_LINE
= 72;
14 static const char *ENCODING
=
15 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
17 void base64_init_encodestate(struct base64_encodestate
*state_in
)
19 state_in
->step
= step_A
;
21 state_in
->stepcount
= 0;
24 char base64_encode_value(char value_in
)
28 return ENCODING
[(int)value_in
];
31 int base64_encode_block(const char *plaintext_in
, int length_in
, char *code_out
,
32 struct base64_encodestate
*state_in
)
34 const char *plainchar
= plaintext_in
;
35 const char *const plaintextend
= plaintext_in
+ length_in
;
36 char *codechar
= code_out
;
40 result
= state_in
->result
;
42 switch (state_in
->step
) {
45 if (plainchar
== plaintextend
) {
46 state_in
->result
= result
;
47 state_in
->step
= step_A
;
48 return codechar
- code_out
;
50 fragment
= *plainchar
++;
51 result
= (fragment
& 0x0fc) >> 2;
52 *codechar
++ = base64_encode_value(result
);
53 result
= (fragment
& 0x003) << 4;
56 if (plainchar
== plaintextend
) {
57 state_in
->result
= result
;
58 state_in
->step
= step_B
;
59 return codechar
- code_out
;
61 fragment
= *plainchar
++;
62 result
|= (fragment
& 0x0f0) >> 4;
63 *codechar
++ = base64_encode_value(result
);
64 result
= (fragment
& 0x00f) << 2;
67 if (plainchar
== plaintextend
) {
68 state_in
->result
= result
;
69 state_in
->step
= step_C
;
70 return codechar
- code_out
;
72 fragment
= *plainchar
++;
73 result
|= (fragment
& 0x0c0) >> 6;
74 *codechar
++ = base64_encode_value(result
);
75 result
= (fragment
& 0x03f) >> 0;
76 *codechar
++ = base64_encode_value(result
);
78 ++(state_in
->stepcount
);
79 if (state_in
->stepcount
== CHARS_PER_LINE
/4) {
81 state_in
->stepcount
= 0;
85 /* control should not reach here */
86 return codechar
- code_out
;
89 int base64_encode_blockend(char *code_out
, struct base64_encodestate
*state_in
)
91 char *codechar
= code_out
;
93 switch (state_in
->step
) {
95 *codechar
++ = base64_encode_value(state_in
->result
);
100 *codechar
++ = base64_encode_value(state_in
->result
);
108 return codechar
- code_out
;
112 signed char base64_decode_value(signed char value_in
)
114 static const signed char decoding
[] = {
115 62, -1, -1, -1, 63, 52, 53, 54,
116 55, 56, 57, 58, 59, 60, 61, -1,
117 -1, -1, -2, -1, -1, -1, 0, 1,
118 2, 3, 4, 5, 6, 7, 8, 9,
119 10, 11, 12, 13, 14, 15, 16, 17,
120 18, 19, 20, 21, 22, 23, 24, 25,
121 -1, -1, -1, -1, -1, -1, 26, 27,
122 28, 29, 30, 31, 32, 33, 34, 35,
123 36, 37, 38, 39, 40, 41, 42, 43,
124 44, 45, 46, 47, 48, 49, 50, 51
127 if (value_in
< 0 || value_in
>= 80)
129 return decoding
[(int)value_in
];
132 void base64_init_decodestate(struct base64_decodestate
*state_in
)
134 state_in
->step
= step_a
;
135 state_in
->plainchar
= 0;
138 int base64_decode_block(const char *code_in
, int length_in
, char *plaintext_out
,
139 struct base64_decodestate
*state_in
)
141 const char *codec
= code_in
;
142 char *plainc
= plaintext_out
;
145 *plainc
= state_in
->plainchar
;
147 switch (state_in
->step
) {
151 if (codec
== code_in
+length_in
) {
152 state_in
->step
= step_a
;
153 state_in
->plainchar
= *plainc
;
154 return plainc
- plaintext_out
;
156 fragmt
= base64_decode_value(*codec
++);
157 } while (fragmt
< 0);
158 *plainc
= (fragmt
& 0x03f) << 2;
162 if (codec
== code_in
+length_in
) {
163 state_in
->step
= step_b
;
164 state_in
->plainchar
= *plainc
;
165 return plainc
- plaintext_out
;
167 fragmt
= base64_decode_value(*codec
++);
168 } while (fragmt
< 0);
169 *plainc
++ |= (fragmt
& 0x030) >> 4;
170 *plainc
= (fragmt
& 0x00f) << 4;
174 if (codec
== code_in
+length_in
) {
175 state_in
->step
= step_c
;
176 state_in
->plainchar
= *plainc
;
177 return plainc
- plaintext_out
;
179 fragmt
= base64_decode_value(*codec
++);
180 } while (fragmt
< 0);
181 *plainc
++ |= (fragmt
& 0x03c) >> 2;
182 *plainc
= (fragmt
& 0x003) << 6;
186 if (codec
== code_in
+length_in
) {
187 state_in
->step
= step_d
;
188 state_in
->plainchar
= *plainc
;
189 return plainc
- plaintext_out
;
191 fragmt
= base64_decode_value(*codec
++);
192 } while (fragmt
< 0);
193 *plainc
++ |= (fragmt
& 0x03f);
196 /* control should not reach here */
197 return plainc
- plaintext_out
;