Add base32 encoding and decoding.
authormdw <mdw>
Tue, 28 Sep 2004 14:11:09 +0000 (14:11 +0000)
committermdw <mdw>
Tue, 28 Sep 2004 14:11:09 +0000 (14:11 +0000)
Makefile.am
base32.c [new file with mode: 0644]
base32.h [new file with mode: 0644]
base32.in [new file with mode: 0644]
base32.ref [new file with mode: 0644]
man/Makefile.am
man/base32.3 [new file with mode: 0644]
man/base64.3
man/hex.3
sym-gtest

index db7de36..b727d9e 100644 (file)
@@ -1,6 +1,6 @@
 ## -*-Makefile-*-
 ##
 ## -*-Makefile-*-
 ##
-## $Id: Makefile.am,v 1.46 2004/04/08 01:36:11 mdw Exp $
+## $Id$
 ##
 ## Building the distribution
 ##
 ##
 ## 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 \
        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 ---
 
 
 ## --- 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 \
        @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@
 
 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 \
 
 check: \
        da.test sym.test assoc.test bits.test base64.test hex.test \
+       base32.test \
        unihash.test
 
 da_t_SOURCES = da-test.c
        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."
 
        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
 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 \
        *.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 \
 
 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 ---
 ##
 
 ## --- Background resolver ---
 ##
diff --git a/base32.c b/base32.c
new file mode 100644 (file)
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 <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 -------------------------------------------------*/
diff --git a/base32.h b/base32.h
new file mode 100644 (file)
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 (file)
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 (file)
index 0000000..fbf760a
--- /dev/null
@@ -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======
index b0e2719..4efc15f 100644 (file)
@@ -1,6 +1,6 @@
 ## -*-makefile-*-
 ##
 ## -*-makefile-*-
 ##
-## $Id: Makefile.am,v 1.9 2004/04/08 01:36:13 mdw Exp $
+## $Id$
 ##
 ## Makefile for mLib's manual pages
 ##
 ##
 ## Makefile for mLib's manual pages
 ##
@@ -36,11 +36,12 @@ MANPAGES = \
        crc-mktab.1 unihash-mkstatic.1
 
 MANPAGESEXT = \
        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)
 
 install-man: $(MANPAGES)
        @$(NORMAL_INSTALL)
diff --git a/man/base32.3 b/man/base32.3
new file mode 100644 (file)
index 0000000..3efab74
--- /dev/null
@@ -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 <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>
index 3d445b7..4ab320a 100644 (file)
@@ -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"
 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 dstr (3),
+.BR hex (3),
 .BR mLib (3).
 .SH AUTHOR
 Mark Wooding, <mdw@nsict.org>
 .BR mLib (3).
 .SH AUTHOR
 Mark Wooding, <mdw@nsict.org>
index b2cee51..d4c4680 100644 (file)
--- 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"
 .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).
 .BR base64 (3),
 .BR dstr (3),
 .BR mLib (3).
index b3db964..3dd6ed6 100755 (executable)
--- a/sym-gtest
+++ b/sym-gtest
@@ -15,7 +15,9 @@ sub random ($) {
   return int(rand($lim));
 }
 
   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);
 @w = <DICT>;
 chomp(@w);
 close(DICT);