base64
This commit is contained in:
parent
7e7bd195a9
commit
b3f67a38de
23
include/tlibc/base64.h
Normal file
23
include/tlibc/base64.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "tlibc/std.h"
|
||||||
|
|
||||||
|
/// @param src_size size of data to encode
|
||||||
|
/// @return number of encoded characters. Is a multiple of 4.
|
||||||
|
u32 base64_encodedSize(u32 src_size);
|
||||||
|
|
||||||
|
/// @param src data to encode
|
||||||
|
/// @param src_size size of data to encode
|
||||||
|
/// @param dst buffer of size base64_encodedSize(src_size)
|
||||||
|
/// @return number of encoded characters. Is a multiple of 4.
|
||||||
|
u32 base64_encode(const u8* src, u32 src_size, char* dst);
|
||||||
|
|
||||||
|
/// @param src data to decode
|
||||||
|
/// @param src_size size of data to decode. Must be a multiple of 4 for valid base64 data.
|
||||||
|
/// @return number of decoded characters or 0 on error
|
||||||
|
u32 base64_decodedSize(const char* src, u32 src_size);
|
||||||
|
|
||||||
|
/// @param src data to decode
|
||||||
|
/// @param src_size size of data to decode. Must be a multiple of 4 for valid base64 data.
|
||||||
|
/// @param dst buffer of size base64_decodedSize(src, src_size)
|
||||||
|
/// @return number of decoded characters or 0 on error
|
||||||
|
u32 base64_decode(const u8* src, u32 src_size, u8* dst);
|
||||||
86
src/base64.c
Normal file
86
src/base64.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include "tlibc/base64.h"
|
||||||
|
|
||||||
|
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c
|
||||||
|
|
||||||
|
u32 base64_encodedSize(u32 src_size){
|
||||||
|
u32 ret = src_size;
|
||||||
|
if (src_size % 3 != 0)
|
||||||
|
ret += 3 - (src_size % 3);
|
||||||
|
ret /= 3;
|
||||||
|
ret *= 4;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
u32 base64_encode(const u8* src, u32 src_size, char* dst){
|
||||||
|
u32 i = 0, j = 0, v = 0;
|
||||||
|
for (; i < src_size; i += 3) {
|
||||||
|
v = src[i];
|
||||||
|
v = i + 1 < src_size ? v << 8 | src[i + 1] : v << 8;
|
||||||
|
v = i + 2 < src_size ? v << 8 | src[i + 2] : v << 8;
|
||||||
|
|
||||||
|
dst[j++] = b64chars[(v >> 18) & 0x3F];
|
||||||
|
dst[j++] = b64chars[(v >> 12) & 0x3F];
|
||||||
|
dst[j++] = i + 1 < src_size ? b64chars[(v >> 6) & 0x3F] : '=';
|
||||||
|
dst[j++] = i + 2 < src_size ? b64chars[v & 0x3F] : '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 base64_decodedSize(const char* src, u32 src_size){
|
||||||
|
// incomplete src
|
||||||
|
if(src_size % 4 != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
u32 ret = src_size / 4 * 3;
|
||||||
|
u32 i = src_size;
|
||||||
|
while(i > 0 && src[--i] == '=') {
|
||||||
|
ret--;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void base64_generateDecodeTable(){
|
||||||
|
int inv[80];
|
||||||
|
memset(inv, -1, sizeof(inv));
|
||||||
|
for (u32 i = 0; i < 64; i + +) {
|
||||||
|
inv[b64chars[i] - 43] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int b64inverse[] = {
|
||||||
|
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
||||||
|
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
|
||||||
|
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
|
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
|
||||||
|
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
||||||
|
43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 base64_decode(const u8* src, u32 src_size, u8* dst){
|
||||||
|
// incomplete src
|
||||||
|
if(src_size % 4 != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
u32 i = 0, j = 0, v = 0;
|
||||||
|
for (; i < src_size; i += 4) {
|
||||||
|
v = b64inverse[src[i] - 43];
|
||||||
|
v = (v << 6) | b64inverse[src[i + 1] - 43];
|
||||||
|
v = src[i + 2]=='=' ? v << 6 : (v << 6) | b64inverse[src[i + 2] - 43];
|
||||||
|
v = src[i + 3]=='=' ? v << 6 : (v << 6) | b64inverse[src[i + 3] - 43];
|
||||||
|
|
||||||
|
dst[j++] = (v >> 16) & 0xFF;
|
||||||
|
if (src[i + 2] != '='){
|
||||||
|
dst[j++] = (v >> 8) & 0xFF;
|
||||||
|
}
|
||||||
|
if (src[i + 3] != '='){
|
||||||
|
dst[j++] = v & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user