aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Röhrich <moritz@ildefons.de>2021-01-07 17:40:20 +0100
committerRob Landley <rob@landley.net>2021-01-07 16:10:47 -0600
commitb6b5becf359370c7f32d8419bcf8f50a47fbe933 (patch)
tree4926ca2fe9180730dd9adfcb464d16c8d4ba2ffc
parent824de078e4bdc752da9559cc64df627028310cc3 (diff)
downloadtoybox-b6b5becf359370c7f32d8419bcf8f50a47fbe933.tar.gz
new toy: base32
Add new toy `base32`. Add tests for `base32`. base32 is added by adapting the base64 encode/decode function to also do base32 encoding/decoding. Then their respective main functions set up the global parameter `n` to be the number of bits used in the encoding (5 for base32 and 6 for base64) and `align` to align the result to a certain length via padding. These are deliberately kept as parameters to enable future expansion for other bases easily.
-rw-r--r--lib/lib.c12
-rw-r--r--lib/lib.h1
-rwxr-xr-xtests/base32.test24
-rw-r--r--toys/other/base64.c46
4 files changed, 74 insertions, 9 deletions
diff --git a/lib/lib.c b/lib/lib.c
index dfa4499f..1aa9b80d 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -870,6 +870,18 @@ void base64_init(char *p)
*(p++) = '/';
}
+// Init base32 table
+
+void base32_init(char *p)
+{
+ int i;
+
+ for (i = 'A'; i != '8'; i++) {
+ if (i == 'Z'+1) i = '2';
+ *(p++) = i;
+ }
+}
+
int yesno(int def)
{
return fyesno(stdin, def);
diff --git a/lib/lib.h b/lib/lib.h
index 431ce5ad..1ba59ee3 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -255,6 +255,7 @@ void delete_tempfile(int fdin, int fdout, char **tempname);
void replace_tempfile(int fdin, int fdout, char **tempname);
void crc_init(unsigned int *crc_table, int little_endian);
void base64_init(char *p);
+void base32_init(char *p);
int yesno(int def);
int fyesno(FILE *fp, int def);
int qstrcmp(const void *a, const void *b);
diff --git a/tests/base32.test b/tests/base32.test
new file mode 100755
index 00000000..00bcffa9
--- /dev/null
+++ b/tests/base32.test
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+# testing "name" "flags" "result" "infile" "stdin"
+
+testcmd "simple" "" "ONUW24DMMUFA====\n" "" "simple\n"
+testcmd "file" "input" "ONUW24DMMUFA====\n" "simple\n" ""
+testcmd "simple -d" "-d" "simple\n" "" "ONUW24DMMUFA====\n"
+testcmd "file -d" "-d input" "simple\n" "ONUW24DMMUFA====" ""
+testcmd "default wrap" "" \
+ "K5SSO5TFEBZGK4DMMFRWKZBAORUGKIDENFWGS5DINF2W2IDUNBSXSIDON5ZG2YLMNR4SA5LTMUQH\nO2LUNAQEM33MM5SXEJ3TEBBXE6LTORQWY4ZO\n" \
+ "" "We've replaced the dilithium they normally use with Folger's Crystals."
+testcmd "multiline -d " "-d" \
+ "We've replaced the dilithium they normally use with Folger's Crystals." "" \
+ "K5SSO5TFEBZGK4DMMFRWKZBAORUGKIDENFWGS5DINF2W2IDUNBSXSIDON5ZG2YLMNR4SA5LTMUQH\nO2LUNAQEM33MM5SXEJ3TEBBXE6LTORQWY4ZO\n"
+
+testcmd "-w" "-w 10" \
+ "JVQXEY3INF\nXGOIDUN4QH\nI2DFEBRGKY\nLUEBXWMIDB\nEBSGSZTGMV\nZGK3TUEBVW\nK5DUNRSSA3\n3GEBTGS43I\nFY======\n" \
+ "" "Marching to the beat of a different kettle of fish."
+
+testcmd "-w0" "-w0 input" \
+ "KZUWW2LOM5ZT6ICUNBSXEZJAMFUW4J3UEBXG6IDWNFVWS3THOMQGQZLSMUXCASTVON2CA5LTEBUG63TFON2CAZTBOJWWK4TTFYQFI2DFEB2G653OEB3WC4ZAMJ2XE3TJNZTSYIDUNBSSA5TJNRWGCZ3FOJZSA53FOJSSAZDFMFSC4ICUNBSXSIDENFSG4J3UEBXGKZLEEB2GQ33TMUQHG2DFMVYCAYLOPF3WC6JOEBKGQYLUE5ZSA33VOIQHG5DPOJ4SAYLOMQQHOZJHOJSSA43UNFRWW2LOM4QHI3ZANF2C4CQ=" \
+ "Vikings? There ain't no vikings here. Just us honest farmers. The town was burning, the villagers were dead. They didn't need those sheep anyway. That's our story and we're sticking to it.\n" ""
diff --git a/toys/other/base64.c b/toys/other/base64.c
index ef7854a1..25e37d41 100644
--- a/toys/other/base64.c
+++ b/toys/other/base64.c
@@ -5,6 +5,7 @@
* No standard
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"
@@ -17,6 +18,18 @@ config 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
@@ -24,8 +37,9 @@ config BASE64
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)
@@ -38,7 +52,7 @@ static void wraputchar(int c, int *x)
};
}
-static void do_base64(int fd, char *name)
+static void do_base_n(int fd, char *name)
{
int out = 0, bits = 0, x = 0, i, len;
char *buf = toybuf+128;
@@ -49,8 +63,8 @@ static void do_base64(int fd, char *name)
// If no more data, flush buffer
if (!(len = xread(fd, buf, sizeof(toybuf)-128))) {
if (!FLAG(d)) {
- if (bits) wraputchar(toybuf[out<<(6-bits)], &x);
- while (TT.total&3) wraputchar('=', &x);
+ if (bits) wraputchar(toybuf[out<<(TT.n-bits)], &x);
+ while (TT.total&TT.align) wraputchar('=', &x);
if (x) xputc('\n');
}
@@ -62,8 +76,8 @@ static void do_base64(int fd, char *name)
if (buf[i] == '=') return;
if ((x = stridx(toybuf, buf[i])) != -1) {
- out = (out<<6) + x;
- bits += 6;
+ out = (out<<TT.n) + x;
+ bits += TT.n;
if (bits >= 8) {
putchar(out >> (bits -= 8));
out &= (1<<bits)-1;
@@ -78,8 +92,8 @@ static void do_base64(int fd, char *name)
} else {
out = (out<<8) + buf[i];
bits += 8;
- while (bits >= 6) {
- wraputchar(toybuf[out >> (bits -= 6)], &x);
+ while (bits >= TT.n) {
+ wraputchar(toybuf[out >> (bits -= TT.n)], &x);
out &= (1<<bits)-1;
}
}
@@ -89,6 +103,20 @@ static void do_base64(int fd, char *name)
void base64_main(void)
{
+ TT.n = 6;
+ TT.align = 3;
base64_init(toybuf);
- loopfiles(toys.optargs, do_base64);
+ loopfiles(toys.optargs, do_base_n);
+}
+
+#define CLEANUP_base64
+#define FOR_base32
+#include "generated/flags.h"
+
+void base32_main(void)
+{
+ TT.n = 5;
+ TT.align = 7;
+ base32_init(toybuf);
+ loopfiles(toys.optargs, do_base_n);
}