#include #include #include "types.h" #include "base64.h" static const u8 base64f[256] = { //00 01 02 03 04 05 06 07 //08 09 0A 0B 0C 0D 0E 0F // 0x00..0x3F 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 // 0x40..0x7F 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 // 0x80..0xBF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0..0xFF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; size_t base64_from(u8 *dst,const char *src,size_t srclen) { if (srclen % 4) { return -1; } else if (!srclen) { return 0; } size_t dstlen = BASE64_FROM_LEN(srclen); dstlen -= (src[srclen - 1] == '='); dstlen -= (src[srclen - 2] == '='); for (size_t i = 0, j = 0; i < srclen;) { u32 sixbits[4]; sixbits[0] = base64f[(unsigned char)src[i++]]; sixbits[1] = base64f[(unsigned char)src[i++]]; sixbits[2] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]); sixbits[3] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]); u32 threebytes = 0 | (sixbits[0] << (3 * 6)) | (sixbits[1] << (2 * 6)) | (sixbits[2] << (1 * 6)) | (sixbits[3] << (0 * 6)); if (j < dstlen) dst[j++] = (threebytes >> (2 * 8)); if (j < dstlen) dst[j++] = (threebytes >> (1 * 8)) & 0xff; if (j < dstlen) dst[j++] = (threebytes >> (0 * 8)) & 0xff; } return dstlen; } int base64_valid(const char *src,size_t *count) { const char *p; for (p = src;base64f[(u8)*p] != 0xFF;++p) ; for (;((size_t) (p - src)) % 4 != 0 && *p == '=';++p) ; if (count) *count = (size_t) (p - src); return !*p && ((size_t) (p - src)) % 4 == 0; }