home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxendeco.zip / BASE64.C next >
C/C++ Source or Header  |  2001-07-13  |  8KB  |  208 lines

  1. /* +------------------------------------------------------------------------+
  2.    |  BASE64 encode/decode routines.     1996-09       Dave Lewis           |
  3.    +------------------------------------------------------------------------+ */
  4.  
  5. #pragma strings(readonly)
  6.  
  7. #include <stdlib.h>
  8.  
  9. /*-----------------------------------------------------------------------------
  10.  
  11.  
  12.    See RFC 1521 Section "5.2.  Base64 Content-Transfer-Encoding"
  13.  
  14.                             Table 1: The Base64 Alphabet
  15.  
  16.       Value Encoding  Value Encoding  Value Encoding  Value Encoding
  17.            0 A            17 R            34 i            51 z
  18.            1 B            18 S            35 j            52 0
  19.            2 C            19 T            36 k            53 1
  20.            3 D            20 U            37 l            54 2
  21.            4 E            21 V            38 m            55 3
  22.            5 F            22 W            39 n            56 4
  23.            6 G            23 X            40 o            57 5
  24.            7 H            24 Y            41 p            58 6
  25.            8 I            25 Z            42 q            59 7
  26.            9 J            26 a            43 r            60 8
  27.           10 K            27 b            44 s            61 9
  28.           11 L            28 c            45 t            62 +
  29.           12 M            29 d            46 u            63 /
  30.           13 N            30 e            47 v
  31.           14 O            31 f            48 w         (pad) =
  32.           15 P            32 g            49 x
  33.           16 Q            33 h            50 y
  34.  
  35. -----------------------------------------------------------------------------*/
  36.  
  37. static unsigned char Base64CharSet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  38.                                        "abcdefghijklmnopqrstuvwxyz"
  39.                                        "0123456789+/";
  40.  
  41. #define BASE64PAD '='
  42.  
  43.  
  44. static unsigned char Base64Bits[256] = /* Base64 characters 6 bit value */
  45. {
  46. // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  47.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 0
  48.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 1  A
  49.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,  // 2
  50.   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,  // 3  S
  51.   64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  // 4
  52.   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,  // 5  C
  53.   64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  // 6
  54.   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,  // 7  I
  55.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 8
  56.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 9  I
  57.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // A
  58.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // B
  59.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // C
  60.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // D
  61.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // E
  62.   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64   // F
  63.  
  64. // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  65. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 0
  66. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 1  E
  67. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 2
  68. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 3  B
  69. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 64, 64, 64, 64,  // 4
  70. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 5  C
  71. //62, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 6
  72. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // 7  D
  73. //64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,  // 8
  74. //64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,  // 9  I
  75. //64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64,  // A
  76. //64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  // B  C
  77. //64,  0,  1,  2,  3,  4,  5,  6,  7,  8, 64, 64, 64, 64, 64, 64,  // C
  78. //64,  9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,  // D
  79. //64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,  // E
  80. //52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64   // F
  81. };
  82.  
  83. /*-----------------------------------------------------------------------------
  84.  
  85.   Convert binary character array to Base64 character set
  86.  
  87.   length = size of the source buffer;
  88.  
  89.   target buffer must be of size ( ( length + 2 ) / 3 * 4 )
  90.  
  91.   returns length of target buffer
  92.  
  93.   --------------------------------------------------------------------------
  94.  
  95.        bits in work    chars in work     required shift
  96.       --------------  ---------------   ----------------
  97.              8               1                  2
  98.             10               1                  4
  99.             12               2                 6,0
  100.  
  101.   --------------------------------------------------------------------------
  102.  
  103. example encoding binariy structure:
  104.  
  105. unsigned char workarea[ ( sizeof( structure ) + 2 ) / 3 * 4 + 1 ];
  106.  
  107. workarea[ utBinToBase64( workarea, (unsigned char *)&structure, sizeof( structure ) ] = 0;
  108.  
  109. example decoding binariy structure:
  110.  
  111. utBase64ToBin( (unsigned char *)&structure, kvdata, strlen( kvdata ) );
  112.  
  113. -----------------------------------------------------------------------------*/
  114.  
  115. int utBinToBase64 ( unsigned char *target, unsigned char *source, int length )
  116. {
  117.   int work = 0;
  118.   int mask = 0;
  119.   int retlen = ( length + 2 ) / 3 * 4;
  120.  
  121.   while ( length-- )
  122.   {
  123.     work <<= 8;
  124.     work  |= *source++;
  125.  
  126.     mask += 2;
  127.  
  128.     *target++ = Base64CharSet[ ( work >> mask ) & 0x3F ];
  129.  
  130.     if ( mask == 6 )
  131.     {
  132.       *target++ = Base64CharSet[ work & 0x3F ];
  133.       mask = 0;
  134.     }
  135.   }
  136.  
  137.   if ( mask )
  138.   {
  139.     if ( mask == 2 )
  140.     {
  141.       *target++ = Base64CharSet[ ( work << 4 ) & 0x3F ];
  142.       *target++ = BASE64PAD;
  143.     }
  144.     else
  145.       *target++ = Base64CharSet[ ( work << 2 ) & 0x3F ];
  146.  
  147.     *target++ = BASE64PAD;
  148.   }
  149.  
  150.  
  151.   return ( retlen );
  152. }
  153.  
  154.  
  155. /*-----------------------------------------------------------------------------
  156.  
  157.   Convert Base64 character array to binary
  158.  
  159.   length = size of the source buffer;
  160.  
  161.   target buffer must be at least of size ( length / 4 * 3 )
  162.  
  163.   returns length of target buffer
  164.  
  165.   --------------------------------------------------------------------------
  166.  
  167.        bits in work    chars in work     required shift    :    mask
  168.       --------------  ---------------   ----------------     ===========
  169.              6               0                 n/a         :     0
  170.             12               1                  4          :     6
  171.             10               1                  2          :     4
  172.              8               1                  0          :     2
  173.  
  174. -----------------------------------------------------------------------------*/
  175.  
  176. int utBase64ToBin ( unsigned char *target, unsigned char *source, int length )
  177. {
  178.   int work = 0;
  179.   int mask = 0;
  180.   int retlen = 0;
  181.  
  182.   while ( length-- )
  183.   {
  184.     if ( *source == BASE64PAD ) break;
  185.  
  186.     if ( Base64Bits[ *source ] < sizeof( Base64CharSet ) )
  187.     {
  188.       work <<= 6;
  189.       work  |= Base64Bits[ *source ];
  190.  
  191.       if ( mask )
  192.       {
  193.         mask -= 2;
  194.  
  195.         *target++ = ( work >> mask ) & 0xFF;
  196.  
  197.         retlen++;
  198.       }
  199.       else mask = 6;
  200.     }
  201.  
  202.     source++;
  203.   }
  204.  
  205.   return ( retlen );
  206. }
  207.  
  208.