Cover V05, I03
Article
Figure 1
Figure 2
Figure 3
Figure 4
Listing 1
Listing 2
Listing 3
Listing 4
Listing 5
Listing 6
Listing 7
Listing 8
Sidebar 1

mar96.tar


Listing 6: Authorization information

#include <stdio.h>

#define MAXVAL	255

static char six2pr[64] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'0','1','2','3','4','5','6','7','8','9','+','/'
};

static unsigned char pr2six[256];

static int encode (
unsigned char	*bufin,
unsigned int	nbytes,
char 		*bufcoded)
{
#define ENC(c) six2pr[c]

register char *outptr = bufcoded;
unsigned int i;

for (i=0; i<nbytes; i += 3) {
*(outptr++) = ENC(*bufin >> 2);            /* c1 */
*(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
*(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));/*c3*/
*(outptr++) = ENC(bufin[2] & 077);         /* c4 */

bufin += 3;
}

/* If nbytes was not a multiple of 3, then we have encoded too
* many characters.  Adjust appropriately.
*/
if(i == nbytes+1) {
/* There were only 2 bytes in that last group */
outptr[-1] = '=';
} else if(i == nbytes+2) {
/* There was only 1 byte in that last group */
outptr[-1] = '=';
outptr[-2] = '=';
}
*outptr = '\0';
return(outptr - bufcoded);
#undef ENC
}

static int decode (
char 		*bufcoded,
unsigned char 	*bufplain,
int		outbufsize)
{
/* single character decode */
#define DEC(c) pr2six[(int)c]
#define MAXVAL 63

static int first = 1;

int nbytesdecoded, j;
register char *bufin = bufcoded;
register unsigned char *bufout = bufplain;
register int nprbytes;

/* If this is the first call, initialize the mapping table.
* This code should work even on non-ASCII machines.
*/
if(first) {
first = 0;
for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;

for(j=0; j<64; j++) pr2six[(int)six2pr[j]] = (unsigned char) j;
}

/* Strip leading whitespace. */

while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;


/* Figure out how many characters are in the input buffer.
* If this would decode into more bytes than would fit into
* the output buffer, adjust the number of input bytes downwards.
*/
bufin = bufcoded;
while(pr2six[(int)*(bufin++)] <= MAXVAL);
nprbytes = bufin - bufcoded - 1;
nbytesdecoded = ((nprbytes+3)/4) * 3;
if(nbytesdecoded > outbufsize) {
nprbytes = (outbufsize*4)/3;
}

bufin = bufcoded;

while (nprbytes > 0) {
*(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
*(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
*(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
bufin += 4;
nprbytes -= 4;
}

if(nprbytes & 03) {
if(pr2six[(int)bufin[-2]] > MAXVAL) {
nbytesdecoded -= 2;
} else {
nbytesdecoded -= 1;
}
}

return(nbytesdecoded);
#undef DEC
#undef MAXVAL
}

main( int argc, char **argv )
{
char	bufin[256], bufout[256];
int	cnt;

if( argc <= 1 ) {
exit( 1 );
}

if( strcmp( *argv, "decode" ) == 0 ) {
while( --argc ) {
argv++;
cnt = decode( *argv, bufout, sizeof(bufout) );
bufout[cnt] = '\0';
printf( "%s\n", bufout );
}
}
else {
if( strcmp( *argv, "encode" ) == 0 ) {
while( --argc ) {
argv++;
cnt = decode( *argv, bufout, sizeof(bufout) );
bufout[cnt] = '\0';
printf( "%s\n", bufout );
}
}
}
}
/* End of File */