1. base64 原理
- Base64 算法的原理,是将输入流中的字节按每 3 个分为一组,然后 每次取 6 个比特,将其转换成表格中对应的数据,一直重复到没有剩余的字符为止,转换表格如下:
- 上面就是Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符,这是标准的Base64协议规定。在日常使用中还会看到“=”或“==”号出现在Base64的编码结果中,“=”在此是作为填充字符出现。
- 示例说明
以下图的表格为示例,具体分析当字符
占
全
\color{gold}{占全}
占全时的过程。 当位数
不
足
\color{gold}{不足}
不足的时候。
2.base64实现
核心原理 1. 获取第一个字符8个 bit 的前6位,作为 base64编码的第一位; 2. 获取第一个字符8个 bit 的后2位和第二个字符8个 bit 的前4位,作为 base64 编码的第二位; 3. 获取第二个字符8个 bit 的后4位和第三个字符8个 bit 的前2位,作为 base64编码的第三位; 4. 获取第三个字符8个 bit 的后6位,作为 base64编码的第四位; 如此3个字符可编码 base64 为4个字符,当位数不够时补 0 来满足一个字符,且要实现编码后的位数为4的倍数,不足的用 “=” 代替。
方法一
利用 ASCII 码与 base64 码进行转换的方法
- base64是由
A
~
Z
,
a
~
z
,
1
~
9
,
+
,
/
\color{red} {A{\sim}Z , a{\sim}z ,1{\sim}9, + , / }
A~Z,a~z,1~9,+,/构成,其编码位
0
~
64
\color{red}{0{\sim}64}
0~64,通过对比
A
S
C
I
I
\color{red} { ASCII }
ASCII 码表可找到对应数字关系
1.编码
- 设传入字符为c,c语言中 char 字符以ASCII码存储,将其变为真正的ASCII码对应的字符即可。
a :当 ASCII 码小于 25(0~25) 时,return ( ‘A’ + c );26是对应的前26个 base (A~Z)码 b :当 ASCII 码在26到51(26~51)之间时,return ( ‘a’ + ( c - 26 ));此时是接下来的26个 base(a~z)码 c :当 ASCII 码在52到61(52~61)之间时,return ( ‘0’ + ( c - 52 ));此时是接下来的10个 base(0~9)码 d :当 ASCII 码为62(62)时,return ‘+’; e :当 ASCII 码为63(63)时,return ‘/’; f :当 ASCII 码大于63 (64~…)时, 此时c = c - c/64*64;循环以上步骤;
2.解码
- 编码传入字符m,base64 的字符,将其还原为真正的 ASCII 码即可。
a :当输入字符在A~Z间return ( m - ‘A’ ); b :当输入字符在a~z之间return ( 26 + m - ‘a’ ); c : 当输入的字符在0~9之间return ( 52 + m - ‘0’ ); d :当输入的字符为 “+”return 62; e :当输入字符为 “/”return 63;
if(*m>='A'&&*m<='Z')
{
*m-='A';
continue;
}
if(*m>='a'&&*m<='z')
{
*m-='a';
*m+=26;
continue;
}
if(*m=='+')
{
*m=62;
continue;
}
if(*m=='/')
{
*m=63;
continue;
}
if(*m=='=')
{
*m=0;
continue;
}
*m-='0';
*m+=52;
参考代码
方法二
直接对字符串进行转换
#pragma once
#ifndef BASE64_H_INCLUDED
#define BASE64_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include<windows.h>
#include <string.h>
char* base64_encode(char* binData, char* base64, int binLength);
char* base64_decode(char const* base64Str, char* debase64Str, int encodeStrLen);
void Menu();
void decode();
void encode();
#endif
#pragma warning(disable:4996)
#include"base64.h"
char base64char[] = {
'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'
};
char c;
void Menu()
{
printf("***************\n");
printf("*1、base64加密\n");
printf("*2、base64解密\n");
printf("*3、退出程序\n");
printf("***************\n");
}
void encode()
{
do
{
system("cls");
printf(" ---- base64_encode ----\n\n");
char soursedata[1024];
scanf("%s", &soursedata);
getchar();
char* result = (char*)malloc(sizeof(char) * 1024);
memset(result, 0, sizeof(char) * 1024);
printf("\t\t\n%s\n", base64_encode(soursedata, result, (int)strlen(soursedata)));
printf("\nWhether to continue:(Y/N)\n");
} while ((c = getch())!='N'&& c != 'n');
}
void decode()
{
do {
system("cls");
printf(" ---- base64_dncode ----\n\n");
char soursedata[1024];
scanf("%s", &soursedata);
getchar();
char* result = (char*)malloc(sizeof(char) * 1024);
memset(result, 0, sizeof(char) * 1024);
printf("\t\t\n%s\n",base64_decode((char const*)soursedata, result, (int)strlen(soursedata)));
printf("\nWhether to continue:(Y/N)\n");
} while ((c = getch()) != 'N' && c != 'n');
}
char* base64_encode(char* binData, char* base64, int binLength)
{
int i = 0;
int j = 0;
int current = 0;
for (i = 0; i < binLength; i += 3) {
current = (*(binData + i) >> 2) & 0x3F;
*(base64 + j++) = base64char[current];
current = (*(binData + i) << 4) & 0x30;
if (binLength <= (i + 1)) {
*(base64 + j++) = base64char[current];
*(base64 + j++) = '=';
*(base64 + j++) = '=';
break;
}
current |= (*(binData + i + 1) >> 4) & 0xf;
*(base64 + j++) = base64char[current];
current = (*(binData + i + 1) << 2) & 0x3c;
if (binLength <= (i + 2)) {
*(base64 + j++) = base64char[current];
*(base64 + j++) = '=';
break;
}
current |= (*(binData + i + 2) >> 6) & 0x03;
*(base64 + j++) = base64char[current];
current = *(binData + i + 2) & 0x3F;
*(base64 + j++) = base64char[current];
}
*(base64 + j) = '\0';
return base64;
}
char* base64_decode(char const* base64Str, char* debase64Str, int encodeStrLen)
{
int i = 0;
int j = 0;
int k = 0;
char temp[4] = "";
for (i = 0; i < encodeStrLen; i += 4) {
for (j = 0; j < 64; j++) {
if (*(base64Str + i) == base64char[j]) {
temp[0] = j;
}
}
for (j = 0; j < 64; j++) {
if (*(base64Str + i + 1) == base64char[j]) {
temp[1] = j;
}
}
for (j = 0; j < 64; j++) {
if (*(base64Str + i + 2) == base64char[j]) {
temp[2] = j;
}
}
for (j = 0; j < 64; j++) {
if (*(base64Str + i + 3) == base64char[j]) {
temp[3] = j;
}
}
*(debase64Str + k++) = ((temp[0] << 2) & 0xFC) | ((temp[1] >> 4) & 0x03);
if (*(base64Str + i + 2) == '=')
break;
*(debase64Str + k++) = ((temp[1] << 4) & 0xF0) | ((temp[2] >> 2) & 0x0F);
if (*(base64Str + i + 3) == '=')
break;
*(debase64Str + k++) = ((temp[2] << 6) & 0xF0) | (temp[3] & 0x3F);
}
return debase64Str;
}
#pragma warning(disable:4996)
#include"base64.h"
int main()
{
Menu();
char a;
scanf("%c", &a);
switch (a)
{
case '1':
encode();
break;
case '2':
decode();
break;
case '3':
exit(0);
}
return 0;
}
|