From 1c4fa4290c4b8b231f38fb009dc1c5f237a4a088 Mon Sep 17 00:00:00 2001 Message-Id: <1c4fa4290c4b8b231f38fb009dc1c5f237a4a088.1714721728.git.mdw@distorted.org.uk> From: Mark Wooding Date: Tue, 28 Sep 2004 14:11:09 +0000 Subject: [PATCH] Add base32 encoding and decoding. Organization: Straylight/Edgeware From: mdw --- Makefile.am | 24 +++- base32.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++ base32.h | 104 +++++++++++++++++ base32.in | 21 ++++ base32.ref | 54 +++++++++ man/Makefile.am | 13 ++- man/base32.3 | 95 +++++++++++++++ man/base64.3 | 2 + man/hex.3 | 1 + sym-gtest | 4 +- 10 files changed, 606 insertions(+), 12 deletions(-) create mode 100644 base32.c create mode 100644 base32.h create mode 100644 base32.in create mode 100644 base32.ref create mode 100644 man/base32.3 diff --git a/Makefile.am b/Makefile.am index db7de36..b727d9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## -*-Makefile-*- ## -## $Id: Makefile.am,v 1.46 2004/04/08 01:36:11 mdw Exp $ +## $Id$ ## ## Building the distribution ## @@ -50,7 +50,7 @@ pkginclude_HEADERS = \ env.h fdflags.h fdpass.h fwatch.h lock.h \ bres.h conn.h lbuf.h ident.h pkbuf.h sel.h selbuf.h selpk.h sig.h \ tv.h \ - base64.h hex.h mdwopt.h str.h testrig.h url.h + base64.h base32.h hex.h mdwopt.h str.h testrig.h url.h ## --- Things to put in the library --- @@ -69,7 +69,7 @@ libmLib_la_SOURCES = \ @BRES_SOURCE@.c \ conn.c lbuf.c ident.c pkbuf.c sel.c selbuf.c selpk.c sig.c \ tv.c \ - base64.c hex.c mdwopt.c str.c testrig.c url.c + base64.c base32.c hex.c mdwopt.c str.c testrig.c url.c EXTRA_libmLib_la_SOURCES = bres.c bres-adns.c libmLib_la_LIBADD = @DEPLIBS@ @@ -99,6 +99,7 @@ noinst_PROGRAMS = da.t sym.t assoc.t bits.t check: \ da.test sym.test assoc.test bits.test base64.test hex.test \ + base32.test \ unihash.test da_t_SOURCES = da-test.c @@ -158,6 +159,19 @@ base64.test: base64.t base64.in base64.ref cmp base64.out $(srcdir)/base64.in @echo "base64 tested OK." +base32.to: base32.c + $(COMPILE) -c -DTEST_RIG -DSRCDIR=\"$(srcdir)\" \ + $(srcdir)/base32.c -o base32.to +base32.t: base32.to base32.o libmLib.la + $(CC) $(CFLAGS) $(LDFLAGS) \ + base32.to .libs/libmLib.a $(LIBS) -o base32.t +base32.test: base32.t base32.in base32.ref + ./base32.t <$(srcdir)/base32.in >base32.out + cmp base32.out $(srcdir)/base32.ref + ./base32.t -d <$(srcdir)/base32.ref >base32.out + cmp base32.out $(srcdir)/base32.in + @echo "base32 tested OK." + hex.to: hex.c $(COMPILE) -c -DTEST_RIG -DSRCDIR=\"$(srcdir)\" \ $(srcdir)/hex.c -o hex.to @@ -187,13 +201,13 @@ TEST_CLEAN = \ *.t *.to \ da.in da.ref da.out \ sym.in sym.ref sym.out \ - base64.out hex.out unihash.in + base64.out base32.out hex.out unihash.in TEST_DIST = \ da-gtest da-ref \ sym-gtest sym-ref \ bits.in bits-testgen.c \ - base64.in base64.ref hex.in hex.ref + base64.in base64.ref base32.in base32.ref hex.in hex.ref ## --- Background resolver --- ## diff --git a/base32.c b/base32.c new file mode 100644 index 0000000..d9b24b2 --- /dev/null +++ b/base32.c @@ -0,0 +1,300 @@ +/* -*-c-*- + * + * $Id$ + * + * Base32 encoding and decoding. + * + * (c) 1997 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include + +#include "base32.h" +#include "dstr.h" + +/*----- Important tables --------------------------------------------------*/ + +static const char encodemap[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" }; + +static const signed char decodemap[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 1x */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 2x */ + -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, /* 3x */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 4x */ + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 5x */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 6x */ + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 7x */ +}; + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @base32_encode@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to a context block + * @const void *p@ = pointer to a source buffer + * @size_t sz@ = size of the source buffer + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Encodes a binary string in base32. To flush out the final + * few characters (if necessary), pass a null source pointer. + */ + +void base32_encode(base32_ctx *ctx, + const void *p, size_t sz, + dstr *d) +{ + if (p) { + unsigned long accl = ctx->accl, acch = ctx->acch; + unsigned qsz = ctx->qsz; + const unsigned char *src = p; + + while (sz) { + acch = (acch << 8) | ((accl >> 24) & 0xff); + accl = (accl << 8) | *src++; + qsz++; + sz--; + if (qsz == 5) { + DPUTC(d, encodemap[(acch >> 3) & 0x1f]); + DPUTC(d, encodemap[((acch << 2) & 0x1c) | ((accl >> 30) & 0x03)]); + DPUTC(d, encodemap[(accl >> 25) & 0x1f]); + DPUTC(d, encodemap[(accl >> 20) & 0x1f]); + DPUTC(d, encodemap[(accl >> 15) & 0x1f]); + DPUTC(d, encodemap[(accl >> 10) & 0x1f]); + DPUTC(d, encodemap[(accl >> 5) & 0x1f]); + DPUTC(d, encodemap[(accl >> 0) & 0x1f]); + ctx->lnlen += 8; + if (ctx->maxline && ctx->lnlen >= ctx->maxline) { + dstr_puts(d, ctx->indent); + ctx->lnlen = 0; + } + qsz = 0; + accl = acch = 0; + } + } + + ctx->acch = acch; ctx->accl = accl; + ctx->qsz = qsz; + } else { + unsigned long accl = ctx->accl, acch = ctx->acch; + unsigned qsz = ctx->qsz; + + if (qsz) { + unsigned pad = 5 - qsz; + if (pad > 3) { + acch = accl << (pad * 8 - 32); + accl = 0; + } else { + acch = (acch << (8 * pad)) | ((accl & 0xffffffff) >> (32 - 8 * pad)); + accl = accl << (8 * pad); + } + qsz = 40; + pad *= 8; + while (qsz > pad) { + DPUTC(d, encodemap[(acch >> 3) & 0x1f]); + acch = (acch << 5) | ((accl >> 27) & 0x1f); + accl = (accl << 5); + qsz -= 5; + } + while (qsz) { + DPUTC(d, '='); + qsz -= 5; + } + ctx->lnlen += 8; + } + ctx->qsz = 0; + ctx->acch = ctx->accl = 0; + } +} + +/* --- @base32_decode@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to a context block + * @const void *p@ = pointer to a source buffer + * @size_t sz@ = size of the source buffer + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Decodes a binary string in base32. To flush out the final + * few characters (if necessary), pass a null source pointer. + */ + +void base32_decode(base32_ctx *ctx, + const void *p, size_t sz, + dstr *d) +{ + if (p) { + unsigned long accl = ctx->accl, acch = ctx->acch; + unsigned qsz = ctx->qsz; + const char *src = p; + int ch; + + while (sz) { + + /* --- Get the next character and convert it --- */ + + ch = *src++; + if (ch >= 128 || ch < 0) + ch = -1; + else + ch = decodemap[ch]; + sz--; + if (ch == -1) + continue; + + /* --- Bung it in the accumulator --- */ + + acch = (acch << 5) | ((accl >> 27) & 0x1f); + accl = (accl << 5) | ch; + qsz++; + + /* --- Maybe write out a completed triplet --- */ + + if (qsz == 8) { + DPUTC(d, (acch >> 0) & 0xff); + DPUTC(d, (accl >> 24) & 0xff); + DPUTC(d, (accl >> 16) & 0xff); + DPUTC(d, (accl >> 8) & 0xff); + DPUTC(d, (accl >> 0) & 0xff); + acch = accl = 0; + qsz = 0; + } + } + + ctx->acch = acch; ctx->accl = accl; + ctx->qsz = qsz; + } else { + + /* --- Notes about the tail-end bits --- * + * + * I'll use the queue size to work out how many tail-end bytes I ought to + * write. This isn't strictly right, but it's easier. + */ + + unsigned long acch = ctx->acch, accl = ctx->accl; + unsigned qsz = ctx->qsz; + + /* --- Now fiddle with everything else --- * + * + * There's a bodge here for invalid encodings which have a funny number + * of quintets in the final group. I'm not sure this is really worth + * having, but it might save some unexpected behaviour. (Not that you + * won't still get unexpected behaviour if the stream is completely + * empty, of course.) + */ + + if (qsz) { + unsigned pad = 8 - qsz; + if (pad > 6) { + acch = accl << (5 * pad - 32); + accl = 0; + } else { + acch = (acch << (5 * pad)) | ((accl & 0xffffffff) >> (32 - 5 * pad)); + accl = accl << (5 * pad); + } + + qsz *= 5; + while (qsz >= 8) { + DPUTC(d, acch & 0xff); + acch = accl >> 24; + accl <<= 8; + qsz -= 8; + } + } + + /* --- That seems to be good enough --- */ + + ctx->qsz = 0; + ctx->acch = ctx->accl = 0; + } +} + +/* --- @base32_init@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to context block to initialize + * + * Returns: --- + * + * Use: Initializes a base32 context properly. + */ + +void base32_init(base32_ctx *ctx) +{ + ctx->accl = ctx->acch = 0; + ctx->qsz = 0; + ctx->lnlen = 0; + ctx->indent = "\n"; + ctx->maxline = 72; +} + +/*----- Test driver code --------------------------------------------------*/ + +#ifdef TEST_RIG + +int main(int argc, char *argv[]) +{ + unsigned char buf[BUFSIZ]; + dstr d = DSTR_INIT; + base32_ctx ctx; + void (*proc)(base32_ctx *, const void *, size_t, dstr *); + size_t sz; + + base32_init(&ctx); + + if (argc > 1 && strcmp(argv[1], "-d") == 0) + proc = base32_decode; + else { + proc = base32_encode; + putchar('\t'); + ctx.indent = "\n\t"; + ctx.maxline = 32; + } + + do { + sz = fread(buf, 1, sizeof(buf), stdin); + if (sz) { + proc(&ctx, buf, sz, &d); + dstr_write(&d, stdout); + dstr_destroy(&d); + } + } while (sz == sizeof(buf)); + + proc(&ctx, 0, 0, &d); + dstr_write(&d, stdout); + + if (proc == base32_encode) + putchar('\n'); + + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/base32.h b/base32.h new file mode 100644 index 0000000..adebf90 --- /dev/null +++ b/base32.h @@ -0,0 +1,104 @@ +/* -*-c-*- + * + * $Id$ + * + * Base32 encoding and decoding + * + * (c) 1997 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef MLIB_BASE32_H +#define MLIB_BASE32_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include "dstr.h" + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct base32_ctx { + unsigned long accl, acch; /* Accumulator for output data */ + unsigned qsz; /* Length of data queued */ + unsigned lnlen; /* Length of the current line */ + const char *indent; /* Newline-and-indent string */ + unsigned maxline; /* Maximum permitted line length */ +} base32_ctx; + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @base32_encode@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to a context block + * @const void *p@ = pointer to a source buffer + * @size_t sz@ = size of the source buffer + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Encodes a binary string in base32. To flush out the final + * few characters (if necessary), pass a null source pointer. + */ + +extern void base32_encode(base32_ctx */*ctx*/, + const void */*p*/, size_t /*sz*/, + dstr */*d*/); + +/* --- @base32_decode@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to a context block + * @const void *p@ = pointer to a source buffer + * @size_t sz@ = size of the source buffer + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Decodes a binary string in base32. To flush out the final + * few characters (if necessary), pass a null source pointer. + */ + +extern void base32_decode(base32_ctx */*ctx*/, + const void */*p*/, size_t /*sz*/, + dstr */*d*/); + +/* --- @base32_init@ --- * + * + * Arguments: @base32_ctx *ctx@ = pointer to context block to initialize + * + * Returns: --- + * + * Use: Initializes a base32 context properly. + */ + +extern void base32_init(base32_ctx */*ctx*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/base32.in b/base32.in new file mode 100644 index 0000000..dba1e73 --- /dev/null +++ b/base32.in @@ -0,0 +1,21 @@ +Buffy: You're Watchers. Without a Slayer, you're pretty much just + watchin' Masterpiece Theater. You can't stop Glory. You can't do + anything with the information you have except maybe publish it in + the "Everyone Thinks We're Insane-O's Home Journal." So here's how + it's gonna work. You're gonna tell me everything you know. Then + you're gonna go away. You'll contact me if and when you have any + further information about Glory. The magic shop will remain open. + Mr. Giles will stay here as my official Watcher, reinstated at full + salary... +Giles: Retroactive. +Buffy: ...to be paid retroactively from the month he was fired. I + will continue my work with the help of my friends... +Buffy: We're talking about two very powerful witches and a + thousand-year-old ex-demon. +Anya: Willow's a demon?! +Philip: The boy? No power there. +Buffy: The boy has clocked more field time than all of you + combined. He's part of the unit. +Willow: That's Riley-speak. +Xander: I've clocked field time. + -- Checkpoint (Buffy the Vampire Slayer, season 5 episode 12) diff --git a/base32.ref b/base32.ref new file mode 100644 index 0000000..fbf760a --- /dev/null +++ b/base32.ref @@ -0,0 +1,54 @@ + IJ2WMZTZHIQFS33VE5ZGKICXMF2GG2DF + OJZS4ICXNF2GQ33VOQQGCICTNRQXSZLS + FQQHS33VE5ZGKIDQOJSXI5DZEBWXKY3I + EBVHK43UBIQCA53BORRWQ2LOE4QE2YLT + ORSXE4DJMVRWKICUNBSWC5DFOIXCAWLP + OUQGGYLOE52CA43UN5YCAR3MN5ZHSLRA + LFXXKIDDMFXCO5BAMRXQUIBAMFXHS5DI + NFXGOIDXNF2GQIDUNBSSA2LOMZXXE3LB + ORUW63RAPFXXKIDIMF3GKIDFPBRWK4DU + EBWWC6LCMUQHA5LCNRUXG2BANF2CA2LO + BIQCA5DIMUQCERLWMVZHS33OMUQFI2DJ + NZVXGICXMUTXEZJAJFXHGYLOMUWU6J3T + EBEG63LFEBFG65LSNZQWYLRCEBJW6IDI + MVZGKJ3TEBUG65YKEAQGS5BHOMQGO33O + NZQSA53POJVS4ICZN52SO4TFEBTW63TO + MEQHIZLMNQQG2ZJAMV3GK4TZORUGS3TH + EB4W65JANNXG65ZOEBKGQZLOBIQCA6LP + OUTXEZJAM5XW43TBEBTW6IDBO5QXSLRA + LFXXKJ3MNQQGG33OORQWG5BANVSSA2LG + EBQW4ZBAO5UGK3RAPFXXKIDIMF3GKIDB + NZ4QUIBAMZ2XE5DIMVZCA2LOMZXXE3LB + ORUW63RAMFRG65LUEBDWY33SPEXCAVDI + MUQG2YLHNFRSA43IN5YCA53JNRWCA4TF + NVQWS3RAN5YGK3ROBIQCATLSFYQEO2LM + MVZSA53JNRWCA43UMF4SA2DFOJSSAYLT + EBWXSIDPMZTGSY3JMFWCAV3BORRWQZLS + FQQHEZLJNZZXIYLUMVSCAYLUEBTHK3DM + BIQCA43BNRQXE6JOFYXAUR3JNRSXGORA + KJSXI4TPMFRXI2LWMUXAUQTVMZTHSORA + FYXC45DPEBRGKIDQMFUWIIDSMV2HE33B + MN2GS5TFNR4SAZTSN5WSA5DIMUQG233O + ORUCA2DFEB3WC4ZAMZUXEZLEFYQESCRA + EB3WS3DMEBRW63TUNFXHKZJANV4SA53P + OJVSA53JORUCA5DIMUQGQZLMOAQG6ZRA + NV4SAZTSNFSW4ZDTFYXC4CSCOVTGM6J2 + EBLWKJ3SMUQHIYLMNNUW4ZZAMFRG65LU + EB2HO3ZAOZSXE6JAOBXXOZLSMZ2WYIDX + NF2GG2DFOMQGC3TEEBQQUIBAORUG65LT + MFXGILLZMVQXELLPNRSCAZLYFVSGK3LP + NYXAUQLOPFQTUICXNFWGY33XE5ZSAYJA + MRSW233OH4QQUUDINFWGS4B2EBKGQZJA + MJXXSPZAJZXSA4DPO5SXEIDUNBSXEZJO + BJBHKZTGPE5CAVDIMUQGE33ZEBUGC4ZA + MNWG6Y3LMVSCA3LPOJSSAZTJMVWGIIDU + NFWWKIDUNBQW4IDBNRWCA33GEB4W65IK + EAQGG33NMJUW4ZLEFYQEQZJHOMQHAYLS + OQQG6ZRAORUGKIDVNZUXILQKK5UWY3DP + O45CAVDIMF2CO4ZAKJUWYZLZFVZXAZLB + NMXAUWDBNZSGK4R2EBESO5TFEBRWY33D + NNSWIIDGNFSWYZBAORUW2ZJOBIQCAIBA + EAQCAIBNFUQEG2DFMNVXA33JNZ2CAKCC + OVTGM6JAORUGKICWMFWXA2LSMUQFG3DB + PFSXELBAONSWC43PNYQDKIDFOBUXG33E + MUQDCMRJBI====== diff --git a/man/Makefile.am b/man/Makefile.am index b0e2719..4efc15f 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,6 @@ ## -*-makefile-*- ## -## $Id: Makefile.am,v 1.9 2004/04/08 01:36:13 mdw Exp $ +## $Id$ ## ## Makefile for mLib's manual pages ## @@ -36,11 +36,12 @@ MANPAGES = \ crc-mktab.1 unihash-mkstatic.1 MANPAGESEXT = \ - alloc.3 arena.3 assoc.3 atom.3 base64.3 bits.3 bres.3 conn.3 \ - crc32.3 darray.3 dspool.3 dstr.3 env.3 exc.3 fdflags.3 fwatch.3 \ - hash.3 ident.3 lbuf.3 lock.3 mLib.3 mdwopt.3 pkbuf.3 pool.3 \ - quis.3 report.3 sel.3 selbuf.3 selpk.3 sig.3 str.3 sub.3 sym.3 \ - testrig.3 trace.3 tv.3 url.3 hex.3 fdpass.3 macros.3 unihash.3 + alloc.3 arena.3 assoc.3 atom.3 base32.3 base64.3 bits.3 bres.3 \ + conn.3 crc32.3 darray.3 dspool.3 dstr.3 env.3 exc.3 fdflags.3 \ + fwatch.3 hash.3 ident.3 lbuf.3 lock.3 mLib.3 mdwopt.3 pkbuf.3 \ + pool.3 quis.3 report.3 sel.3 selbuf.3 selpk.3 sig.3 str.3 sub.3 \ + sym.3 testrig.3 trace.3 tv.3 url.3 hex.3 fdpass.3 macros.3 \ + unihash.3 install-man: $(MANPAGES) @$(NORMAL_INSTALL) diff --git a/man/base32.3 b/man/base32.3 new file mode 100644 index 0000000..3efab74 --- /dev/null +++ b/man/base32.3 @@ -0,0 +1,95 @@ +.\" -*-nroff-*- +.TH base32 3 "28 September 2004" "Straylight/Edgeware" "mLib utilities library" +.SH NAME +base32 \- conversion to and from base32 encoding +.\" @base32_encode +.\" @base32_decode +.\" @base32_init +.SH SYNOPSIS +.nf +.B "#include " + +.BI "void base32_encode(base32_ctx *" ctx , +.BI " const void *" p ", size_t " sz , +.BI " dstr *" d ); +.BI "void base32_decode(base32_ctx *" ctx , +.BI " const void *" p ", size_t " sz , +.BI " dstr *" d ); +.BI "void base32_init(base32_ctx *" ctx ); +.fi +.SH DESCRIPTION +The +.B base32 +functions perform base32 encoding and decoding of arbitrary binary +strings. The base32 encoding is defined by RFC2938. +.PP +Before encoding or decoding a string, a +.I context +(of type +.BR base32_ctx ) +must be initialized, by passing it to +.BR base32_init . +The context contains data which must be retained between calls to encode +or decode substrings. The +.B base32_init +function sets up initial values for the data, and sets up defaults for +the output formatting settings (see below). +.PP +Encoding of a string is performed by the +.B base32_encode +function. It is passed a pointer to a context block +.IR ctx , +the input substring to encode passed by address +.I p +and length +.IR sz , +and a pointer to a dynamic string +.I d +in which to write its output (see +.BR dstr (3) +for details on dynamic strings). Once all the input data has been +passed through +.B base32_encode +it is necessary to flush the final few bytes of output. This is +achieved by passing +.B base32_encode +a null pointer as its source argument. It is an error to attempt to +continue encoding after flushing output. +.PP +The output of the +.B base32_encode +function is formatted into lines using values from the context +structure. The +.B indent +member is a pointer to a null-terminated string which is used to +separate the output lines. The default indent string contains only a +newline character. The +.B maxline +member gives the maximum length of line that +.B base32_encode +is allowed to produce. If this is not a multiple of 4, it is rounded +up to the next highest multiple of four before use. A value of zero +instructs +.B base32_encode +not to perform line splitting: the output will be a single (possibly +very long) output line. The default maximum line length is 72 +characters. You may set these parameters by direct assignment to the +context structure once it has been initialized. +.PP +Decoding is performed similarly by the +.B base32_decode +function. The comments above about flushing output apply equally to +decoding. +.PP +Decoding ignores all whitespace characters in the encoded string. It +also ignores +.RB ` = ' +characters in the string and works out the final block length +automatically based on the input size. +.SH "SEE ALSO" +.BR base64 (3), +.BR dstr (3), +.BR hex (3), +.BR mLib (3). +.SH AUTHOR +Mark Wooding, diff --git a/man/base64.3 b/man/base64.3 index 3d445b7..4ab320a 100644 --- a/man/base64.3 +++ b/man/base64.3 @@ -87,7 +87,9 @@ also ignores characters in the string and works out the final block length automatically based on the input size. .SH "SEE ALSO" +.BR base32 (3), .BR dstr (3), +.BR hex (3), .BR mLib (3). .SH AUTHOR Mark Wooding, diff --git a/man/hex.3 b/man/hex.3 index b2cee51..d4c4680 100644 --- a/man/hex.3 +++ b/man/hex.3 @@ -83,6 +83,7 @@ decoding. .PP Decoding ignores all whitespace characters in the encoded string. .SH "SEE ALSO" +.BR base34 (3), .BR base64 (3), .BR dstr (3), .BR mLib (3). diff --git a/sym-gtest b/sym-gtest index b3db964..3dd6ed6 100755 --- a/sym-gtest +++ b/sym-gtest @@ -15,7 +15,9 @@ sub random ($) { return int(rand($lim)); } -open(DICT, "/usr/dict/words") or die("open(/usr/dict/words): $!"); +$words = "/usr/dict/words"; +-r $words or $words = "/usr/share/dict/words"; +open(DICT, $words) or die("open($words): $!"); @w = ; chomp(@w); close(DICT); -- [mdw]