目录

前言

附上代码

编码表

首先来简述一下base64的基本原理:

与base64进行异或运算

运行结果展示和小结



前言

本次代码基于本周的二进制作业,我们需要使用c或c++语言来实现以下要求

输入一个字符串,检查该字符串总ascii码值。如果值大于1000则对该字符串进行base64加密输出,否则与base64加密表进行异或输出。

大概就是三步
1.判断输入字符串的总值是否大于1000
2.如果大于1000的话我们将它使用base64加密输出
3.如果小于1000就和base64字符串进行异或输出(这里说到的和base64异或的意思就是假如我们输入了tnnd四个字符,那我们就需要和base64的前四个字符也就是ABCD本别异或再得到一个新的字符串。)


附上代码

我使用的是c语言

#include<stdio.h>
#include<string.h>void base64jiami(char a, char b, char c);
char a[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char str[100];//待带输入的字符串
char s[100];//待输出的字符串
int i, j;int main()
{   printf("请输入字符串:");gets_s(str);int len = strlen(str);//输入字符串的长度int sum=0;int num;//得到ascii总值for (i = 0; i < len; i++){int num = str[i];sum = sum + num;}printf("您输入的字符串是:");puts(str);printf("您输入的字符串的ascii的总值为:");printf("%d", sum);printf("\n");
//对ascii的总值进行比较判断if(sum > 1000){printf("您输入的字符串的ascii总值大于1000,需要base64加密");printf("\n");for (i = 0, j = 0; i <= len - 3; i += 3, j += 4) {base64jiami(str[i], str[i + 1], str[i + 2]);}//但字符串的长度无法被3整除时if (len % 3 == 1){s[j] = a[str[len - 1] >> 2];s[j + 1] = a[str[len - 1]<< 4 & 0x3f];s[j + 2] = '=';s[j + 3] = '=';}if (len % 3 == 2) {s[j] = a[str[len - 2] >> 2];s[j+1] = a[(str[len - 2] << 4 | str[len - 1] >> 4) & 0x3f];s[j + 2] = a[(str[len - 1] << 2) & 0x3f];s[j + 3] = '=';}printf("base64加密之后为:");puts(s);printf("\n");}else {for (i = 0; i < len; i++) {s[i] = str[i] ^ a[i];}printf("由于您输入的字符串ascii总值小于1000,所以需要和base64进行异或输出\n");printf("加密后的字符串是:");puts(s);}}
void base64jiami(char x, char y, char z) {s[j] = a[x >> 2];s[j + 1] = a[(x << 4 | y >> 4) & 0x3f];s[j + 2] = a[(y << 2 | z >> 6) & 0x3f];s[j + 3] = a[z & 0x3f];
}

数值准备

void base64jiami(char a, char b, char c);
char a[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char str[100];//待带输入的字符串
char s[100];//待输出的字符串
int i, j;

main主函数(用于判断ascii总值和加密输出)

int main()
{   printf("请输入字符串:");gets_s(str);int len = strlen(str);//输入字符串的长度int sum=0;int num;//得到ascii总值for (i = 0; i < len; i++){int num = str[i];sum = sum + num;}printf("您输入的字符串是:");puts(str);printf("您输入的字符串的ascii的总值为:");printf("%d", sum);printf("\n");
//对ascii的总值进行比较判断if(sum > 1000){printf("您输入的字符串的ascii总值大于1000,需要base64加密");printf("\n");for (i = 0, j = 0; i <= len - 3; i += 3, j += 4) {base64jiami(str[i], str[i + 1], str[i + 2]);}//但字符串的长度无法被3整除时if (len % 3 == 1){s[j] = a[str[len - 1] >> 2];s[j + 1] = a[str[len - 1]<< 4 & 0x3f];s[j + 2] = '=';s[j + 3] = '=';}if (len % 3 == 2) {s[j] = a[str[len - 2] >> 2];s[j+1] = a[(str[len - 2] << 4 | str[len - 1] >> 4) & 0x3f];s[j + 2] = a[(str[len - 1] << 2) & 0x3f];s[j + 3] = '=';}printf("base64加密之后为:");puts(s);printf("\n");}else {for (i = 0; i < len; i++) {s[i] = str[i] ^ a[i];}printf("由于您输入的字符串ascii总值小于1000,所以需要和base64进行异或输出\n");printf("加密后的字符串是:");puts(s);}}

base64加密函数

void base64jiami(char x, char y, char z) {s[j] = a[x >> 2];s[j + 1] = a[(x << 4 | y >> 4) & 0x3f];s[j + 2] = a[(y << 2 | z >> 6) & 0x3f];s[j + 3] = a[z & 0x3f];
}

编码表

下图是base64的编码表

这个代码中有些难度的就是要实现base64的移位运算。


首先来简述一下base64的基本原理:

在这里附上base64原理超详细讲解链接:point one time

例1,当我们输入的字符串刚好可以被3整除时:
在这里我输入了Man这三个字符-------将这三个字符的ASCII值转为二进制共24个字节-------6个字节为一组再转为十进制,然后在base64编码表中找到对应的字符
也就是一个简单的分割,原理我们知道了那我们怎么通过代码来实现呢?

void base64jiami(char x, char y, char z) {s[j] = a[x >> 2];s[j + 1] = a[(x << 4 | y >> 4) & 0x3f];s[j + 2] = a[(y << 2 | z >> 6) & 0x3f];s[j + 3] = a[z & 0x3f];
}

在我写的这串代码中我们使用x,y,z来代表我们输入的字符
使用for循环来3个3个进行分割,每次循环结束i=i+3,j=j+4;来确保我们将自己输入的代码分割成了3个一组,而后得到了四个一组的加密结果。

for (i = 0, j = 0; i <= len - 3; i += 3, j += 4) {base64jiami(str[i], str[i + 1], str[i + 2]);}

这串代码我们共用了三个数组
1.加密后的数组s[] 即s[0],s[1] ,s[2],s[3]
2.我们输入的字符串str[] str[0]=M, str[1]=a ,str[2]=n
3.base64字符串a[] ,即a[0] ,a[1], a[2] ,a[3] (这里的1,2,3仅代表编号)

1.得到s[0]
可以看到我们只是取了第一个字符二进制字节的前6个字节,所以只需要将str[0]右移2位就可以得到
s[j] = a[x >> 2];

2.得到s[1]
可以看到我们取了第一个字符的前两个字节和第二个字符的前四个字节。也就是第一个字符的1,2字节位要补到5,6字节位,第二个字符的5,6,7,8字节位要作为1,2,3,4字节位。
首先我们将str[0]=M左移四位得到1101 0000
将str[1]=右移四位得到0000 0110
而后将两者进行 (|)运算得到 1101 0110
但是现在7,8位还是1,还要和0x3f 即 0011 1111进行与(&)运算得到 0001 0110
和0x3f进行与运算的目的就是把7,8位变为0.
s[j + 1] = a[(x << 4 | y >> 4) & 0x3f];

3.得到s[2]
可以看到我们取了第二个字符的后四个字节还有第三个字符的前两个字节。根据得到s[1]的方法
str[1]左移2位得到1000 0100
str[2]右移6位得到0000 0001
两者进行或运算得到 0000 0101
再和0x3f进行与运算得到 0000 0101
s[j + 2] = a[(y << 2 | z >> 6) & 0x3f];

4.得到s[3]
可以看到我们需要str[2]的后6位。
所以我们可以直接将str[2]和0x3f进行与运算
s[j + 3] = a[z & 0x3f];

上面是当我们输入的字符串可以被3整除的情况,那如果不能整除呢?
当我们整除3余1时:

if (len % 3 == 1){s[j] = a[str[len - 1] >> 2];s[j + 1] = a[str[len - 1]<< 4 & 0x3f];s[j + 2] = '=';s[j + 3] = '=';}

第二个字符后面的字节补0,第三个和第四个字符直接变为“=”。这也是为什么“=“是我们判断base64加密的一个最主要的特征。

当整除3余2时:

if (len % 3 == 2) {s[j] = a[str[len - 2] >> 2];s[j+1] = a[(str[len - 2] << 4 | str[len - 1] >> 4) & 0x3f];s[j + 2] = a[(str[len - 1] << 2) & 0x3f];s[j + 3] = '=';}

第三个字符的后2个字节补0,第四个字符变为”=“。


以上就是base64编码的全部过程了。总的来说就是我们先把他按可以被3整除之后再去将最后一位或两位字符进行纠正就行了。第二步实现完成。

与base64进行异或运算

最后一步就非常简单了,一个for循环搞定!

 else {for (i = 0; i < len; i++) {s[i] = str[i] ^ a[i];}

运行结果展示和小结

ASCII总值大于1000时
ASCII总值小于1000时
通过本次作业对移位运算更加的熟练了,并且对base64的加密算法有了一个系统的了解。
see you!

base64原理解析相关推荐

  1. (转)Base64原理解析

    阅读目录 一. Base64编码由来 二.Base的索引表 三.Base64的原理 四 参考: 回到顶部 一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字 ...

  2. java_security之base64原理解析以及三种代码的实现方式

    一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送.这样用途就受到了很大 ...

  3. base64解码_一份简明的 Base64 原理解析

    书接上回,在 记一个 Base64 有关的 Bug 一文里,我们说到了 Base64 的编解码器有不同实现,交叉使用它们可能引发的问题等等. 这一回,我们来对 Base64 这一常用编解码技术的原理一 ...

  4. clickhouse原理解析与应用实践_Hybrid App (混合应用) 技术全解析 方案原理篇

    引言 随着 Web 技术和移动设备的快速发展,Hybrid 技术已经成为一种最主流最常见的方案.一套好的 Hybrid架构方案 能让 App 既能拥有极致的体验和性能,同时也能拥有 Web技术 灵活的 ...

  5. 私有密钥与公钥的用途与原理解析

    私有密钥与公钥的用途与原理解析 数字签名是什么? 作者: 阮一峰        http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_sig ...

  6. php webshell原理,php webshell分析和绕过waf原理解析

    本文讲述的是php webshell分析和绕过waf的原理解析,旨在服务社会,供安全研究人员学习使用,请勿用于其他非法用途,违者后果自负.WebShell是攻击者使用的恶意脚本,它的用途主要是在攻击后 ...

  7. Spark Shuffle原理解析

    Spark Shuffle原理解析 一:到底什么是Shuffle? Shuffle中文翻译为"洗牌",需要Shuffle的关键性原因是某种具有共同特征的数据需要最终汇聚到一个计算节 ...

  8. 秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

    2019独角兽企业重金招聘Python工程师标准>>> 上节概要: 上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六)  中, 介绍了 ...

  9. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  10. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

最新文章

  1. Iptables架构
  2. 两个获取http页面的c#函数
  3. MobileNet论文阅读笔记
  4. 设置和清除LD_LIBRARY_PATH
  5. idea 个性化定制快捷键
  6. 手把手教安装java开发环境_手把手教你配置java开发环境-java环境变量设置
  7. 25 PP配置-生产车间控制-工序-定义生产计划参数文件
  8. 数据科学 IPython 笔记本 7.5 数据索引和选择
  9. 击溃音乐服务器第一人!周杰伦新歌首发,QQ音乐服务器一度崩溃
  10. 震惊!华为服务器操作系统竟然开源了!
  11. python-pygame作品之黑客帝国代码雨
  12. 静态代理和动态代理的区别
  13. mybatis-plus批量insert效率低下怎么办(mysql)
  14. 基于DCT的信息隐藏
  15. 深度学习与计算机视觉教程(17) | 深度强化学习 (马尔可夫决策过程,Q-Learning,DQN)(CV通关指南·完结)
  16. JPBC库(基于配对的密码学)入门和避坑指南
  17. 04-dropbear
  18. 有些视频不显示IDM的下载按钮
  19. mysql 辅键_mysql 的主辅配置
  20. k8s学习-kubectl命令常用选项详解与实战

热门文章

  1. 智慧水务技能——SWMM、最优化与预测理论及三维动态可视化
  2. RF无线射频电路设计难点分析
  3. [转载]GRADS画图
  4. STM32 USB接口 一键下载电路详解与过程分析
  5. 信息学奥赛一本通pdf_信息学奥赛冠军的竞赛“秘籍”
  6. 8uftp是不是要保存,4步掌握8uftp保存密码的方法
  7. qqkey获取原理_征途手机版电脑版安装使用教程【安卓+ios电脑版图文攻略】
  8. QQ IDKey生成--一键加群
  9. 全能电子地图下载器——MapTileDownloader
  10. NSSM 注册PYTHON服务