unsigned char* _stdcall Base64Encode(const char *str
,
int length)
{
//int length
=
strlen(str)
;
static char base64_table
[]
=
{
'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
'
,
'+'
,
'/'
,
'\
0
'
}
;
static char base64_pad
=
'
=
'
;
unsigned const char *current
=
(unsigned const char*)str
;
int i
=
0
;
unsigned char *result
=
(unsigned char *)malloc(((length +
3
- length %
3
) *
4
/
3
+
1
) * sizeof(char))
;
while (length >
2
) { /* keep going until we have less than
24
bits */
result
[
i++
]
=
base64_table
[
current[0
]
>>
2
]
;
result
[
i++
]
=
base64_table
[
((current[0
]
& 0x03) <<
4
) + (current
[
1
]
>>
4
)]
;
result
[
i++
]
=
base64_table
[
((current[1
]
& 0x0f) <<
2
) + (current
[
2
]
>>
6
)]
;
result
[
i++
]
=
base64_table
[
current[2
]
& 0x3f]
;
current +
=
3
;
length -
=
3
;
/* we just handle 3 octets of data */
}
/* now deal with the tail end of things */
if (length !
=
0
) {
result
[
i++
]
=
base64_table
[
current[0
]
>>
2
]
;
if (length >
1
) {
result
[
i++
]
=
base64_table
[
((current[0
]
& 0x03 ) <<
4
) + (current
[
1
]
>>
4
)]
;
result
[
i++
]
=
base64_table
[
(current[1
]
& 0x0f) <<
2
]
;
result[i++] = base64_pad;
}
else {
result
[
i++
]
=
base64_table
[
(current[0
]
& 0x03) <<
4
]
;
result
[
i++
]
=
base64_pad
;
result
[
i++
]
=
base64_pad
;
}
}
result
[
i
]
=
'\
0
'
;
// printf("%s\n",result);
return result
;
}
unsigned char* _stdcall Base64Decode(const unsigned char *str
,
int length
,
int *ret_length)
{
static char base64_table
[]
=
{
'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
'
,
'+'
,
'/'
,
'\
0
'
}
;
static char base64_pad
=
'
=
'
;
const unsigned char *current
=
str
;
int ch
,
i
=
0
,
j
=
0
,
k
;
/* this sucks for threaded environments */
static short reverse_table
[
256
]
;
static int table_built
;
unsigned char *result
;
if (++table_built
==
1
) {
char *chp
;
for(ch
=
0
;
ch < 256; ch++) {
chp
=
strchr(base64_table
,
ch)
;
if(chp) {
reverse_table
[
ch
]
=
chp - base64_table
;
} else {
reverse_table
[
ch
]
=
-
1
;
}
}
}
result
=
(unsigned char *)malloc(length +
1
)
;
if (result
==
NULL) {
return NULL
;
}
/* run through the whole string
,
converting as we go */
while ((ch
=
*current++) !
=
'\
0
') {
if (ch
==
base64_pad) break
;
/* When Base64 gets POSTed
,
all pluses are interpreted as spaces.
This line changes them back. It's not exactly the Base64 spec
,
but it is completely compatible with it (the spec says that
spaces are invalid). This will also save many people considerable
headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
*/
if (ch
==
' ') ch
=
'+'
;
ch
=
reverse_table
[
ch
]
;
if (ch <
0
) continue
;
switch(i %
4
) {
case
0
:
result
[
j
]
=
ch <<
2
;
break
;
case
1
:
result
[
j++
]
|
=
ch >>
4
;
result
[
j
]
=
(ch & 0x0f) <<
4
;
break
;
case
2
:
result
[
j++
]
|
=
ch >>
2
;
result
[
j
]
=
(ch & 0x03) <<
6
;
break
;
case
3
:
result
[
j++
]
|
=
ch
;
break
;
}
i++
;
}
k
=
j
;
/* mop things up if we ended on a boundary */
if (ch
==
base64_pad) {
switch(i %
4
) {
case
0
:
case
1
:
free(result)
;
return NULL
;
case
2
:
k++
;
case
3
:
result
[
k++
]
=
0
;
}
}
if(ret_length) {
*ret_length
=
j
;
}
result
[
k
]
=
'\
0
'
;
return result
;
}