You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
2.5 KiB
123 lines
2.5 KiB
/* base64.c - Encode and decode base64
|
|
*
|
|
* Copyright 2014 Rob Landley <rob@landley.net>
|
|
*
|
|
* 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<len; i++) {
|
|
if (FLAG(d)) {
|
|
if (buf[i] == '=') return;
|
|
|
|
if ((x = stridx(toybuf, buf[i])) != -1) {
|
|
out = (out<<TT.n) + x;
|
|
bits += TT.n;
|
|
if (bits >= 8) {
|
|
putchar(out >> (bits -= 8));
|
|
out &= (1<<bits)-1;
|
|
if (ferror(stdout)) perror_exit(0);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if (buf[i] == '\n' || FLAG(i)) continue;
|
|
|
|
break;
|
|
} else {
|
|
out = (out<<8) + buf[i];
|
|
bits += 8;
|
|
while (bits >= TT.n) {
|
|
wraputchar(toybuf[out >> (bits -= TT.n)], &x);
|
|
out &= (1<<bits)-1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void base64_main(void)
|
|
{
|
|
TT.n = 6;
|
|
TT.align = 3;
|
|
base64_init(toybuf);
|
|
loopfiles(toys.optargs, do_base);
|
|
}
|
|
|
|
void base32_main(void)
|
|
{
|
|
int i;
|
|
|
|
TT.n = 5;
|
|
TT.align = 7;
|
|
for (i = 0; i<32; i++) toybuf[i] = i+(i<26 ? 'A' : 24);
|
|
loopfiles(toys.optargs, do_base);
|
|
}
|