summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2017-01-07 16:05:05 +1300
committerDavid Phillips <david@sighup.nz>2017-01-07 16:05:05 +1300
commit6862f27687a497aa559746b22173f2a02f1210a7 (patch)
tree3736623dca168b5632db23b4afe0cb13ddd2476f
parent96ff2d2ec1b3e101c76e299927975fefb81178d2 (diff)
downloadodds-and-ends-6862f27687a497aa559746b22173f2a02f1210a7.tar.xz
Add base64 thing
-rw-r--r--.gitignore1
-rw-r--r--base64/Makefile1
-rw-r--r--base64/base64.c49
3 files changed, 51 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 00e3b3e..d9a6211 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
words-misc/match_pool
words-misc/permutations
monty/monty
+base64/base64
*.o
diff --git a/base64/Makefile b/base64/Makefile
new file mode 100644
index 0000000..59d1285
--- /dev/null
+++ b/base64/Makefile
@@ -0,0 +1 @@
+base64:
diff --git a/base64/base64.c b/base64/base64.c
new file mode 100644
index 0000000..e27217c
--- /dev/null
+++ b/base64/base64.c
@@ -0,0 +1,49 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#define BYTES_PER_BLOCK 3
+#define BASE64_PER_BLOCK 4
+
+const char *lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+void dump_base64_block(const unsigned char *data, size_t len, FILE* stream)
+{
+ char out_block[BASE64_PER_BLOCK+1];
+
+ memset(out_block, '=', sizeof(out_block));
+ out_block[4] = '\0';
+
+ switch(len) {
+ case 3:
+ out_block[3] = lookup[data[2] & 0x3F];
+ case 2:
+ out_block[2] = lookup[(data[1] & 0x0F) << 2 | data[2] >> 6];
+ case 1:
+ out_block[1] = lookup[(data[0] & 0x03) << 4 | (data[1] & 0xF0) >> 4];
+ out_block[0] = lookup[data[0] >> 2];
+ fputs(out_block, stream);
+ break;
+ default:
+ break;
+ }
+}
+
+void dump_base64(FILE* in, FILE* out)
+{
+ size_t nread = 0;
+ char buffer[BYTES_PER_BLOCK+1];
+
+ while (!feof(in)) {
+ nread = fread(buffer, 1, BYTES_PER_BLOCK, in);
+ buffer[nread] = '\0';
+ dump_base64_block(buffer, nread, out);
+ }
+}
+
+int main(void)
+{
+ dump_base64(stdin, stdout);
+ fputc('\n', stdout);
+}