Skip to content

Instantly share code, notes, and snippets.

@gue-ni
Last active April 29, 2021 08:28
Show Gist options
  • Save gue-ni/1972890bd5ad4586ffaf2bd04af310cf to your computer and use it in GitHub Desktop.
Save gue-ni/1972890bd5ad4586ffaf2bd04af310cf to your computer and use it in GitHub Desktop.
/*
@author: Jakob Maier
@brief: simple base64 encoder/decoder
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
uint8_t dict(uint8_t n)
{
if (n < 26)
return n + 65;
if (n < 52)
return n + 71;
if (n < 62)
return n - 4;
if (n == 0x3E)
return 0x2B;
return 0x2F;
}
uint8_t rdict(uint8_t n)
{
if (n > 0x40 && n < 0x5B)
return n - 65;
if (n > 0x60 && n < 0x7B)
return n - 71;
if (n < 0x3A && n > 0x2F)
return n + 4;
if (n == 0x2B)
return 0x3E;
if (n == 0x2F)
return 0x3F;
return 0x00;
}
void b64_decode(uint8_t *in, uint8_t *out, size_t size)
{
for (int i = 0; i < 4; i++)
{
in[i] = rdict(in[i]);
}
out[0] = (uint8_t) ((in[0] << 2) | (in[1] >> 4));
out[1] = (uint8_t) ((in[1] << 4) | (in[2] >> 2));
out[2] = (uint8_t) (((in[2] << 6) & 0xC0) | in[3]);
}
void b64_encode(uint8_t *in, uint8_t *out, size_t size)
{
memset(in + size, 0x00, 3 - size);
out[0] = dict( in[0] >> 2 );
out[1] = dict( ( ( in[0] & 0x03 ) << 4 ) | ( ( in[1] & 0xF0 ) >> 4) );
out[2] = size > 1 ? dict( ( ( in[1] & 0x0F ) << 2 ) | ( ( in[2] & 0xC0 ) >> 6) ) : (uint8_t) '=';
out[3] = size > 2 ? dict( in[2] & 0x3F ) : (uint8_t) '=';
}
int main(int argc, char *argv[])
{
size_t n;
int encode = 1;
int c;
while ( (c = getopt(argc, argv, "de")) != -1)
{
switch (c)
{
case 'd':
encode = !encode;
break;
case 'e':
break;
default:
fprintf(stderr, "Usage: %s [ -d | -e ]\n", argv[0]);
exit(0);
break;
}
}
size_t n_in, n_out;
if (encode)
{
n_in = 3;
n_out = 4;
} else {
n_in = 4;
n_out = 3;
}
uint8_t in[n_in], out[n_out];
// FILE *input = fopen("encoded", "r");
FILE *input = stdin;
while( (n = fread(in, 1, sizeof(in), input)) > 0)
{
if (encode)
{
b64_encode(in, out, n);
} else {
b64_decode(in, out, n);
}
fwrite(out, 1, sizeof(out), stdout);
}
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment