/* base64.c - Encode and decode base64 * * Copyright 2014 Rob Landley * * See https://tools.ietf.org/html/rfc4648 // These optflags have to match. Todo: cleanup and collapse together? USE_BASE64(NEWTOY(base64, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN)) USE_BASE32(NEWTOY(base32, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN)) config BASE64 bool "base64" default y help usage: base64 [-di] [-w COLUMNS] [FILE...] Encode or decode in base64. -d Decode -i Ignore non-alphabetic characters -w Wrap output at COLUMNS (default 76 or 0 for no wrap) config BASE32 bool "base32" default y help usage: base32 [-di] [-w COLUMNS] [FILE...] Encode or decode in base32. -d Decode -i Ignore non-alphabetic characters -w Wrap output at COLUMNS (default 76 or 0 for no wrap) */ #define FOR_base64 #define FORCE_FLAGS #include "toys.h" GLOBALS( long w; unsigned total; unsigned n; // number of bits used in encoding. 5 for base32, 6 for base64 unsigned align; // number of bits to align to ) static void wraputchar(int c, int *x) { putchar(c); TT.total++; if (TT.w && ++*x == TT.w) { *x = 0; xputc('\n'); }; } static void do_base(int fd, char *name) { int out = 0, bits = 0, x = 0, i, len; char *buf = toybuf+128; TT.total = 0; for (;;) { // If no more data, flush buffer if (!(len = xread(fd, buf, sizeof(toybuf)-128))) { if (!FLAG(d)) { if (bits) wraputchar(toybuf[out<<(TT.n-bits)], &x); while (TT.total&TT.align) wraputchar('=', &x); if (x) xputc('\n'); } return; } for (i=0; i= TT.n) { wraputchar(toybuf[out >> (bits -= TT.n)], &x); out &= (1<