首页 > 编程语言 >vc++ 使用base64 编码与解码

vc++ 使用base64 编码与解码

时间:2024-02-27 13:45:59浏览次数:20  
标签:++ text 解码 base64 c++ encode uint32 255

 

 

 

 

Base64原理

Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 2^6 = 64,所以每 6 个比特为一个单元,对应某个可打印字符。3 个字节有 24 个比特,对应于 4 个 Base64 单元,即 3 个字节可由 4 个可打印字符来表示。它可用来作为电子邮件的传输编码。在 Base64 中的可打印字符包括字母 A-Za-z、数字 0-9 和 +/

Base64 常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及XML的一些复杂数据。

Base64 的索引表如下:

 示例:将 Man 编码得到 TWFu:

 如果要编码的字节数不能被 3 整除,最后会多出 1 个或 2 个字节,那么可以使用下面的方法进行处理:先使用 0 字节值在末尾补足,使其能够被 3 整除,然后再进行 Base64 的编码。在编码后的 Base64 文本后加上一个或两个 = 号,代表补足的字节数。也就是说,当最后剩余两个八位(待补足)字节(2 个 byte)时,最后一个 6 位的 Base64 字节块有四位是 0 值,最后附加上两个等号;如果最后剩余一个八位(待补足)字节( 1 个 byte)时,最后一个 6 位的 base 字节块有两位是 0 值,最后附加一个等号

 

 

 

 

 

 

Base64是常见的加密算法,代码实现了基于C++的对于base64的编码和解码。

其中注释掉的部分为编码部分,取消注释将解码部分注释掉即可实现编码,反之可以实现解码。

 

#include <stdio.h>
#include <string.h>
#include <assert.h>

typedef unsigned char uint8;
typedef unsigned long uint32;

static uint8 alphabet_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static uint8 reverse_map[] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255
};

uint32 base64_encode(const uint8 *text, uint32 text_len, uint8 *encode)
{
uint32 i, j;
for (i = 0, j = 0; i+3 <= text_len; i+=3)
{
encode[j++] = alphabet_map[text[i]>>2]; //取出第一个字符的前6位并找出对应的结果字符
encode[j++] = alphabet_map[((text[i]<<4)&0x30)|(text[i+1]>>4)]; //将第一个字符的后2位与第二个字符的前4位进行组合并找到对应的结果字符
encode[j++] = alphabet_map[((text[i+1]<<2)&0x3c)|(text[i+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符
encode[j++] = alphabet_map[text[i+2]&0x3f]; //取出第三个字符的后6位并找出结果字符
}

if (i < text_len)
{
uint32 tail = text_len - i;
if (tail == 1)
{
encode[j++] = alphabet_map[text[i]>>2];
encode[j++] = alphabet_map[(text[i]<<4)&0x30];
encode[j++] = '=';
encode[j++] = '=';
}
else //tail==2
{
encode[j++] = alphabet_map[text[i]>>2];
encode[j++] = alphabet_map[((text[i]<<4)&0x30)|(text[i+1]>>4)];
encode[j++] = alphabet_map[(text[i+1]<<2)&0x3c];
encode[j++] = '=';
}
}
return j;
}

uint32 base64_decode(const uint8 *code, uint32 code_len, uint8 *plain)
{
assert((code_len&0x03) == 0); //如果它的条件返回错误,则终止程序执行。4的倍数。

uint32 i, j = 0;
uint8 quad[4];
for (i = 0; i < code_len; i+=4)
{
for (uint32 k = 0; k < 4; k++)
{
quad[k] = reverse_map[code[i+k]];//分组,每组四个分别依次转换为base64表内的十进制数
}

assert(quad[0]<64 && quad[1]<64);

plain[j++] = (quad[0]<<2)|(quad[1]>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的前2位进行组合

if (quad[2] >= 64)
break;
else if (quad[3] >= 64)
{
plain[j++] = (quad[1]<<4)|(quad[2]>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应base64表的十进制数的前4位进行组合
break;
}
else
{
plain[j++] = (quad[1]<<4)|(quad[2]>>2);
plain[j++] = (quad[2]<<6)|quad[3];//取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合
}
}
return j;
}


/*int main(void)
{
char input[256];
while (true){
printf("Please input string: ");
scanf("%s", input);
uint8 *text = (uint8 *)input;
uint32 text_len = (uint32)strlen((char *)text);
uint8 buffer[1024], buffer2[4096];
uint32 size = base64_encode(text, text_len, buffer2);
buffer2[size] = 0;
printf("%s\n", buffer2);

size = base64_decode(buffer2, size, buffer);
buffer[size] = 0;
printf("%s\n", buffer);

}
return 0;
}*/
//编码
int main(void)
{
char input[256];
while (true){
printf("Please input what you want to decode: ");
scanf("%s", input);
uint8 *text = (uint8 *)input;
uint32 text_len = (uint32)strlen((char *)text);
uint8 buffer[1024],buffer2[4096];

uint32 size = base64_decode(text, text_len, buffer);
buffer[size] = 0;
printf("Decoded content: %s\n", buffer);
size = base64_encode(buffer, size, buffer2);
buffer2[size] = 0;
printf("Confirmation of the original content: %s\n", buffer2);
}
return 0;
}
//解码

 

参考:

https://www.cnblogs.com/Severus-Cavendish/p/11623240.html

标签:++,text,解码,base64,c++,encode,uint32,255
From: https://www.cnblogs.com/rebrobot/p/18036717

相关文章

  • Qt Virtual Keyboard C++集成与实现(QWidget)
    一.设置1.配置所需语言1).通过QtCreator配置打开Qt工程文件,点开左侧 Projects->Build->BuildSteps->qmake->Additionalarguments在 Additionalarguments 增加配置参数:CONFIG+="lang-ar_ARlang-da_DKlang-de_DElang-en_GBlang-es_ESlang-fa_FAlang-fi_FIlang-fr......
  • Qt Virtual Keyboard C++集成与实现(解决模态对话框键盘失效问题)
    一.Qt模态对话框先让我们来看看对话框的几种特性:1.Qt::NonModaThewindowisnotmodalanddoesnotblockinputtootherwindows.2.Qt::WindowModalThewindowismodaltoasinglewindowhierarchyandblocksinputtoitsparentwindow,allgrandparentwin......
  • c++引用和指针
    指针和引用当我们需要在程序中传递变量的地址时,可以使用指针或引用。它们都可以用来间接访问变量,但它们之间有一些重要的区别。指针是一个变量,它存储另一个变量的地址。通过指针,我们可以访问存储在该地址中的变量。指针可以被重新分配,可以指向不同的变量,也可以为NULL。指针使用*......
  • C++内存管理
    关于C++内存和分配的学习笔记C++内存和分配很容易出问题,为了编写高质量的CPP代码,我们必须了解幕后的工作原理。1.内存泄漏例如:voidleaky(){newint;//这里就是内存泄漏cout<<"我泄漏了一个int的内存!"<<endl;}自由存储区中的数据库无法被栈或者间接访问,这块内存被......
  • C++ 关键字
    C++关键字alignas和alignof用法alignasalignas指定了内存按照多少对齐。alignas(0)这种写法无效,编译器会无视你的这个代码structalignas(8)S{};//表示是8个字节的对齐方式structalignas(1)U{Ss;};//虽然里面有个S,但是依然指定了该结构体的内存对齐要求为1字......
  • C++库大全
    基础类1、DinkumwareC++Library参考站点:http://www.dinkumware.comP.J.Plauger编写的高品质的标准库。P.J.Plauger博士是Dr.Dobb's程序设计杰出奖的获得者。其编写的库长期被Microsoft采用,并且最近Borland也取得了其OEM的license,在其C/C++的产品中采用Dinkumware的库。2......
  • C++ 刷题必备
    目录语言必备语言必备在C++中刷Leetcode时,有一些常用的语言技巧和最佳实践可以帮助你更有效地解决问题。以下是一些建议:熟悉STL(StandardTemplateLibrary):使用vector,list,set,map等容器来存储和操作数据。使用algorithm库中的函数,如sort,binary_search,unique等。......
  • vue3+vite使用vue-pdf-embed或者pdf-vue3预览 PDF 文件(能躲避 XSS 攻击,需要 pdf 文件
    1.使用vue-pdf-embed1.npm安装所需插件[email protected]@0.1.62.封装组件(创建pdfPriview.index文件)<template><divclass="pdf-preview"> <vue-pdf-embed :source="state.source" v-for="pageinstate......
  • C++ GDAL用CreateCopy()新建栅格并修改波段的个数
      本文介绍基于C++语言GDAL库,为CreateCopy()函数创建的栅格图像添加更多波段的方法。  在C++语言的GDAL库中,我们可以基于CreateCopy()函数与Create()函数创建新的栅格图像文件。其中,CreateCopy()函数需要基于一个已有的栅格图像文件作为模板,将模板文件的各项属性信息(例如空间......
  • C++ auto与循环
    C++auto与循环C++auto的介绍typeid(p).name();可以输出auto的类型auto是C++11引入的一个关键字,用于自动类型推导。编译器会根据初始化表达式的类型来自动推导auto变量的类型。使用auto可以简化代码,减少重复书写类型名称的繁琐,并且当类型非常复杂或者难以书写时,auto......