The standard Base64 is not suitable for transmission directly to the URL. Because the URL encoder will change the "/" and "+" characters in the standard Base64 to form "%xx", these "%" numbers will need to be converted when they are stored in the database, because the ANSI SQL has "%" Number is used as a wildcard character.
to solve this problem, you can use an improved BASE64 encoding for URLs, it fills the ' = ' number at the end and changes the "+" and "/" in the standard Base64 to "-" and "_", eliminating the conversion to be made in the URL codec and database storage. It avoids the increase of the length of encoded information in this process, and unifies the format of object identifiers such as databases, forms, and so on.
There is also an improved BASE64 variant for regular expressions, which changes "+" and "/" to "!" and "-", because "+", "*", and "[" and "]" previously used in IRCU may have special meanings in regular expressions.
In addition, there are variants that change "+/" to "-" or "." (used as the identifier name in the programming language) or ".-" (for NmToken in XML) or even "_:" (for name in XML).
BASE64 requires converting every three 8Bit bytes to four 6Bit bytes (3*8 = 4*6 = 24), and then adding 6Bit two-bit high 0 to form four 8Bit bytes, that is, the converted string is theoretically going to be 1/3 longer than the original.
Rules about this encoding:
①. Turn 3 characters into 4 characters.
② alphanumeric a newline character every 76 characters.
③. The final terminator also have to be dealt with.
Example (1)
Convert before 11111111, 11111111, 11111111 (binary)
After conversion 00111111, 00111111, 00111111, 00111111 (binary)
The three bytes above are original, the following four bytes are converted Base64 encodings, and the first two digits are 0.
After the conversion, we use a code table to get the string we want (that is, the final Base64 encoding), and this table is this: (Excerpt from RFC2045) conversion table
Index |
corresponding character |
Index |
corresponding character |
Index |
corresponding character |
Index |
corresponding character |
0 |
A |
17 |
R |
34 |
I |
51 |
Z |
1 |
B |
18 |
S |
35 |
J |
52 |
0 |
2 |
C |
19 |
T |
36 |
K |
53 |
1 |
3 |
D |
20 |
U |
37 |
L |
54 |
2 |
4 |
E |
21st |
V |
38 |
M |
55 |
3 |
5 |
F |
22 |
W |
39 |
N |
56 |
4 |
6 |
G |
23 |
X |
40 |
O |
57 |
5 |
7 |
H |
24 |
Y |
41 |
P |
58 |
6 |
8 |
I |
25 |
Z |
42 |
Q |
59 |
7 |
9 |
J |
26 |
A |
43 |
R |
60 |
8 |
10 |
K |
27 |
B |
44 |
S |
61 |
9 |
11 |
L |
28 |
C |
45 |
T |
62 |
+ |
12 |
M |
29 |
D |
46 |
U |
63 |
/ |
13 |
N |
30 |
E |
47 |
V |
|
|
14 |
O |
31 |
F |
48 |
W |
|
|
15 |
P |
32 |
G |
49 |
X |
|
|
16 |
Q |
33 |
H |
50 |
Y |
|
|
Self-completion algorithm implementation///<summary>///Base64 encryption///</summary>///<param name= "M
Essage "></param>///<returns></returns> public string Base64code (String message) {char[] Base64code = {' 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 ', ' + ', '/', ' = '};
byte empty = 0;
var bytemessage = new ArrayList (Encoding.Default.GetBytes (message));
StringBuilder Outmessage;
int messagelen = Bytemessage.count;
Divide the characters into groups of 3 bytes, or, if not enough, a 0-padded int page = MESSAGELEN/3;
int use = 0; if (use = messagelen%3) > 0} {for (int i = 0; i < 3-use; i++)
Bytemessage.add (empty);
page++; ///converts 3 bytes of each set of characters into 4 byte sets. A group of 3, a group of 4 bytes a group//method is converted to ASCII code, in order to arrange 24-bit data, and then the 24-bit data into 4 groups, that is, 6 bits per group.
Then fill a byte with two 0 in front of each group's top digit.
Outmessage = new StringBuilder (page*4);
for (int i = 0; i < page; i++) {//Take a group of 3-byte groups var instr = new Byte[3];
Instr[0] = (byte) bytemessage[i*3];
INSTR[1] = (byte) bytemessage[i*3 + 1];
INSTR[2] = (byte) bytemessage[i*3 + 2];
Six bits for a group, 0 becomes 4 bytes var outstr = new Int[4];
First output byte: Takes the first 6 bits of the input byte, and makes up 0 in the high position so that it becomes 8 bits (one byte) outstr[0] = instr[0] >> 2; Second output byte: the first 4 bits (total 6 digits) of the second input byte and the last 2 digits of the input byte, and 0 in the high position, making it 8 bit (one byte) outstr[1] = ((instr[0) & 0x03) << 4) ^ (Instr[1]>> 4); Third output byte: the first 2 bits (total 6 bits) of the second input byte and the third input byte, and 0 in the high position, making it 8 (one byte) if (!instr[1].
Equals (empty)) outstr[2] = ((instr[1] & 0x0f) << 2 ^ (instr[2) >> 6);
else outstr[2] = 64; The fourth output byte: The last 6 digits of the third input byte, and 0 in the high position, so that it becomes 8 bits (one byte) if (!instr[2).
Equals (empty)) outstr[3] = (instr[2] & 0x3f);
else outstr[3] = 64; Outmessage.
Append (Base64code[outstr[0]]); Outmessage.
Append (Base64code[outstr[1]]); Outmessage.
Append (Base64code[outstr[2]]); Outmessage.
Append (Base64code[outstr[3]]); Return outmessage.
ToString (); ///<summary>///Base64 decryption///</summary>///<param name= "message" ></param>///<returns></returns> Public StrinG Base64decode (String message) {if ((message.length%4)!= 0) {throw new ArgumentException ("Not the correct BASE64 encoding, please check.")
"," message "); } if (! Regex.IsMatch (Message, "^[a-z0-9/+=]*$", Regexoptions.ignorecase)) {throw new Argumentexcepti On ("contains incorrect BASE64 encoding, please check.")
"," message ");
} string base64code = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/=";
int page = MESSAGE.LENGTH/4;
var outmessage = new ArrayList (page*3);
char[] message = Message.tochararray ();
for (int i = 0; i < page; i++) {var instr = new Byte[4];
Instr[0] = (byte) base64code.indexof (Message[i*4]);
INSTR[1] = (byte) base64code.indexof (Message[i*4 + 1]);
INSTR[2] = (byte) base64code.indexof (Message[i*4 + 2]); INSTR[3] = (byte) base64code.indexof (message[i*4 + 3]);
var outstr = new Byte[3];
Outstr[0] = (byte) ((Instr[0] << 2) ^ ((instr[1] & 0x30) >> 4)); if (Instr[2]!=) {outstr[1] = (byte) ((instr[1) << 4) ^ ((instr[2) & 0x3
c) >> 2));
else {outstr[2] = 0; } if (Instr[3]!=) {outstr[2] = (byte) ((instr[2) << 6) ^ in
STR[3]);
else {outstr[2] = 0;
} outmessage.add (Outstr[0]);
if (Outstr[1]!= 0) outmessage.add (outstr[1));
if (Outstr[2]!= 0) outmessage.add (outstr[2));
var outbyte = (byte[]) Outmessage.toarray (Type.GetType ("System.Byte")); Return Encoding.Default.GetSTring (Outbyte); }
/direct use. NET Library class function///<summary>///base64 encryption///</summary>///<param name= "message"
></param>///<returns></returns> public string Base64code (String message) {
byte[] bytes = Encoding.Default.GetBytes (message);
Return convert.tobase64string (bytes); ///<summary>///base64 decryption///</summary>///<param name= "message" ></p
aram>///<returns></returns> public string Base64decode (String message) {
byte[] bytes = convert.frombase64string (message);
Return Encoding.Default.GetString (bytes); }