Base64编码和解码/Libcurl库进行http通讯
Base64编码的原理
Base64可以将ASCII字符串或者是二进制编码成只包含A—Z,a—z,0—9,+,/ 这64个字符( 26个大写字母,26个小写字母,10个数字,1个+,一个 / 刚好64个字符)。这64个字符用6个bit位就可以全部表示出来,一个字节有8个bit 位,那么还剩下两个bit位,这两个bit位用0来补充。
界面设置
-
步骤
-
选择文件-》进行base64编码
-
编码后的数据-》进行base64解码-》显示数据
-
-
代码说明–编码是在别人的基础上进行修改;解码部分个人完成
编码 --文件读取后,需要在末尾添加“\0”
FILE* file = fopen(m_strFileName, "r"); if (file) { char* buf; //要获取的字符串 int len; //获取的长度 fseek(file, 0, SEEK_END); //移到尾部 len = ftell(file); //提取长度 rewind(file); //回归原位 //分配buf空间 buf = (char*)malloc(sizeof(char) * len + 1); if (!buf) { return; } //读取文件 //读取进的buf,单位大小,长度,文件指针 int rLen = fread(buf, sizeof(char), len, file); buf[rLen] = '\0'; strOrigCode = buf; fclose(file); free(buf); } Base64 classBase64; std::string strBase64Code; strBase64Code = classBase64.base64_encode(strOrigCode); //进行编码
解码
Base64 classBase64; std::string strOrigCode; std::string strFileCode; strBase64Code = m_strBase64Code.GetBuffer(); strFileCode = classBase64.base64_decode(strBase64Code);
核心代码 base64.h
/** \file Base64.h
** \date 2004-02-13
** \author grymse@alhem.net
**/
/*
Copyright (C) 2004-2006 Anders Hedstrom
This library is made available under the terms of the GNU GPL.
If you would like to use this library in a closed-source application,
a separate license agreement is available. For information about
the closed-source license agreement for the C++ sockets library,
please visit http://www.alhem.net/Sockets/license.html and/or
email license@alhem.net.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _BASE64_H
#define _BASE64_H
#ifdef _WIN32
#pragma warning(disable:4514)
#endif
#include "StdAfx.h"
#include <stdio.h>
#include <string>
/** \defgroup util Utilities */
/** Base64 encode/decode.
\ingroup util */
class Base64
{
public:
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));};
std::string base64_encode(unsigned char const* , unsigned int len);
//std::string base64_encode(std::string const& s);
std::string Base64::base64_encode(std::string str);
std::string base64_decode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);
};
#endif // _BASE64_H
核心代码 base64.cpp
#include "StdAfx.h"
#include "Base64.h"
#include <iostream>
#include <ctype.h>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string Base64::base64_encode(std::string str)
//(const std::string &s)
{
//return base64_encode((const unsigned char *)s.c_str(), s.length());
return base64_encode(reinterpret_cast<const unsigned char*>(str.c_str()), str.length());
}
std::string Base64::base64_decode(unsigned char const* encoded_string, unsigned int in_len)
{
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
//第二种 都可以
// if (i) {
// for (j = 0; j < i; j++)
// char_array_4[j] = base64_chars.find(char_array_4[j]);
//
// char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
// char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
//
// for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
// }
//
return ret;
}
std::string Base64::base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
//char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string Base64::base64_decode(std::string const& decode_string)
{
return base64_decode((const unsigned char *)decode_string.c_str(), decode_string.size());
}
如果没有语言要求,可以用c#语言更加简单
// 文件转为base64编码
try
{
using (FileStream filestream = new FileStream(filePath, FileMode.Open))
{
byte[] bt = new byte[filestream.Length];
//调用read读取方法
filestream.Read(bt, 0, bt.Length);
base64Str = Convert.ToBase64String(bt);
filestream.Close();
}
return base64Str;
}
catch (Exception ex)
{
return base64Str;
}
// 文件base64解码
var contents = Convert.FromBase64String(base64Str);
using (var fs = new FileStream(outPath, FileMode.Create, FileAccess.Write))
{
fs.Write(contents, 0, contents.Length);
fs.Flush();
}
Libcurl库
-
编译
解压压缩包;在project目录的Windows下,有许多vc版本,我个人用的vc15
打开curl-all.sln,选择对应的debug/release
-
环境配置
头文件 :
#include “stdafx.h”
#include
#include “curl/curl.h”
#include
#include
#includestdafx.cpp – 对库的引用
#include “stdafx.h”
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib, “…/bin_debug_x64/libcurld.lib”)
#else
#pragma comment(lib, “…/bin_x64/libcurl.lib”)#endif // _DEBUG
#else
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
//而不是在此文件中引用
#ifdef _DEBUG //x86 | debug
#pragma comment(lib,"…/bin_debug/libcurld.lib")
#else //x86 | release
#pragma comment(lib,"…/bin/libcurl.lib")#endif
#endif //_WIN64 -
-
代码
-
get
size_t getUrlResponse(char* buffer, size_t size, size_t count, string* response) { size_t recv_size = size * count; //response->clear(); response->append(buffer); return recv_size; } string get(const string& url) { // 请求数据 string response; // easy handle声明 CURL *handle; // 初始化handle handle = curl_easy_init(); // 设置url curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); // 注册回调函数 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &getUrlResponse); /* 可以注释 set CURLOPT_WRITEDATA, 同时将回调函数恢复为上文中的原型, 看看会发生什么 */ // 获取信息 curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response); // 执行请求 curl_easy_perform(handle); // 释放 curl_easy_cleanup(handle); return response; } 简单使用的url 请求是http get(url); 返回的值是响应的字符串
-
post
size_t req_reply(void *ptr, size_t size, size_t nmemb, void *stream) { //在注释的里面可以打印请求流,cookie的信息 //cout << "----->reply" << endl; string *str = (string*)stream; //cout << *str << endl; (*str).append((char*)ptr, size*nmemb); return size * nmemb; } //http POST请求 CURLcode curl_post_req(const string &url, const string &postParams, string &response) { // curl初始化 CURL *curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { // set params //设置curl的请求头 struct curl_slist* header_list = NULL; header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"); header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); //不接收响应头数据0代表不接收 1代表接收 curl_easy_setopt(curl, CURLOPT_HEADER, 0); //设置请求为post请求 curl_easy_setopt(curl, CURLOPT_POST, 1); //设置请求的URL地址 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); //设置post请求的参数 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postParams.c_str()); //设置ssl验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 6); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6); // 开启post请求 res = curl_easy_perform(curl); } //释放curl curl_easy_cleanup(curl); return res; } 简单使用例子 string url_post0 = "http://httpbin.org/post"; string paramsLogin0 = "key1=value1&key2=value2"; string resPost0; auto res3 = curl_post_req(url_post0, paramsLogin0, resPost0); if (res3 == CURLE_OK) { //cout << resPost0 << endl; }
-