Created
April 29, 2015 22:58
-
-
Save deepcube/e34e4ecfc443c178176a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* base64 | |
* with no arguments read from stdin and write base64 encoded output to stdout | |
* with argument -d read base64 encoded input from stdin and write decoded output to stdout | |
* exit status 1 on any error | |
* ignores newlines in encoded input | |
* any illegal character in encoded input causes error | |
* no newlines in encoded output | |
* does not require padding (=) but if padding is present it must be correct | |
* after padding more encoded input may follow | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
char code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
int encode(int c) | |
{ | |
static unsigned char s[3] = { 0 }; | |
static int i = 0; | |
if (c == EOF) | |
for (int j = i; j < 3; j++) | |
s[j] = 0; | |
else | |
s[i++] = c; | |
if (i == 3 || (i && c == EOF)) { | |
putchar( code[(s[0] >> 2 ) ] ); | |
putchar( code[(s[0] << 4 | s[1] >> 4) & 0x3f] ); | |
putchar(i > 1 ? code[(s[1] << 2 | s[2] >> 6) & 0x3f] : '='); | |
putchar(i > 2 ? code[(s[2] ) & 0x3f] : '='); | |
i = 0; | |
} | |
return c != EOF; | |
} | |
int decode(int c) | |
{ | |
static char s[4] = { 0 }; | |
static int i = 0; | |
char *p = strchr(code, c); | |
if (c == '\n') | |
return 1; | |
if ((c == '=' && i < 2) || | |
(c == EOF && i && i < 2) || | |
(c != EOF && c != '=' && !p) || | |
(c == '=' && i == 2 && (c = getchar()) != '=')) | |
exit(1); | |
if (p) | |
s[i++] = p - code; | |
if (i == 4 || c == '=' || c == EOF) { | |
if (i > 1) putchar((s[0] << 2 | s[1] >> 4) & 0xff); | |
if (i > 2) putchar((s[1] << 4 | s[2] >> 2) & 0xff); | |
if (i > 3) putchar((s[2] << 6 | s[3] ) & 0xff); | |
i = 0; | |
} | |
return c != EOF; | |
} | |
int main(int argc, char **argv) | |
{ | |
int (*fn)(int) = encode; | |
if (argc == 2 && !strcmp(argv[1], "-d")) | |
fn = decode; | |
else if (argc != 1) | |
exit(1); | |
while (fn(getchar())) | |
; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment