GNU Info

Info Node: (libc.info)Encode Binary Data

(libc.info)Encode Binary Data


Next: Argz and Envz Vectors Prev: Trivial Encryption Up: String and Array Utilities
Enter node , (file) or (file)node

Encode Binary Data
==================

   To store or transfer binary data in environments which only support
text one has to encode the binary data by mapping the input bytes to
characters in the range allowed for storing or transfering.  SVID
systems (and nowadays XPG compliant systems) provide minimal support for
this task.

 - Function: char * l64a (long int N)
     This function encodes a 32-bit input value using characters from
     the basic character set.  It returns a pointer to a 6 character
     buffer which contains an encoded version of N.  To encode a series
     of bytes the user must copy the returned string to a destination
     buffer.  It returns the empty string if N is zero, which is
     somewhat bizarre but mandated by the standard.
     *Warning:* Since a static buffer is used this function should not
     be used in multi-threaded programs.  There is no thread-safe
     alternative to this function in the C library.
     *Compatibility Note:* The XPG standard states that the return
     value of `l64a' is undefined if N is negative.  In the GNU
     implementation, `l64a' treats its argument as unsigned, so it will
     return a sensible encoding for any nonzero N; however, portable
     programs should not rely on this.

     To encode a large buffer `l64a' must be called in a loop, once for
     each 32-bit word of the buffer.  For example, one could do
     something like this:

          char *
          encode (const void *buf, size_t len)
          {
            /* We know in advance how long the buffer has to be. */
            unsigned char *in = (unsigned char *) buf;
            char *out = malloc (6 + ((len + 3) / 4) * 6 + 1);
            char *cp = out;
          
            /* Encode the length. */
            /* Using `htonl' is necessary so that the data can be
               decoded even on machines with different byte order. */
          
            cp = mempcpy (cp, l64a (htonl (len)), 6);
          
            while (len > 3)
              {
                unsigned long int n = *in++;
                n = (n << 8) | *in++;
                n = (n << 8) | *in++;
                n = (n << 8) | *in++;
                len -= 4;
                if (n)
                  cp = mempcpy (cp, l64a (htonl (n)), 6);
                else
                      /* `l64a' returns the empty string for n==0, so we 
                         must generate its encoding ("......") by hand. */
                  cp = stpcpy (cp, "......");
              }
            if (len > 0)
              {
                unsigned long int n = *in++;
                if (--len > 0)
                  {
                    n = (n << 8) | *in++;
                    if (--len > 0)
                      n = (n << 8) | *in;
                  }
                memcpy (cp, l64a (htonl (n)), 6);
                cp += 6;
              }
            *cp = '\0';
            return out;
          }

     It is strange that the library does not provide the complete
     functionality needed but so be it.


   To decode data produced with `l64a' the following function should be
used.

 - Function: long int a64l (const char *STRING)
     The parameter STRING should contain a string which was produced by
     a call to `l64a'.  The function processes at least 6 characters of
     this string, and decodes the characters it finds according to the
     table below.  It stops decoding when it finds a character not in
     the table, rather like `atoi'; if you have a buffer which has been
     broken into lines, you must be careful to skip over the
     end-of-line characters.

     The decoded number is returned as a `long int' value.

   The `l64a' and `a64l' functions use a base 64 encoding, in which
each character of an encoded string represents six bits of an input
word.  These symbols are used for the base 64 digits:

        0     1     2     3     4     5     6     7
0       `.'   `/'   `0'   `1'   `2'   `3'   `4'   `5'
8       `6'   `7'   `8'   `9'   `A'   `B'   `C'   `D'
16      `E'   `F'   `G'   `H'   `I'   `J'   `K'   `L'
24      `M'   `N'   `O'   `P'   `Q'   `R'   `S'   `T'
32      `U'   `V'   `W'   `X'   `Y'   `Z'   `a'   `b'
40      `c'   `d'   `e'   `f'   `g'   `h'   `i'   `j'
48      `k'   `l'   `m'   `n'   `o'   `p'   `q'   `r'
56      `s'   `t'   `u'   `v'   `w'   `x'   `y'   `z'

   This encoding scheme is not standard.  There are some other encoding
methods which are much more widely used (UU encoding, MIME encoding).
Generally, it is better to use one of these encodings.


automatically generated by info2www version 1.2.2.9