[Add] Start of base64 encode/decode routines. Not quite working yet.
This commit is contained in:
parent
e77ac4a022
commit
8b12c22369
105
src/base64.c
Normal file
105
src/base64.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Encode table.
|
||||||
|
static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu \
|
||||||
|
vwxyz0123456789+/";
|
||||||
|
// Decode table.
|
||||||
|
static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW \
|
||||||
|
$$$$$$XYZ[\\]^_'abcdefghijklmnopq";
|
||||||
|
|
||||||
|
// Encode src of sz length storing the new length in len.
|
||||||
|
char* base64_encode(int* len, char* src, size_t sz) {
|
||||||
|
char* r;
|
||||||
|
size_t i, c;
|
||||||
|
uint32_t n;
|
||||||
|
uint8_t ch[4], pad;
|
||||||
|
|
||||||
|
// Create r.
|
||||||
|
c = sz * 4 / 3 + sz % 3;
|
||||||
|
c += c / 76;
|
||||||
|
(*len) = c;
|
||||||
|
r = malloc((*len) * sizeof(char));
|
||||||
|
|
||||||
|
// Setup padding.
|
||||||
|
pad = sz % 3;
|
||||||
|
|
||||||
|
// Time to do the bulk of the work.
|
||||||
|
i = 0;
|
||||||
|
for(c = 0; c < sz; c += 3) {
|
||||||
|
// Specification wants newline after every 76 characters.
|
||||||
|
if((c > 0) && ((c / 3 * 4) % 76 == 0))
|
||||||
|
r[i++] = '\n';
|
||||||
|
|
||||||
|
// n is 24 bits.
|
||||||
|
n = (src[c] << 16) +
|
||||||
|
(c+1<sz) ? (src[c+1] << 8) : 0 + // May be out of range.
|
||||||
|
(c+2<sz) ? src[c+2] : 0; // May be out of range.
|
||||||
|
|
||||||
|
// ch[0-3] are 6 bits each.
|
||||||
|
ch[0] = (n >> 18) & 63;
|
||||||
|
ch[1] = (n >> 12) & 63;
|
||||||
|
ch[2] = (n >> 6) & 63;
|
||||||
|
ch[3] = n & 63;
|
||||||
|
|
||||||
|
r[i++] = cb64[ch[0]];
|
||||||
|
r[i++] = cb64[ch[1]];
|
||||||
|
r[i++] = cb64[ch[2]];
|
||||||
|
r[i++] = cb64[ch[3]];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(c = 0; c < pad; c++)
|
||||||
|
r[i++] = '=';
|
||||||
|
r[i] = '\0';
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int dec_valid(char inp) {
|
||||||
|
if((inp < 43) || (inp > 122) || cd64[(int)inp-43] == '$')
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char dec_ch(char inp) {
|
||||||
|
return cd64[(int)inp-43] - 61;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* base64_decode(int* len, char* src, size_t sz) {
|
||||||
|
char* r, *dat;
|
||||||
|
size_t c, i, j;
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
// Allocate r.
|
||||||
|
c = sz * 3 / 4;
|
||||||
|
r = malloc(c * sizeof(char));
|
||||||
|
|
||||||
|
// Create a clean version of the text.
|
||||||
|
dat = malloc(sz * sizeof(char));
|
||||||
|
j = 0;
|
||||||
|
for(i = 0; i < sz; i++) {
|
||||||
|
if(src[i] == '=')
|
||||||
|
dat[j++] = '\0';
|
||||||
|
else if(dec_valid(src[i]))
|
||||||
|
dat[j++] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill r.
|
||||||
|
i = 0;
|
||||||
|
for(c = 0; c < j; c += 4) {
|
||||||
|
n = dec_ch(dat[c+0]) << 18;
|
||||||
|
n = dec_ch(dat[c+1]) << 12;
|
||||||
|
n = dec_ch(dat[c+2]) << 6;
|
||||||
|
n = dec_ch(dat[c+3]) << 0;
|
||||||
|
|
||||||
|
r[i++] = (n >> 16) & 0xFF;
|
||||||
|
r[i++] = (n >> 8) & 0xFF;
|
||||||
|
r[i++] = (n >> 0) & 0xFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(*len) = i;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
5
src/base64.h
Normal file
5
src/base64.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
char* base64_encode(int* len, char* src, size_t sz);
|
||||||
|
char* base64_decode(int* len, char* src, size_t sz);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user