///
<summary>
///
Base64 Encode Decode Methods
///
</summary>
public
class
Base64 {
///
<summary>
///
Alphabet used for encoded string representation.
///
It should contain exactly 64 characters.
/// This can be changed to other text, but must be the same in encode/decode.
///
</summary>
public
static
string
Alphabet
=
"
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz[]
"
;
public
static
char
Pad
=
'
!
'
;
public
static
string
EncodeText(
string
text){
return
EncodeText(text,Encoding.UTF8);
}
public
static
string
DecodeText(
string
code){
return
DecodeText(code,Encoding.UTF8);
}
public
static
string
EncodeText(
string
text,Encoding encoding){
return
Encode(encoding.GetBytes(text));
}
public
static
string
DecodeText(
string
code,Encoding encoding){
return
encoding.GetString(Decode(code));
}
public
static
string
Encode(
byte
[] _data){
int
n
=
_data.Length;
if
(n
==
0
)
return
""
;
int
r
=
n
%
3
;
int
p
=
3
-
r;
if
(p
==
3
)p
=
0
;
int
k
=
n
+
p;
byte
[] data
=
new
byte
[k];
_data.CopyTo(data,
0
);
int
m
=
(k
/
3
)
*
4
;
int
[] code
=
new
int
[m];
/*
6 2 4 4 2 6
* data|###### ##|#### ####|## ######|
* code|######|## ####|#### ##|######|
*
* code[0]=data[0]>>2;
* code[1]=data[0]<<4&X | data[1]>>4; X = 0b00110000 = 48;
* code[2]=data[1]<<2&Y | data[2]>>6; Y = 0b00111100 = 60;
* code[3]=data[2]&Z; Z = 0b00111111 = 63;
*/
for
(
int
i
=
0
;i
<
k
/
3
;i
++
){
code[i
*
4
+
0
]
=
data[i
*
3
+
0
]
>>
2
;
code[i
*
4
+
1
]
=
data[i
*
3
+
0
]
<<
4
&
48
|
data[i
*
3
+
1
]
>>
4
;
code[i
*
4
+
2
]
=
data[i
*
3
+
1
]
<<
2
&
60
|
data[i
*
3
+
2
]
>>
6
;
code[i
*
4
+
3
]
=
data[i
*
3
+
2
]
&
63
;
}
StringBuilder codestring
=
new
StringBuilder(
new
string
(Pad,m));
for
(
int
i
=
0
;i
<
m
-
p;i
++
){
codestring[i]
=
Alphabet[code[i]];
}
return
codestring.ToString();
}
public
static
byte
[] Decode(
string
_code){
int
n
=
_code.Length;
byte
[] code
=
new
byte
[n];
for
(
int
i
=
0
;i
<
n;i
++
){
code[i]
=
LetterIndex(_code[i]);
}
int
p
=
_code.IndexOf(Pad);
if
(p
==-
1
){
p
=
0
;
}
else
{
p
=
n
-
p;
}
int
m
=
(n
/
4
)
*
3
;
byte
[] data
=
new
byte
[m];
/*
6 2 4 4 2 6
* data|###### ##|#### ####|## ######|
* code|######|## ####|#### ##|######|
*
* data[0]=code[0]<<2 | code[1]>>4;
* data[1]=code[1]<<4 | code[2]>>2;
* data[2]=code[2]<<6 | code[3];
*/
for
(
int
i
=
0
;i
<
n
/
4
;i
++
){
data[i
*
3
+
0
]
=
(
byte
)(code[i
*
4
+
0
]
<<
2
|
code[i
*
4
+
1
]
>>
4
);
data[i
*
3
+
1
]
=
(
byte
)(code[i
*
4
+
1
]
<<
4
|
code[i
*
4
+
2
]
>>
2
);
data[i
*
3
+
2
]
=
(
byte
)(code[i
*
4
+
2
]
<<
6
|
code[i
*
4
+
3
]);
}
byte
[] _data
=
new
byte
[m
-
p];
for
(
int
i
=
0
;i
<
_data.Length;i
++
){
_data[i]
=
data[i];
}
return
_data;
}
static
byte
LetterIndex(
char
letter){
int
index
=
Alphabet.IndexOf(letter);
if
(index
==
-
1
){
index
=
0
;
}
return
(
byte
)index;
}
}