3 Copyright (C) 2002 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
20 or both in parallel, as here.
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
41 #define ENCODE(alphabet,x) ((alphabet)[0x3F & (x)])
44 encode_raw(const uint8_t *alphabet,
45 uint8_t *dst, size_t length, const uint8_t *src)
47 const uint8_t *in = src + length;
48 uint8_t *out = dst + BASE64_ENCODE_RAW_LENGTH(length);
50 unsigned left_over = length % 3;
60 *--out = ENCODE(alphabet, (in[0] << 4));
64 *--out = ENCODE(alphabet, (in[1] << 2));
65 *--out = ENCODE(alphabet, ((in[0] << 4) | (in[1] >> 4)));
71 *--out = ENCODE(alphabet, (in[0] >> 2));
77 *--out = ENCODE(alphabet, (in[2]));
78 *--out = ENCODE(alphabet, ((in[1] << 2) | (in[2] >> 6)));
79 *--out = ENCODE(alphabet, ((in[0] << 4) | (in[1] >> 4)));
80 *--out = ENCODE(alphabet, (in[0] >> 2));
86 static const uint8_t base64_encode_table[64] =
87 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
88 "abcdefghijklmnopqrstuvwxyz"
92 base64_encode_raw(uint8_t *dst, size_t length, const uint8_t *src)
94 encode_raw(base64_encode_table, dst, length, src);
98 base64_encode_group(uint8_t *dst, uint32_t group)
100 *dst++ = ENCODE(base64_encode_table, (group >> 18));
101 *dst++ = ENCODE(base64_encode_table, (group >> 12));
102 *dst++ = ENCODE(base64_encode_table, (group >> 6));
103 *dst++ = ENCODE(base64_encode_table, group);
107 base64_encode_init(struct base64_encode_ctx *ctx)
109 ctx->word = ctx->bits = 0;
110 ctx->alphabet = base64_encode_table;
113 /* Encodes a single byte. */
115 base64_encode_single(struct base64_encode_ctx *ctx,
120 unsigned word = ctx->word << 8 | src;
121 unsigned bits = ctx->bits + 8;
126 dst[done++] = ENCODE(ctx->alphabet, (word >> bits));
137 /* Returns the number of output characters. DST should point to an
138 * area of size at least BASE64_ENCODE_LENGTH(length). */
140 base64_encode_update(struct base64_encode_ctx *ctx,
146 size_t left = length;
150 while (ctx->bits && left)
153 done += base64_encode_single(ctx, dst + done, *src++);
156 left_over = left % 3;
157 bulk = left - left_over;
163 encode_raw(ctx->alphabet, dst + done, bulk, src);
164 done += BASE64_ENCODE_RAW_LENGTH(bulk);
172 done += base64_encode_single(ctx, dst + done, *src++);
175 assert(done <= BASE64_ENCODE_LENGTH(length));
180 /* DST should point to an area of size at least
181 * BASE64_ENCODE_FINAL_SIZE */
183 base64_encode_final(struct base64_encode_ctx *ctx,
187 unsigned bits = ctx->bits;
191 dst[done++] = ENCODE(ctx->alphabet, (ctx->word << (6 - ctx->bits)));
192 for (; bits < 6; bits += 2)
198 assert(done <= BASE64_ENCODE_FINAL_LENGTH);