1 /* $Id: encode.c 6119 2003-01-13 07:59:39Z rra $
3 ** Produce a seven-bit printable encoding of stdin on stdout.
4 ** From @(#)encode.c 1.3 5/15/85, distributed with B2.11 News.
6 ** The encoding uses characters from 0x20 (' ') through 0x7A ('z').
7 ** (That fits nicely into the UUCP 'f' protocol by Piet Beertema.) First,
8 ** expand three eight-bit charcters into four six-bit ones. Collect
9 ** until we have 13, and spread the last one over the first 12, so that
10 ** we have 12 6.5-bit characters. Since there are very few half-bit
11 ** machines, collect them into pairs, making six 13-bit characters. We
12 ** can do this as A * 91 + B where A and B are less then 91 after we add
13 ** 0x20 to make it printable.
15 ** And if you thought that was unclear, then we won't even get into the
16 ** terminating conditions!
24 ** These characters can't appear in normal output, so we use them to
25 ** mark that the data that follows is the terminator. The character
26 ** immediately following this pair is the length of the terminator (which
27 ** otherwise might be indeterminable)
29 #define ENDMARK1 ((90 * 91 + 90) / 91 + ' ')
30 #define ENDMARK2 ((90 * 91 + 90) % 91 + ' ')
32 static char Buffer[13];
37 dumpcode(char *p, int n)
51 for (; n > 0; n -= 2) {
54 if (last & (1 << (6 - 1)))
58 putchar((c / 91) + ' ');
59 putchar((c % 91) + ' ');
69 dumpcode(Buffer, Count);
74 encode(char *dest, int n)
81 b4[0] = (dest[0] >> 2) & 0x3F;
82 b4[1] = ((dest[0] & 0x03) << 4) | ((dest[1] >> 4) & 0x0F);
83 b4[2] = ((dest[1] & 0x0F) << 2) | ((dest[2] >> 6) & 0x03);
84 b4[3] = (char)(n == 3 ? dest[2] & 0x3F : n);
86 for (p = b4, i = Count, dest = &Buffer[i], j = 4; --j >= 0; i++) {
105 for (p = b3; (c = getchar()) != EOF; ) {
112 encode(b3, (int)(p - b3));