## -*-Makefile-*-
##
-## $Id: Makefile.am,v 1.46 2004/04/08 01:36:11 mdw Exp $
+## $Id$
##
## Building the distribution
##
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 ---
@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@
check: \
da.test sym.test assoc.test bits.test base64.test hex.test \
+ base32.test \
unihash.test
da_t_SOURCES = da-test.c
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
*.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 ---
##
--- /dev/null
+/* -*-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 -------------------------------------------------*/
--- /dev/null
+/* -*-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
--- /dev/null
+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)
--- /dev/null
+ 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======
## -*-makefile-*-
##
-## $Id: Makefile.am,v 1.9 2004/04/08 01:36:13 mdw Exp $
+## $Id$
##
## Makefile for mLib's manual pages
##
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)
--- /dev/null
+.\" -*-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 <mLib/base32.h>"
+
+.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, <mdw@nsict.org>
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, <mdw@nsict.org>
.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).
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 = <DICT>;
chomp(@w);
close(DICT);