1 /* Copyright 2015 Jann Horn <jann@thejh.net>.
2 * See LICENSE for license information.
4 * This file performs Base64 encoding and decoding using the
5 * "URL and Filename Safe Alphabet" from RFC 4648; however, it does
6 * not attempt to be RFC-compliant apart from the choice of alphabet.
7 * These Base64 routines are not generic; they only convert between
8 * 24 bits of binary data and 4 characters of Base64.
18 static char alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
20 static char bin_to_char(uint32_t n) {
24 static uint32_t char_to_bin(char c) {
25 char *p = strchr(alphabet, c);
27 fprintf(stderr, "invalid base64 character encountered: '%c'\n", c);
33 /* base64-encode 24 bits of data, least significant bits first */
34 void base64_encode(uint32_t n, char out[5]) {
35 assert((n & 0xff000000U) == 0);
36 for (int i = 0; i < 4; i++) {
37 out[i] = bin_to_char(n & 0x3f);
44 uint32_t base64_decode(char *in) {
45 size_t len = strlen(in);
47 fprintf(stderr, "Expected 4 bytes of Base64 data, but got %d\n", (int)len);
51 for (int i = 3; i >= 0; i--) {
53 out |= char_to_bin(in[i]);
55 assert((out & 0xff000000U) == 0);