current version
[opsoft_test.git] / gclib2 / modules / Crypt / base64.cxx
blob7e679933f2f1e26a03d3611eab95b93e9d78728e
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
4 *
5 */
7 #include "StdHeaders.h"
8 #include "Macroses.h"
9 #include <gclib2.h>
12 /*! \file base64.c Кодирование/декодирование в/из Base64.
15 const static char base64ABC[] =
16 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
17 typedef unsigned char uchar_t;
19 #define S_(a) S[n * 3 + a]
20 #define S__(a,b) (S[n * 3 + a] & b)
21 #define S__l(a,b,c) ((S[n * 3 + a] & b) << c)
23 #define B1 buf[(n<<2)] = base64ABC[ (S_(0) >> 2) ];
24 #define B2 buf[(n<<2) + 1] = base64ABC [ (S__l(0,0x3,4)) | S_(1) >> 4 ];
25 #define B3 buf[(n<<2) + 2] = base64ABC [ S__l(1,0x0F,2) | S_(2) >> 6];
26 #define B4 buf[(n<<2) + 3] = base64ABC [ S__(2,0x3F) ];
28 /*! \brief Закодировать в Base64.
29 * \param S - исходный буфер.
30 * \param SIZE - размер исходного буфера.
32 __export uchar_t * base64_code (unsigned char * S, int SIZE)
34 uchar_t c, *buf;
35 int n;
37 c = (SIZE == 0) ? strlen ((const char *) S) % 3 : SIZE % 3;
38 SIZE = (SIZE == 0) ? strlen ((const char *) S) / 3 : SIZE / 3;
40 buf = (uchar_t *) malloc (SIZE * 4 + 5);
42 for (n = 0; n < SIZE; ++n) {
43 B1; B2; B3; B4;
46 switch (c) {
47 case 1:
48 B1; B2;
49 buf[(n<<2) + 2] = '=';
50 buf[(n<<2) + 3] = '=';
51 ++n;
52 break;
53 case 2:
54 B1; B2; B3;
55 buf[(n<<2) + 3] = '=';
56 ++n;
57 break;
59 buf[(n<<2)] = 0;
60 return buf;
63 #define BASE64(a) ((unsigned char) (strchr (base64ABC, S[(n<<2) + a]) - base64ABC))
65 /*! \brief Перекодировать из Base64.
66 * \param S - исходный буфер.
67 * \param SIZE - размер исходного буфера.
69 __export uchar_t * base64_decode (unsigned char * S, int SIZE)
71 unsigned char * ptr;
72 int n;
74 if (SIZE % 4)
75 return NULL;
77 SIZE = SIZE ? SIZE / 4 : strlen ((const char *) S) / 4;
78 ptr = (uchar_t *) malloc (SIZE * 4 + 5);
80 for (n = 0; n < SIZE; n++) {
81 ptr[n * 3] = (BASE64(0) << 2) | ( BASE64(1) >> 4);
82 if (S[(n<<2) + 2] != '=') {
83 ptr[n * 3 + 1] = ((BASE64(1) & 0x0F) << 4) | (BASE64(2) >> 2);
84 if (S[(n<<2) + 3] != '=')
85 ptr[n * 3 + 2] = ((BASE64(2) & 0x03) << 6) | BASE64(3);
86 else
87 ptr[n * 3 + 2] = 0;
88 } else
89 ptr[n * 3 +1] = 0;
92 ++n;
93 ptr [n * 3] = 0;
94 return ptr;