当前位置:   article > 正文

Base64在线转换工具(详解)

base64在线

1.项目背景:

在计算机中一个字节共有256种,即ascii码表,而ascii码的128~255之间的值是不可见字符,对于一些只支持可见字符的协议,比如邮件传输协议(SMTP)只支持可见的ASCII字符的传递,如果要传输二进制文件,比如:图片、视 频是无法实现的,因此就有了base64编码格式,Base64编码格式对于所有二进制格式的数据,都可以转化为可显 示的字符base64的应用场景非常多,比如:

    1. 在网络上交换数据时,比如说从A地传递到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方  式有一些不同,这样那些不可见字符就有可能被处理错误,不利于传输。
    2. http先以当中的key-value字段,必须进行url编码,不然出现的等号或者空格可能是解析失败
    3. 有些文本协议不支持可见字符传输,比如简单邮件传输协议(SMTP)
    4. 网页中内嵌简单图片

2.项目目标

实现一个在线的base64的转换工具,支持文本的base64编码以及base64的解码,以及图片base64的转换

3.整体框架:

采用B/S的模式

4.base64编码原理

base64编码之所以成为base64,是因为其使用64个字符来对二进制数据进行编码

采用对应的编码表:

4.1编码过程:

这是最重要的一步,也是核心的地方

具体编码过程如下:

  1. 将每三个字符作为一组,一共是24个二进制比特位
  2. 将这24个二进制比特位分为4组,每组有6个二进制比特位
  3. 在每组前面加两个00扩展成32个二进制位,即四个字节

说白了就是将每三个字节转变为上述表格中可显示的4个字节。具体如下:

字符串能被3整除,比如base64编码:Man

1.   "M""a""n"ASCII值分别是7797110,对应的二进制值是010011010110000101101110将它们连成一个24位的二进制字符串010011010110000101101110

2.      将这个24位的二进制字符串分成4组,每组6个二进制位:010011010110000101101110

3.      在每组前面加两个00,扩展成32个二进制位,即四个字节:000100110001011000000101

00101110。它们的十进制值分别是1922546

4.      根据上表,得到每个值对应Base64编码,即T,W,F,U

不能被3整除,比如base64编码:Lucy

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

注意:base64一行最多只能显示76个可显字符

缺陷:Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右

4.2解码过程

解码过程与编码过程是可逆的,对于一个base64的结果,只需每四个一组,将其转化为3个字节即可

采用对应的解码表:

假设对于base64结果:aGVsbG8=

每四个字节一组,以每个字符的ASCII码为下标,从解码表中取每个字节对应的解码表中的下标,对于每个下标取  其低6位,构成24个比特位,即:

base64[0]取其低6位,存储到一个整形的第18~23比特位置 >base64[0]<<18

base64[1]取其低6位,存储到一个整形的第12~17比特位置 >base64[1]<<12

base64[2]取其低6位,存储到一个整形的第11~06比特位置 >base64[2]<<6

base64[3]取其低6位,存储到一个整形的第0~5比特位置 >base64[3]

然后依次取该整形的低三个字节,即解码后的结果。

根据这样子的编码与解码,就能编写出base64的类与代码。

5.搭建服务端

5.1 使用cpp-httplib搭建服务器

本文使用cpp-httplib搭建http服务器,cpp-httplib是一个C++封装的跨平台的http库,借助该库可以快速在

windowslinux下搭建http服务器和客户端,使用非常简单,只需在项目中包含httplib.h头文件即可。

搭建http服务器的流程:

  1. 搭建tcp服务器
  2. 等待客户端连接请求
  3. 连接到来时,则创建线程/进程来处理这个连接

5.2Json使用介绍

JSON( JavaScript Object Notation)一种轻量级的数据交换格式.易于阅读和理解,也易于机器解析和生成.JSON采用独立于语言的文本格式,使用了类似于C语言家族的习惯(包括C,C++,C#,Java, JavaScript, Perl, Python).这些特性使得JSON成为理想的数据交换语言。

  1. json格式

对象

对象是一个无序的"'名称/'"集合.一个对象以“{”(左括号)开始,“}”(右括号)结束。每个名称跟一个“:”(冒号);“‘名称/之间使用“,”(逗号)分隔。

数组

数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间间使 “,”(逗号)分隔。

  1. vs2013下搭建json环境

2.设置json头文件加载路径

3.设置json lib库文件路径

4.包含json头文件和引入json 静态库文件

5.3http协议约定

1.文本转换为base64编码

2.图片转base64编码

6.客户端处理:

客户端请求以及收到服务响应之后,将转换结果更新到网页中,用THML语言实现。

 

 

以下是我编写的源代码;

base64类头文件

  1. #pragma once
  2. #include<string>
  3. using namespace std;
  4. class Base64
  5. {
  6. public:
  7. string Encode(const string& strdate);
  8. string Decode(const string& strdate);
  9. };

base64类的实现

  1. #include"Base64.h"
  2. using namespace std;
  3. string Base64::Encode(const string& strDate){
  4. string strEncode;
  5. string strEncodetable("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
  6. unsigned char temp[4];
  7. size_t index = 0;
  8. size_t lineLength = 0;
  9. for (size_t i = 0; i < strDate.size()/3; i++)
  10. {
  11. //三个字符一组来进行转换
  12. temp[1] = strDate[index++];
  13. temp[2] = strDate[index++];
  14. temp[3] = strDate[index++];
  15. //取一个第一个字节的高6
  16. strEncode += strEncodetable[temp[1] >> 2];
  17. //取第一个字节的低2位,与第二个字节的高四位拼接
  18. strEncode += strEncodetable[(((temp[1] << 4) | (temp[2] >> 4)) & 0x3f)];
  19. //取第二个字节的低4位,与第三个字节的高2位拼接
  20. strEncode += strEncodetable[(temp[2] << 2 | temp[3] >> 6) & 0x3f];
  21. //第三个字节剩余6个比特位
  22. strEncode += strEncodetable[temp[3] & 0x3f];
  23. lineLength += 4;
  24. if (76 == lineLength){
  25. strEncode += "\r\n";
  26. lineLength = 0;
  27. }
  28. }
  29. size_t mod = strDate.size() % 3;
  30. //模完剩余一个字节,补两个=
  31. if (1 == mod){
  32. temp[1] = strDate[index++];
  33. strEncode += strEncodetable[ (temp[1] & 0xfc) >>2];
  34. strEncode += strEncodetable[(temp[1] & 0x03 )<< 4];
  35. strEncode += "==";
  36. }
  37. //摸完剩余两个字节,补一个=
  38. else if (2 == mod){
  39. temp[1] = strDate[index++];
  40. temp[2] = strDate[index++];
  41. //取第一个字节的高6个比特位
  42. strEncode += strEncodetable[temp[1] >> 2];
  43. //取第一个字节的低2个比特位,与第二个字节的高4
  44. strEncode += strEncodetable[(((temp[1] << 4) | (temp[2] >> 4)) & 0x3f)];
  45. //取第二个比特位的低4
  46. strEncode += strEncodetable[(temp[2] & 0x0f) << 2];
  47. strEncode += "=";
  48. }
  49. return strEncode;
  50. }
  51. string Base64::Decode(const string& strDate){
  52. string strDecode;
  53. const char DecodeTable[] =
  54. {
  55. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  56. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57. 62, // '+'
  58. 0, 0, 0,
  59. 63, // '/'
  60. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
  61. 0, 0, 0, 0, 0, 0, 0,
  62. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  63. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
  64. 0, 0, 0, 0, 0, 0,
  65. 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
  66. 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
  67. };
  68. size_t value = 0;//用来保存解码的四组6个比特位---总共24个比特位
  69. size_t index = 0;
  70. while (index < strDate.size()){
  71. //base编码时一行能放置76个字符,超过76个字符,放置下一行
  72. if (strDate[index] != '\r' &&strDate[index+1] != '\n'){
  73. //一行没有解码完毕
  74. //解析第一个编码---->以该编码作为解码表的下标,到解码表找该编码在编码表的下标
  75. value=DecodeTable[strDate[index++]]<<18;
  76. //解析第二个编码
  77. value += DecodeTable[strDate[index++]] << 12;
  78. strDecode += ((value >> 16)&0xff);
  79. if (strDate[index] != '='){
  80. //解析第三个编码
  81. value += DecodeTable[strDate[index++]] << 6;
  82. strDecode += ((value >> 8)&0xff);
  83. if (strDate[index] != '='){
  84. //解析第四个编码
  85. value += DecodeTable[strDate[index++]];
  86. strDecode += (value&0xff);
  87. }
  88. else{
  89. break;
  90. }
  91. }
  92. else{
  93. break;
  94. }
  95. }
  96. else{
  97. //解码来到该行的末尾
  98. //跳过/r/n
  99. index += 2;
  100. }
  101. }
  102. return strDecode;
  103. }

服务端的搭建以及对服务端的使用

  1. #include"Base64.h"
  2. #include<iostream>
  3. #include"httplib.h"
  4. #include"json.h"
  5. #pragma comment(lib, ".\\..\\Debug\\json_vc71_libmtd.lib")
  6. using namespace std;
  7. //必须要有两个参数
  8. //http请求
  9. //http响应
  10. void testjson(){
  11. Json::Value value;
  12. value["name"] = "peter";
  13. value["gender"] = "男";
  14. value["age"] = "18";
  15. int scores[] = { 70, 80, 90 };
  16. for (auto e : scores)
  17. {
  18. value["score"].append(e);
  19. }
  20. Json::StyledWriter sw;
  21. string strJsonData = sw.write(value);
  22. cout << strJsonData << endl;
  23. Json::Reader rd;
  24. Json::Value rdvalue;
  25. rd.parse(strJsonData,rdvalue);
  26. }
  27. void Str2base64(const httplib::Request &req,httplib::Response& rsp){
  28. //解析前端数据
  29. Json::Value value;
  30. Json::Reader rd;
  31. if (!rd.parse(req.body, value)){
  32. rsp.set_content("", "text/html");
  33. rsp.status = 500;
  34. return;
  35. }
  36. //将文本转换为base64
  37. Base64 base64;
  38. string strRst=base64.Encode(value["strtextdata"].asString());
  39. //先来进行序列化
  40. Json::StyledWriter sw;
  41. Json::Value wvalue;
  42. wvalue["base64Data"] = strRst;
  43. strRst = sw.write(wvalue);
  44. rsp.set_content(strRst, "text/html");
  45. rsp.status = 200;
  46. }
  47. void base642Str(const httplib::Request &req, httplib::Response& rsp){
  48. //解析前端数据
  49. Json::Value value;
  50. Json::Reader rd;
  51. if (!rd.parse(req.body, value)){
  52. rsp.set_content("", "text/html");
  53. rsp.status = 500;
  54. return;
  55. }
  56. //将文本转换为base64
  57. Base64 base64;
  58. string strRst = base64.Decode(value["base64data"].asString());
  59. //先来进行序列化
  60. Json::StyledWriter sw;
  61. Json::Value wvalue;
  62. wvalue["str"] = strRst;
  63. strRst = sw.write(wvalue);
  64. rsp.set_content(strRst, "text/html");
  65. rsp.status = 200;
  66. }
  67. int main()
  68. {
  69. httplib::Server s;
  70. s.set_base_dir(".//..//Debug");
  71. s.Post("/str_2_base64", Str2base64);
  72. s.Post("/base64_2_str", base642Str);
  73. s.listen("127.0.0.1",9000);
  74. return 0;
  75. }

下面是客户端的HTML的代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>base64在线转换工具</title>
  6. <style type="text/css">
  7. /*清除默认样式,定义网页选择样式*/
  8. *{
  9. margin: 0;
  10. padding: 0;
  11. }
  12. .select_menu{
  13. height: 30px;
  14. width: 800px;
  15. background-color: cornflowerblue;
  16. margin: 30px auto 3px;
  17. }
  18. .base64_text_content{
  19. height:600px;
  20. width: 800px;
  21. margin: 0 auto;
  22. }
  23. li{
  24. list-style:none;/*清除li前的标记*/
  25. cursor: pointer;/*当光标在li上,让光标按照小手鼠标样子进行显示*/
  26. }
  27. .select_menu li{
  28. float:left;
  29. height: 30px;
  30. width: 50%;
  31. text-align: center;
  32. color: white;
  33. font-weight: bold;
  34. }
  35. .select_menu li:hover{
  36. background-color: red;
  37. }
  38. .page_1{
  39. width: 100%;
  40. height: 100%;
  41. display: block;
  42. }
  43. .page_2{
  44. width: 100%;
  45. height: 100%;
  46. display: none;
  47. }
  48. .content_left{
  49. width:300px;
  50. height: 100%;
  51. float: left;
  52. }
  53. .content_mid{
  54. width:200px;
  55. height: 100%;
  56. background-color: aquamarine;
  57. float: left;
  58. text-align:center;
  59. }
  60. .content_right{
  61. width:300px;
  62. height: 100%;
  63. float: left;
  64. }
  65. .text{
  66. width:100%;
  67. height: 100%;
  68. resize: none;
  69. }
  70. .btn_op{
  71. background-color: aliceblue;
  72. display: block;
  73. margin: 30px auto;
  74. }
  75. .pictextarea{
  76. width:800px;
  77. height: 600px;
  78. }
  79. </style>
  80. </head>
  81. <body>
  82. <!--选择v具体操作功能菜单-->
  83. <div class="select_menu">
  84. <ul>
  85. <li onclick="select_op(true)">文本base64转换</li>
  86. <li onclick="select_op(false)">图片base64转换</li>
  87. </ul>
  88. </div>
  89. <!--具体显示 文本转64和图片转base64内容区-->
  90. <div class="base64_text_content">
  91. <div id="text2base64"class="page_1">
  92. <div class="content_left">
  93. <textarea id="strtext"class="text" >我是一个文本</textarea>
  94. </div>
  95. <div class="content_mid">
  96. <button class="btn_op"onclick="str2Base64()">文本转base64</button>
  97. <button class="btn_op"onclick="Base642str()">base64转文本</button>
  98. </div>
  99. <div class="content_right">
  100. <textarea id="base64Data"class="text" >我是一个文本</textarea>
  101. </div>
  102. </div>
  103. <div id="pic2base64"class="page_2">
  104. <form id="picData" method="post" action="",enctype="multipart/form-data" style="float: left;">
  105. <input type="file" name="file" />
  106. </form>
  107. <button onclick="pic2Base64()">图片转base64</button>
  108. <p>base64图片数据</p>
  109. <textarea class="pictextarea"></textarea>
  110. <img src="img/1.jpg"/>
  111. </div>
  112. </div>
  113. <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
  114. <script>
  115. function select_op(op){
  116. if(op){
  117. document.getElementById("text2base64").style.display="block";
  118. document.getElementById("pic2base64").style.display="none";
  119. }
  120. else{
  121. document.getElementById("pic2base64").style.display="block";
  122. document.getElementById("text2base64").style.display="none";
  123. }
  124. }
  125. function str2Base64(){
  126. //从网页中获取文本数据
  127. var strData=document.getElementById("strtext").value;
  128. //构造post请求,发送给服务器
  129. $.ajax({
  130. type:"POST",
  131. url:"/str_2_base64",
  132. data:JSON.stringify({"strtextdata":strData}),
  133. dataType:"json",
  134. success:function(result){
  135. //result保存的就是转换结果的json格式数据
  136. $("#base64Data").val(result["base64Data"]);
  137. },
  138. error:function(result){
  139. alert("str2base失败");
  140. }
  141. });
  142. }
  143. function Base642str(){
  144. var strData=document.getElementById("base64Data").value;
  145. //构造post请求,发送给服务器
  146. $.ajax({
  147. type:"POST",
  148. url:"/base64_2_str",
  149. data:JSON.stringify({"base64data":strData}),
  150. dataType:"json",
  151. success:function(result){
  152. //result保存的就是转换结果的json格式数据
  153. $("#strtext").val(result["str"]);
  154. },
  155. error:function(result){
  156. alert("str2base失败");
  157. }
  158. });
  159. }
  160. function pic2Base64(){
  161. //获取图片数据
  162. var strData=document.getElementById("base64Data").value;
  163. var formData=new FormData();
  164. var file=document.getElementById("picData").files[0];
  165. formData.append("strPicData",file);
  166. //构造post请求,发送给服务器
  167. $.ajax({
  168. type:"POST",
  169. url:"/pic_base64",
  170. data:formData,
  171. dataType:"json",
  172. success:function(result){
  173. //result保存的就是转换结果的json格式数据
  174. $("#strtext").val(result["str"]);
  175. },
  176. error:function(result){
  177. alert("str2base失败");
  178. }
  179. });
  180. }
  181. </script>
  182. </body>
  183. </html>

以上就是项目的全部内容了。

谢谢观看:)

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/256230
推荐阅读
相关标签
  

闽ICP备14008679号