标准base64编码表
['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
编码原理
原数据长度是3的倍数
- 首先将原数据每三个字节分为一组,每个字节占8位,一组24位
- 将这24以每6位分为一组,共分成4组
- 每组中的值作为索引到base64编码表中寻找对应的字符
- 三个字节长度变成了四个字节长度
原数据的长度不是3的倍数
- 首先还是将原数据每三个字节为一组分组,最后一组不足三个字节
- 原数据只有一个字节长度的分为一个6位的和一个2位的两组
- 2位的那一组在后面补4个0
- 这样可以从base64编码表中找到两个字符,然后在后面补两个
=
- 一个字节长度变成了四个字节长度
- 原数据只有两个字节长度的分为两个6位和一个4位的三组
- 4位的那一组在后面补两个0
- 这样可以在base64编码表中找到三个字符,然后在后面补一个
=
- 两个字节长度变成了4个字节长度
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
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', '+', '/'};
char* base64_encode(char* plain){
char counts = 0;
char buffer[3];
char* cipher = malloc(strlen(plain)*4/3+4);
int i=0,c=0;
for(i=0;plain[i]!='\0';i++){
buffer[counts++]=plain[i];
if(counts==3){
cipher[c++]=base64_table[buffer[0]>>2];
cipher[c++]=base64_table[((buffer[0]&0x03)<<4)+(buffer[1]>>4)];
cipher[c++]=base64_table[((buffer[1]&0x0F)<<2)+(buffer[2]>>6)];
cipher[c++]=base64_table[(buffer[2]&0x3F)];
counts=0;
}
}
if(counts>0){
cipher[c++]=base64_table[buffer[0]>>2];
if(counts==1){
cipher[c++]=base64_table[(buffer[0]&0x03)<<4];
cipher[c++]='=';
}else{
cipher[c++]=base64_table[((buffer[0]&0x03)<<4)+(buffer[1]>>4)];
cipher[c++]=base64_table[((buffer[1]&0x0F)<<2)];
}
cipher[c++]='=';
}
cipher[c]='\0';
return cipher;
}
char* base64_decode(char* cipher){
char counts = 0;
char buffer[4];
char* plain = malloc(strlen(cipher)*3/4);
int i=0,p=0;
for(i=0;cipher[i]!='\0';i++){
char k;
for(k=0;k<64;k++){
if(cipher[i]==base64_table[k]){
break;
}
}
buffer[counts++]=k;
if(counts == 4) {
plain[p++] = (buffer[0] << 2) + (buffer[1] >> 4);
if(buffer[2] != 64)
plain[p++] = (buffer[1] << 4) + (buffer[2] >> 2);
if(buffer[3] != 64)
plain[p++] = (buffer[2] << 6) + buffer[3];
counts = 0;
}
}
plain[p] = '\0';
return plain;
}
int main(){
char ch[] ="A";
char* en = base64_encode(ch);
printf("%s\n",en);
char* de = base64_decode(en);
printf("%s\n",de);
return 0;
}
Python调用
import base64
data = "Bielton"
print("data:",data)
data_b64encode = base64.b64encode(data.encode())
print("b64编码:",data_b64encode.decode("utf-8"))
data_b64decode = base64.b64decode(data_b64encode)
print("b64解码",data_b64decode.decode("utf-8"))
>>>
data: Bielton
b64编码: QmllbHRvbg==
b64解码 Bielton
Java调用
String data = "Bielton";
Base64.Encoder encoder= Base64.getEncoder();
byte[] encoded = encoder.encode(data.getBytes());
String encodedToString = new String(encoded);
System.out.println(encodedToString); // QmllbHRvbg==
byte[] decoded = Base64.getDecoder().decode(encodedToString);
String decodedToString = new String(decoded);
System.out.println(decodedToString); // Bielton
Android Studio
Button B64_en = findViewById(R.id.b64encode);
B64_en.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "Bileton";
String data_encode = Base64.encodeToString(data.getBytes(), Base64.DEFAULT);
Toast.makeText(MainActivity.this,data_encode,Toast.LENGTH_SHORT).show();
}
});
Button B64_de = findViewById(R.id.b64decode);
B64_de.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "Bileton";
String data_encode = Base64.encodeToString(data.getBytes(), Base64.DEFAULT);
byte[] data_decode = Base64.decode(data_encode,Base64.DEFAULT);
String decodeString = new String(data_decode);
Toast.makeText(MainActivity.this,decodeString,Toast.LENGTH_SHORT).show();
}
});