赞
踩
在计算机中一个字节共有256种,即ascii码表,而ascii码的128~255之间的值是不可见字符,对于一些只支持可见字符的协议,比如邮件传输协议(SMTP)只支持可见的ASCII字符的传递,如果要传输二进制文件,比如:图片、视 频是无法实现的,因此就有了base64编码格式,Base64编码格式对于所有二进制格式的数据,都可以转化为可显 示的字符。base64的应用场景非常多,比如:
实现一个在线的base64的转换工具,支持文本的base64编码以及base64的解码,以及图片base64的转换
采用B/S的模式
base64编码之所以成为base64,是因为其使用64个字符来对二进制数据进行编码。
采用对应的编码表:
这是最重要的一步,也是核心的地方
具体编码过程如下:
说白了就是将每三个字节转变为上述表格中可显示的4个字节。具体如下:
字符串能被3整除,比如base64编码:Man
1. "M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110, 将它们连成一个24位的二进制字符串010011010110000101101110。
2. 将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。
3. 在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、
00101110。它们的十进制值分别是19、22、5、46。
4. 根据上表,得到每个值对应Base64编码,即T,W,F,U
不能被3整除,比如base64编码:Lucy
如果要编码的字节数不能被3整除,最后会多出1个或2个字节,先使用0字节值在末尾补足,使其能够被3整 除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。也就是 说,当最后剩余一个八位字节(1个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个 等号;如果最后剩余两个八位字节(2个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等 号。
注意:base64一行最多只能显示76个可显字符。
缺陷:Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右
解码过程与编码过程是可逆的,对于一个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的类与代码。
本文使用cpp-httplib搭建http服务器,cpp-httplib是一个C++封装的跨平台的http库,借助该库可以快速在
windows和linux下搭建http服务器和客户端,使用非常简单,只需在项目中包含httplib.h头文件即可。
搭建http服务器的流程:
JSON( JavaScript Object Notation)是一种轻量级的数据交换格式.易于阅读和理解,也易于机器解析和生成.JSON采用独立于语言的文本格式,使用了类似于C语言家族的习惯(包括C,C++,C#,Java, JavaScript, Perl, Python等).这些特性使得JSON成为理想的数据交换语言。
对象
对象是一个无序的"'名称/值'对"集合.一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后 跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间间使 用“,”(逗号)分隔。
2.设置json头文件加载路径
3.设置json lib库文件路径
4.包含json头文件和引入json 静态库文件
1.文本转换为base64编码
2.图片转base64编码
客户端请求以及收到服务响应之后,将转换结果更新到网页中,用THML语言实现。
base64类头文件
- #pragma once
-
- #include<string>
- using namespace std;
- class Base64
- {
- public:
- string Encode(const string& strdate);
- string Decode(const string& strdate);
- };
base64类的实现
- #include"Base64.h"
- using namespace std;
- string Base64::Encode(const string& strDate){
- string strEncode;
- string strEncodetable("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
- unsigned char temp[4];
- size_t index = 0;
- size_t lineLength = 0;
- for (size_t i = 0; i < strDate.size()/3; i++)
- {
- //三个字符一组来进行转换
- temp[1] = strDate[index++];
- temp[2] = strDate[index++];
- temp[3] = strDate[index++];
- //取一个第一个字节的高6位
- strEncode += strEncodetable[temp[1] >> 2];
- //取第一个字节的低2位,与第二个字节的高四位拼接
- strEncode += strEncodetable[(((temp[1] << 4) | (temp[2] >> 4)) & 0x3f)];
- //取第二个字节的低4位,与第三个字节的高2位拼接
- strEncode += strEncodetable[(temp[2] << 2 | temp[3] >> 6) & 0x3f];
- //第三个字节剩余6个比特位
- strEncode += strEncodetable[temp[3] & 0x3f];
- lineLength += 4;
- if (76 == lineLength){
- strEncode += "\r\n";
- lineLength = 0;
- }
- }
- size_t mod = strDate.size() % 3;
- //模完剩余一个字节,补两个=号
- if (1 == mod){
- temp[1] = strDate[index++];
- strEncode += strEncodetable[ (temp[1] & 0xfc) >>2];
- strEncode += strEncodetable[(temp[1] & 0x03 )<< 4];
- strEncode += "==";
- }
- //摸完剩余两个字节,补一个=号
- else if (2 == mod){
- temp[1] = strDate[index++];
- temp[2] = strDate[index++];
- //取第一个字节的高6个比特位
- strEncode += strEncodetable[temp[1] >> 2];
- //取第一个字节的低2个比特位,与第二个字节的高4位
- strEncode += strEncodetable[(((temp[1] << 4) | (temp[2] >> 4)) & 0x3f)];
- //取第二个比特位的低4位
- strEncode += strEncodetable[(temp[2] & 0x0f) << 2];
-
- strEncode += "=";
- }
- return strEncode;
- }
- string Base64::Decode(const string& strDate){
- string strDecode;
- const char DecodeTable[] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, // '+'
- 0, 0, 0,
- 63, // '/'
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
- 0, 0, 0, 0, 0, 0, 0,
- 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, // 'A'-'Z'
- 0, 0, 0, 0, 0, 0,
- 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, // 'a'-'z'
- };
- size_t value = 0;//用来保存解码的四组6个比特位---总共24个比特位
- size_t index = 0;
- while (index < strDate.size()){
- //base编码时一行能放置76个字符,超过76个字符,放置下一行
- if (strDate[index] != '\r' &&strDate[index+1] != '\n'){
- //一行没有解码完毕
- //解析第一个编码---->以该编码作为解码表的下标,到解码表找该编码在编码表的下标
- value=DecodeTable[strDate[index++]]<<18;
- //解析第二个编码
- value += DecodeTable[strDate[index++]] << 12;
- strDecode += ((value >> 16)&0xff);
- if (strDate[index] != '='){
- //解析第三个编码
- value += DecodeTable[strDate[index++]] << 6;
- strDecode += ((value >> 8)&0xff);
- if (strDate[index] != '='){
- //解析第四个编码
- value += DecodeTable[strDate[index++]];
- strDecode += (value&0xff);
- }
- else{
- break;
- }
- }
- else{
- break;
- }
- }
- else{
- //解码来到该行的末尾
- //跳过/r/n
- index += 2;
- }
- }
- return strDecode;
- }
服务端的搭建以及对服务端的使用
- #include"Base64.h"
- #include<iostream>
- #include"httplib.h"
- #include"json.h"
- #pragma comment(lib, ".\\..\\Debug\\json_vc71_libmtd.lib")
- using namespace std;
- //必须要有两个参数
- //http请求
- //http响应
- void testjson(){
- Json::Value value;
- value["name"] = "peter";
- value["gender"] = "男";
- value["age"] = "18";
- int scores[] = { 70, 80, 90 };
- for (auto e : scores)
- {
- value["score"].append(e);
- }
- Json::StyledWriter sw;
- string strJsonData = sw.write(value);
- cout << strJsonData << endl;
- Json::Reader rd;
- Json::Value rdvalue;
- rd.parse(strJsonData,rdvalue);
-
- }
- void Str2base64(const httplib::Request &req,httplib::Response& rsp){
- //解析前端数据
- Json::Value value;
- Json::Reader rd;
- if (!rd.parse(req.body, value)){
- rsp.set_content("", "text/html");
- rsp.status = 500;
- return;
- }
- //将文本转换为base64
- Base64 base64;
- string strRst=base64.Encode(value["strtextdata"].asString());
- //先来进行序列化
- Json::StyledWriter sw;
- Json::Value wvalue;
- wvalue["base64Data"] = strRst;
- strRst = sw.write(wvalue);
- rsp.set_content(strRst, "text/html");
- rsp.status = 200;
- }
- void base642Str(const httplib::Request &req, httplib::Response& rsp){
- //解析前端数据
- Json::Value value;
- Json::Reader rd;
- if (!rd.parse(req.body, value)){
- rsp.set_content("", "text/html");
- rsp.status = 500;
- return;
- }
- //将文本转换为base64
- Base64 base64;
- string strRst = base64.Decode(value["base64data"].asString());
- //先来进行序列化
- Json::StyledWriter sw;
- Json::Value wvalue;
- wvalue["str"] = strRst;
- strRst = sw.write(wvalue);
- rsp.set_content(strRst, "text/html");
- rsp.status = 200;
- }
- int main()
- {
- httplib::Server s;
- s.set_base_dir(".//..//Debug");
- s.Post("/str_2_base64", Str2base64);
- s.Post("/base64_2_str", base642Str);
- s.listen("127.0.0.1",9000);
- return 0;
- }
下面是客户端的HTML的代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>base64在线转换工具</title>
- <style type="text/css">
- /*清除默认样式,定义网页选择样式*/
- *{
- margin: 0;
- padding: 0;
- }
- .select_menu{
- height: 30px;
- width: 800px;
- background-color: cornflowerblue;
- margin: 30px auto 3px;
- }
- .base64_text_content{
- height:600px;
- width: 800px;
- margin: 0 auto;
- }
- li{
- list-style:none;/*清除li前的标记*/
- cursor: pointer;/*当光标在li上,让光标按照小手鼠标样子进行显示*/
- }
- .select_menu li{
- float:left;
- height: 30px;
- width: 50%;
- text-align: center;
- color: white;
- font-weight: bold;
- }
- .select_menu li:hover{
- background-color: red;
- }
-
- .page_1{
- width: 100%;
- height: 100%;
- display: block;
- }
- .page_2{
- width: 100%;
- height: 100%;
- display: none;
- }
- .content_left{
- width:300px;
- height: 100%;
- float: left;
- }
- .content_mid{
- width:200px;
- height: 100%;
- background-color: aquamarine;
- float: left;
- text-align:center;
- }
- .content_right{
- width:300px;
- height: 100%;
- float: left;
- }
- .text{
- width:100%;
- height: 100%;
- resize: none;
- }
- .btn_op{
- background-color: aliceblue;
- display: block;
- margin: 30px auto;
- }
- .pictextarea{
- width:800px;
- height: 600px;
- }
- </style>
- </head>
- <body>
- <!--选择v具体操作功能菜单-->
- <div class="select_menu">
- <ul>
- <li onclick="select_op(true)">文本base64转换</li>
- <li onclick="select_op(false)">图片base64转换</li>
- </ul>
- </div>
- <!--具体显示 文本转64和图片转base64内容区-->
- <div class="base64_text_content">
- <div id="text2base64"class="page_1">
-
-
- <div class="content_left">
- <textarea id="strtext"class="text" >我是一个文本</textarea>
- </div>
-
-
-
- <div class="content_mid">
- <button class="btn_op"onclick="str2Base64()">文本转base64</button>
- <button class="btn_op"onclick="Base642str()">base64转文本</button>
- </div>
-
-
-
- <div class="content_right">
- <textarea id="base64Data"class="text" >我是一个文本</textarea>
- </div>
- </div>
- <div id="pic2base64"class="page_2">
- <form id="picData" method="post" action="",enctype="multipart/form-data" style="float: left;">
- <input type="file" name="file" />
- </form>
- <button onclick="pic2Base64()">图片转base64</button>
- <p>base64图片数据</p>
- <textarea class="pictextarea"></textarea>
- <img src="img/1.jpg"/>
- </div>
- </div>
-
-
- <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
- <script>
- function select_op(op){
- if(op){
- document.getElementById("text2base64").style.display="block";
- document.getElementById("pic2base64").style.display="none";
- }
- else{
- document.getElementById("pic2base64").style.display="block";
- document.getElementById("text2base64").style.display="none";
- }
- }
- function str2Base64(){
- //从网页中获取文本数据
- var strData=document.getElementById("strtext").value;
- //构造post请求,发送给服务器
- $.ajax({
- type:"POST",
- url:"/str_2_base64",
- data:JSON.stringify({"strtextdata":strData}),
- dataType:"json",
- success:function(result){
- //result保存的就是转换结果的json格式数据
- $("#base64Data").val(result["base64Data"]);
- },
- error:function(result){
- alert("str2base失败");
- }
- });
- }
- function Base642str(){
- var strData=document.getElementById("base64Data").value;
- //构造post请求,发送给服务器
- $.ajax({
- type:"POST",
- url:"/base64_2_str",
- data:JSON.stringify({"base64data":strData}),
- dataType:"json",
- success:function(result){
- //result保存的就是转换结果的json格式数据
- $("#strtext").val(result["str"]);
- },
- error:function(result){
- alert("str2base失败");
- }
- });
- }
- function pic2Base64(){
- //获取图片数据
- var strData=document.getElementById("base64Data").value;
- var formData=new FormData();
- var file=document.getElementById("picData").files[0];
- formData.append("strPicData",file);
- //构造post请求,发送给服务器
- $.ajax({
- type:"POST",
- url:"/pic_base64",
- data:formData,
- dataType:"json",
- success:function(result){
- //result保存的就是转换结果的json格式数据
- $("#strtext").val(result["str"]);
- },
- error:function(result){
- alert("str2base失败");
- }
- });
- }
- </script>
- </body>
- </html>
以上就是项目的全部内容了。
谢谢观看:)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。