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