[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