diff options
author | P. J. McDermott <pjm@nac.net> | 2013-02-14 18:03:09 (EST) |
---|---|---|
committer | P. J. McDermott <pjm@nac.net> | 2013-02-14 18:03:09 (EST) |
commit | 80191b41352ad20493fb62e8f3683d69133d0d24 (patch) | |
tree | cb77e93dfe476d9535ca48e732a98aae9a780ba4 /src/base64.c | |
download | overworld-rpg-80191b41352ad20493fb62e8f3683d69133d0d24.zip overworld-rpg-80191b41352ad20493fb62e8f3683d69133d0d24.tar.gz overworld-rpg-80191b41352ad20493fb62e8f3683d69133d0d24.tar.bz2 |
Initial commit.
Diffstat (limited to 'src/base64.c')
-rw-r--r-- | src/base64.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..6a2c873 --- /dev/null +++ b/src/base64.c @@ -0,0 +1,95 @@ +#include "base64.h" + +static void +base64_decode_block(const char *src, char *dest) +{ + int i; + char buf[4]; + + /* Convert base 64 characters into values. */ + /* Supports ASCII and EBCDIC systems. */ + for (i = 0; i < 4; ++i) { + if (src[i] >= 'A' && src[i] <= 'I') { + buf[i] = src[i] - 'A' + 0; + } else if (src[i] >= 'J' && src[i] <= 'R') { + buf[i] = src[i] - 'J' + 9; + } else if (src[i] >= 'S' && src[i] <= 'Z') { + buf[i] = src[i] - 'S' + 18; + } else if (src[i] >= 'a' && src[i] <= 'i') { + buf[i] = src[i] - 'a' + 26; + } else if (src[i] >= 'j' && src[i] <= 'r') { + buf[i] = src[i] - 'j' + 35; + } else if (src[i] >= 's' && src[i] <= 'z') { + buf[i] = src[i] - 's' + 44; + } else if (src[i] >= '0' && src[i] <= '9') { + buf[i] = src[i] - '0' + 52; + } else if (src[i] == '+') { + buf[i] = 62; + } else if (src[i] == '/') { + buf[i] = 63; + } else { + buf[i] = '\0'; + } + } + + /* Map four decoded value bytes into three output bytes. */ + dest[0] = (buf[0] << 2) | (buf[1] >> 4); + dest[1] = (buf[1] << 4) | (buf[2] >> 2); + dest[2] = (buf[2] << 6) | (buf[3] >> 0); +} + +void +base64_decode(const char *src, char *dest, size_t dest_len) +{ + size_t i; + + /* Decode the input one entire block at a time. */ + for (i = 0; i < (dest_len - 1) / 3; ++i) { + if (src[i * 4] == '\0' || + src[i * 4 + 1] == '\0' || + src[i * 4 + 2] == '\0' || + src[i * 4 + 3] == '\0') { + dest[i * 3] = '\0'; + break; + } + base64_decode_block(src + i * 4, dest + i * 3); + } + + /* Ensure NUL termination. */ + dest[dest_len - 1] = '\0'; +} + +#if 0 +int +main() +{ + char dest[1024]; + base64_decode( + "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5v" + "dCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1" + "dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Np" + "b24gZnJvbSBvdGhlciBhbmltYWxzLCB3" + "aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1p" + "bmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFu" + "Y2Ugb2YgZGVsaWdodCBpbiB0aGUgY29u" + "dGludWVkIGFuZCBpbmRlZmF0aWdhYmxl" + "IGdlbmVyYXRpb24gb2Yga25vd2xlZGdl" + "LCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhl" + "bWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVh" + "c3VyZS4=", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhc3VyZS4=", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhc3VyZQ==", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhc3Vy", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhc3U=", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhcw==", dest, 1024); + printf("Decoded string: \"%s\"\n", dest); + base64_decode("YW55IGNhcm5hbCBwbGVhcw==", dest, 4); + printf("Decoded string: \"%s\"\n", dest); + return 0; +} +#endif |