CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/Data/Encoding/Base64.cpp
Views: 1401
#include "Common/Data/Encoding/Base64.h"12// TODO: This is a simple but not very efficient implementation.3std::string Base64Encode(const uint8_t *p, size_t sz) {4static const char digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";56size_t unpaddedLength = (4 * sz + 2) / 3;7std::string result;8result.resize((unpaddedLength + 3) & ~3, '=');910for (size_t i = 0; i < unpaddedLength; ++i) {11// This is the index into the original string.12size_t pos = (i * 3) / 4;13int8_t off = 2 * ((i * 3) % 4);1415int c = p[pos];16if (off > 2) {17c <<= 8;18off -= 8;1920// Grab more bits from the next character.21if (pos + 1 < sz) {22c |= p[pos + 1];23}24}2526// Since we take from the big end, off starts at 2 and goes down.27int8_t shift = 2 - off;2829// Now take the bits at off and encode the character.30result[i] = digits[(c >> shift) & 0x3F];31}3233return result;34}3536std::vector<uint8_t> Base64Decode(const char *s, size_t sz) {37static const uint8_t lookup[256] = {38255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,39255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,40255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 63, 62, 255, 63,41// '0' starts here.4252, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,43// 'A' after an invalid.44255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,4515, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,46// 'a' after an invalid.47255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,4841, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,49};5051const uint8_t *p = (const uint8_t *)s;52std::vector<uint8_t> result;53result.reserve(3 * sz / 4);5455for (size_t i = 0; i < sz; i += 4) {56uint8_t quad[4] = {57lookup[p[i]],58i + 1 < sz ? lookup[p[i + 1]] : (uint8_t)255,59i + 2 < sz ? lookup[p[i + 2]] : (uint8_t)255,60i + 3 < sz ? lookup[p[i + 3]] : (uint8_t)255,61};6263// First: ABCDEF GHXXXX XXXXXX XXXXXX. Neither 6-bit value should be invalid.64result.push_back((quad[0] << 2) | ((quad[1] & 0x30) >> 4));6566// Next: XXXXXX XXABCD EFGHXX XXXXXX. Invalid if quad[2] is invalid.67if (quad[2] == 255) {68continue;69}70result.push_back(((quad[1] & 0x0F) << 4) | ((quad[2] & 0x3C) >> 2));7172// Last: XXXXXX XXXXXX XXXXAB CDEFGH. Invalid only if quad[3] is.73if (quad[3] == 255) {74continue;75}76result.push_back(((quad[2] & 0x03) << 6) | (quad[3] & 0x3F));77}7879return result;80}818283