Base64编码原理

标准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();
            }
        });

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值