1 /*!
2 \file  b64.c
3 \brief This file contains some simple 8bit-to-6bit encoding/deconding routines
4 
5 Most of these routines are outdated and should be converted using glibc's equivalent
6 routines.
7 
8 \date   Started 2/22/05
9 \author George
10 \version\verbatim $Id: b64.c 10711 2011-08-31 22:23:04Z karypis $ \endverbatim
11 
12 \verbatim
13 $Copyright$
14 $License$
15 \endverbatim
16 
17 */
18 
19 
20 #include "GKlib.h"
21 
22 #define B64OFFSET       48      /* This is the '0' number */
23 
24 
25 /******************************************************************************
26 * Encode 3 '8-bit' binary bytes as 4 '6-bit' characters
27 *******************************************************************************/
encodeblock(unsigned char * in,unsigned char * out)28 void encodeblock(unsigned char *in, unsigned char *out)
29 {
30   out[0] = (in[0] >> 2);
31   out[1] = (((in[0] & 0x03) << 4) | (in[1] >> 4));
32   out[2] = (((in[1] & 0x0f) << 2) | (in[2] >> 6));
33   out[3] = (in[2] & 0x3f);
34 
35   out[0] += B64OFFSET;
36   out[1] += B64OFFSET;
37   out[2] += B64OFFSET;
38   out[3] += B64OFFSET;
39 
40 //  printf("%c %c %c %c %2x %2x %2x %2x %2x %2x %2x\n", out[0], out[1], out[2], out[3], out[0], out[1], out[2], out[3], in[0], in[1], in[2]);
41 }
42 
43 /******************************************************************************
44 * Decode 4 '6-bit' characters into 3 '8-bit' binary bytes
45 *******************************************************************************/
decodeblock(unsigned char * in,unsigned char * out)46 void decodeblock(unsigned char *in, unsigned char *out)
47 {
48   in[0] -= B64OFFSET;
49   in[1] -= B64OFFSET;
50   in[2] -= B64OFFSET;
51   in[3] -= B64OFFSET;
52 
53   out[0] = (in[0] << 2 | in[1] >> 4);
54   out[1] = (in[1] << 4 | in[2] >> 2);
55   out[2] = (in[2] << 6 | in[3]);
56 }
57 
58 
59 /******************************************************************************
60 * This function encodes an input array of bytes into a base64 encoding. Memory
61 * for the output array is assumed to have been allocated by the calling program
62 * and be sufficiently large. The output string is NULL terminated.
63 *******************************************************************************/
GKEncodeBase64(int nbytes,unsigned char * inbuffer,unsigned char * outbuffer)64 void GKEncodeBase64(int nbytes, unsigned char *inbuffer, unsigned char *outbuffer)
65 {
66   int i, j;
67 
68   if (nbytes%3 != 0)
69     gk_errexit(SIGERR, "GKEncodeBase64: Input buffer size should be a multiple of 3! (%d)\n", nbytes);
70 
71   for (j=0, i=0; i<nbytes; i+=3, j+=4)
72     encodeblock(inbuffer+i, outbuffer+j);
73 
74 //printf("%d %d\n", nbytes, j);
75   outbuffer[j] = '\0';
76 }
77 
78 
79 
80 /******************************************************************************
81 * This function decodes an input array of base64 characters into their actual
82 * 8-bit codes. Memory * for the output array is assumed to have been allocated
83 * by the calling program and be sufficiently large. The padding is discarded.
84 *******************************************************************************/
GKDecodeBase64(int nbytes,unsigned char * inbuffer,unsigned char * outbuffer)85 void GKDecodeBase64(int nbytes, unsigned char *inbuffer, unsigned char *outbuffer)
86 {
87   int i, j;
88 
89   if (nbytes%4 != 0)
90     gk_errexit(SIGERR, "GKDecodeBase64: Input buffer size should be a multiple of 4! (%d)\n", nbytes);
91 
92   for (j=0, i=0; i<nbytes; i+=4, j+=3)
93     decodeblock(inbuffer+i, outbuffer+j);
94 }
95 
96