- 新增ISV用户平台

- 新增门户网站(portal)
- 新增`C++`,`Rust`语言SDK
This commit is contained in:
tanghc
2020-11-07 10:55:12 +08:00
parent 1370883af9
commit 6ab696dfaf
599 changed files with 34834 additions and 141 deletions

27
sop-sdk/sdk-c++/.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
/target/
/cmake-build-debug/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/

View File

@@ -0,0 +1,42 @@
# cmake和CMakeLists.txt教程
# https://www.jianshu.com/p/cb4f8136a265
cmake_minimum_required(VERSION 3.16)
project(sdk_cxx)
set(CMAKE_CXX_STANDARD 14)
set(LIB_SRC
common/OpenClient.cpp
common/OpenClient.h
common/RequestType.h
common/tool.h
common/sign.h
common/RSASign.h
common/RSASign.cpp
common/sha256.hpp
request/BaseRequest.h
request/MemberInfoGetRequest.hpp
thirdparty/base64/base64.h
thirdparty/base64/base64.cpp
thirdparty/CJsonObject/cJSON.c
thirdparty/CJsonObject/cJSON.h
thirdparty/CJsonObject/CJsonObject.hpp
thirdparty/CJsonObject/CJsonObject.cpp
thirdparty/x2struct/x2struct.hpp
common/sign.cpp common/tool.cpp common/sha256.cpp
request/BaseRequest.cpp response/BaseResponse.h response/MemberInfoGetResponse.h)
# openssl安装路径
set(OPENSSL_INC_DIR /usr/local/opt/openssl/include)
set(OPENSSL_LINK_DIR /usr/local/opt/openssl/lib)
include_directories(${OPENSSL_INC_DIR})
link_directories(${OPENSSL_LINK_DIR})
link_libraries(ssl crypto)
# 添加类库
add_library(lib ${LIB_SRC})
# 添加可执行文件
add_executable(sdk_cxx main.cpp)
# 可执行文件依赖lib库
target_link_libraries(sdk_cxx lib ssl)

1
sop-sdk/sdk-c++/aa.txt Normal file
View File

@@ -0,0 +1 @@
hello你好123

1
sop-sdk/sdk-c++/bb.txt Normal file
View File

@@ -0,0 +1 @@
文件bb的内容

View File

@@ -0,0 +1,133 @@
#include "OpenClient.h"
#include "httplib.h"
#include "tool.h"
#include "sign.h"
#include "../thirdparty/CJsonObject/CJsonObject.hpp"
httplib::Headers headers = {
{"Accept-Encoding", "identity"}
};
const string ERROR_NODE = "error_response";
OpenClient::OpenClient(const string &appId, const string &privateKeyFilePath, const string &url) {
this->appId = appId;
this->privateKeyFilePath = privateKeyFilePath;
char *_url = const_cast<char *>(url.c_str());
char *host;
int port;
char *path;
tool::parse_url(_url, &host, &port, &path);
this->hostInfo = HostInfo{
host = host,
port = port,
path = path
};
}
neb::CJsonObject OpenClient::execute(BaseRequest *request) {
return this->execute(request, "");
}
neb::CJsonObject OpenClient::execute(BaseRequest *request, const string &token) {
string method = request->getMethod();
string version = request->getVersion();
RequestType requestType = request->getRequestType();
map<string, string> bizModel = request->bizModel;
// 创建HTTP请求客户端
httplib::Client cli(this->hostInfo.host, this->hostInfo.port);
// 构建请求参数
map<string, string> allParams = this->buildParams(request, token);
char *path = this->hostInfo.path;
string responseBody;
// 如果有文件上传
if (!request->getFiles().empty()) {
httplib::MultipartFormDataItems items = OpenClient::getMultipartFormDataItems(
allParams, request->getFiles());
responseBody = cli.Post(path, headers, items)->body;
} else {
switch (requestType) {
case GET: {
responseBody = cli.Get(path, allParams, headers)->body;
break;
}
case POST_FORM: {
responseBody = cli.Post(path, headers, OpenClient::getParams(allParams))->body;
break;
}
case POST_JSON: {
string json = tool::mapToJson(allParams);
responseBody = cli.Post(path, json, "application/json")->body;
break;
}
case POST_FILE: {
httplib::MultipartFormDataItems items = OpenClient::getMultipartFormDataItems(
allParams, request->getFiles());
responseBody = cli.Post(path, headers, items)->body;
}
}
}
return OpenClient::parseResponse(responseBody, request);
}
httplib::Params OpenClient::getParams(map<string, string> allParams) {
httplib::Params params;
map<string, string>::iterator it;
for (it = allParams.begin(); it != allParams.end(); ++it) {
params.emplace(it->first, it->second);
}
return params;
}
map<string, string> OpenClient::buildParams(BaseRequest *request, const string &token) {
map<string, string> allParams;
allParams["app_id"] = this->appId;
allParams["method"] = request->getMethod();
allParams["charset"] = "UTF-8";
allParams["sign_type"] = "RSA2";
allParams["timestamp"] = tool::getTime();
allParams["version"] = request->getVersion();
if (!token.empty()) {
allParams["app_auth_token"] = token;
}
map<string, string> bizModel = request->bizModel;
allParams.insert(bizModel.begin(), bizModel.end());
// 生成签名
string sign = signutil::createSign(allParams, this->privateKeyFilePath, "RSA2");
allParams["sign"] = sign;
return allParams;
}
httplib::MultipartFormDataItems
OpenClient::getMultipartFormDataItems(map<string, string> allParams, vector<FileInfo> fileInfoList) {
httplib::MultipartFormDataItems items = {};
map<string, string>::iterator it;
for (it = allParams.begin(); it != allParams.end(); ++it) {
items.push_back({it->first, it->second, "", ""});
}
// 添加上传文件
vector<FileInfo>::iterator vit;
for (vit = fileInfoList.begin(); vit != fileInfoList.end(); vit++) {
string content = tool::getFileContent(vit->filepath);
items.push_back({vit->name, content, tool::getFilename(vit->filepath), "application/octet-stream"});
}
return items;
}
neb::CJsonObject OpenClient::parseResponse(const string& responseBody, BaseRequest *request) {
neb::CJsonObject oJson(responseBody);
neb::CJsonObject data = oJson[ERROR_NODE];
if (data.IsEmpty()) {
string method = request->getMethod();
string nodeName = tool::replace(method.c_str(),".","_") + "_response";
data = oJson[nodeName];
}
return data;
}

View File

@@ -0,0 +1,66 @@
#ifndef SDK_CXX_OPENCLIENT_H
#define SDK_CXX_OPENCLIENT_H
#include <string>
#include "httplib.h"
#include "../request/BaseRequest.h"
#include "../thirdparty/CJsonObject/CJsonObject.hpp"
using namespace std;
struct HostInfo {
string host;
int port;
char *path;
};
/**
* 请求客户端
*/
class OpenClient {
private:
/** 应用id */
string appId;
/** 私钥文件路径 */
string privateKeyFilePath;
public:
/**
* 创建客户端对象
* @param appId 应用ID
* @param privateKeyFilePath 应用私钥路径
* @param url 请求URL
*/
OpenClient(const string &appId, const string &privateKeyFilePath, const string &url);
/**
* 发送请求
* @param request 请求对象BaseRequest的子类
* @param token token
* @return 返回响应结果
*/
neb::CJsonObject execute(BaseRequest *request, const string& token);
/**
* 发送请求
* @param request 请求对象BaseRequest的子类
* @return 返回响应结果
*/
neb::CJsonObject execute(BaseRequest *request);
private:
HostInfo hostInfo;
map<string, string> buildParams(BaseRequest *request, const string& token);
static httplib::MultipartFormDataItems
getMultipartFormDataItems(map<string, string> allParams, vector<FileInfo> fileInfoList);
static httplib::Params getParams(map<string, string> params);
static neb::CJsonObject parseResponse(const string& responseBody,BaseRequest *request);
};
#endif //SDK_CXX_OPENCLIENT_H

View File

@@ -0,0 +1,94 @@
#include "stdafx.h"
#include "RSASign.h"
#include "../thirdparty/base64/base64.h"
RSA* GetPublicKeyEx(char* szPath)
{
RSA *pubkey = RSA_new();
BIO *pubio;
pubio = BIO_new_file(szPath, "rb");
pubkey = PEM_read_bio_RSAPublicKey(pubio, &pubkey, NULL, NULL);
BIO_free(pubio);
return pubkey;
}
RSA* GetPrivateKeyEx(char* szPath)
{
RSA *prikey = RSA_new();
BIO *priio;
priio = BIO_new_file(szPath, "rb");
prikey = PEM_read_bio_RSAPrivateKey(priio, &prikey, NULL, NULL);
BIO_free(priio);
return prikey;
}
bool RSASignAction(const string& strEnData, char *privateKeyFilePath, string &strSigned)
{
int nlen = strEnData.length();
RSA *prsa = NULL;
if (NULL == (prsa = GetPrivateKeyEx(privateKeyFilePath)))
{
RSA_free(prsa);
printf("获取私钥失败\n");
return false;
}
char szTmp[1024] = { 0 };
//对待签名数据做SHA1摘要
SHA256((const unsigned char*)strEnData.c_str(), nlen, (unsigned char*)szTmp);
int nLength;
unsigned int nLengthRet;
char szTmp1[1024] = { 0 }; //位数一定不能小于等于RSA的128位没有\0,数据会增加后面位数
// unsigned char *szTmp1 = {0};
nLength = RSA_sign(NID_sha256, (unsigned char *)szTmp, 32, (unsigned char *)szTmp1, &nLengthRet, prsa);
if (nLength != 1)
{
RSA_free(prsa);
return false;
}
strSigned = base64_encode((unsigned char *)szTmp1, strlen((const char *)szTmp1));
RSA_free(prsa);
return true;
}
bool RSAVerifyAction(string strEnData, string &strSigned)
{
int nlen = strEnData.length();
printf("验签的原始数据:[%s]\n", strEnData.c_str());
RSA *prsa = NULL;
if (NULL == (prsa = GetPublicKeyEx(PUBLIC_KEY_FILE_EX)))
{
RSA_free(prsa);
printf("获取公钥失败\n");
return -1;
}
//对待签名数据做SHA1摘要
char szTmp[1024] = { 0 };
int nLen = strEnData.length();
SHA256((const unsigned char*)strEnData.c_str(), nLen, (unsigned char*)szTmp);
int nLength;
unsigned int nLengthRet = strSigned.length();
printf("nLengthRet2 = %d\n", nLengthRet);
nLength = RSA_verify(NID_sha256, (unsigned char *)szTmp, 32, (unsigned char*)strSigned.c_str(), nLengthRet, prsa);
if (nLength != 1)
{
RSA_free(prsa);
return false;
}
RSA_free(prsa);
return true;
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string>
using namespace std;
#define PUBLIC_KEY_FILE_EX "publicEx.pem" //公钥文件
#define PRIVATE_KEY_FILE_EX "privateEx.pem" //私钥文件
RSA* GetPublicKeyEx(char* szPath);
RSA* GetPrivateKeyEx(char* szPath);
bool RSASignAction(const string& strEnData,char *privateKeyFilePath, string &strSigned);
bool RSAVerifyAction(string strEnData, string &strSigned);

View File

@@ -0,0 +1,11 @@
#ifndef SDK_CXX_REQUESTTYPE_H
#define SDK_CXX_REQUESTTYPE_H
enum RequestType {
GET,
POST_FORM,
POST_JSON,
POST_FILE
};
#endif //SDK_CXX_REQUESTTYPE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,270 @@
/*
* Filename: sha256.cpp
* Author: L.Y.
* Brief: SHA256算法实现
* Version: V1.0.0
* Update log:
* 120191108-20191113 V1.0.0
* 1、初次版本。
* TODO:
* Attention:
* 1输入信息中有中文时得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
* 原因是中文的编码方式不同。
*/
#include "sha256.hpp"
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
namespace digest
{
//////////////////////////////// 静态数据成员初始化 //////////////////////////////////////////
std::vector<uint32_t> Sha256::initial_message_digest_ =
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372,
0xa54ff53a, 0x510e527f, 0x9b05688c,
0x1f83d9ab, 0x5be0cd19
};
std::vector<uint32_t> Sha256::add_constant_ =
{
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
//////////////////////////////// 成员函数的定义 //////////////////////////////////////////
bool Sha256::encrypt(const std::vector<uint8_t>& input_message,
std::vector<uint8_t>* _digest)
{
if (!input_message.empty() && _digest)
{
//! 文本预处理
std::vector<uint8_t> message = input_message;
preprocessing(&message);
//! 将文本分解成连续的64Byte大小的数据块
std::vector<std::vector<uint8_t>> chunks;
breakTextInto64ByteChunks(message, &chunks);
//! 由64Byte大小的数据块构造出64个4Byte大小的字。然后进行循环迭代。
std::vector<uint32_t> message_digest(initial_message_digest_); // 初始化信息摘要
std::vector<uint32_t> words;
for (const auto& chunk : chunks)
{
structureWords(chunk, &words);
transform(words, &message_digest);
}
//! 获取最终结果
produceFinalHashValue(message_digest, _digest);
return true;
}
else
{
return false;
}
}
std::string Sha256::getHexMessageDigest(const std::string& message)
{
if (!message.empty())
{
std::vector<uint8_t> __message;
for (auto it = message.begin(); it != message.end(); ++it)
{
__message.push_back(static_cast<uint8_t>(*it));
}
std::vector<uint8_t> digest;
encrypt(__message, &digest);
std::ostringstream o_s;
o_s << std::hex << std::setiosflags(std::ios::uppercase);
for (auto it = digest.begin(); it != digest.end(); ++it)
{
o_s << std::setw(2) << std::setfill('0')
<< static_cast<unsigned short>(*it);
}
return o_s.str();
}
else
{
return "";
}
}
bool Sha256::preprocessing(std::vector<uint8_t>* _message) const
{
if (_message)
{
const uint64_t original_bit_size = _message->size() * 8;
//! 附加填充比特
size_t remainder = _message->size() % 64;
if (remainder < 56)
{
_message->push_back(0x80); // ox80 == 10000000
for (size_t i = 1; i < 56 - remainder; ++i)
{
_message->push_back(0x00);
}
}
else if (remainder == 56)
{
_message->push_back(0x80);
for (size_t i = 1; i < 64; ++i)
{
_message->push_back(0x00);
}
}
else
{
_message->push_back(0x80);
for (size_t i = 1; i < 64 - remainder + 56; ++i)
{
_message->push_back(0x00);
}
}
//! 附加原始文本的长度值
for (int i = 1; i <= 8; ++i)
{
uint8_t c = static_cast<uint8_t>(original_bit_size >> (64 - 8 * i));
_message->push_back(c);
}
return true;
}
else
{
return false;
}
}
bool Sha256::breakTextInto64ByteChunks(const std::vector<uint8_t>& message,
std::vector<std::vector<uint8_t>>* _chunks) const
{
if (_chunks && 0 == message.size() % 64)
{
_chunks->clear(); // 清空输出buffer
size_t quotient = message.size() / 64;
for (size_t i = 0; i < quotient; ++i)
{
std::vector<uint8_t> temp(message.begin() + i * 64, message.begin() + (i + 1) * 64);
_chunks->push_back(temp);
}
return true;
}
else
{
return false;
}
}
bool Sha256::structureWords(const std::vector<uint8_t>& chunk,
std::vector<uint32_t>* _words) const
{
if (_words && 64 == chunk.size())
{
_words->resize(64);
auto& words = *_words;
for (int i = 0; i < 16; ++i)
{
words[i] = (static_cast<uint32_t>(chunk[i * 4]) << 24)
| (static_cast<uint32_t>(chunk[i * 4 + 1]) << 16)
| (static_cast<uint32_t>(chunk[i * 4 + 2]) << 8)
| static_cast<uint32_t>(chunk[i * 4 + 3]);
}
for (int i = 16; i < 64; ++i)
{
words[i] = small_sigma1(words[i - 2])
+ words[i - 7]
+ small_sigma0(words[i - 15])
+ words[i - 16];
}
return true;
}
else
{
return false;
}
}
bool Sha256::transform(const std::vector<uint32_t>& words,
std::vector<uint32_t>* _message_digest) const
{
if (_message_digest && 8 == _message_digest->size() && 64 == words.size())
{
std::vector<uint32_t> d = *_message_digest;
for (int i = 0; i < 64; ++i)
{
uint32_t temp1 = d[7] + big_sigma1(d[4]) + ch(d[4], d[5], d[6]) + add_constant_[i] + words[i];
uint32_t temp2 = big_sigma0(d[0]) + maj(d[0], d[1], d[2]);
d[7] = d[6];
d[6] = d[5];
d[5] = d[4];
d[4] = d[3] + temp1;
d[3] = d[2];
d[2] = d[1];
d[1] = d[0];
d[0] = temp1 + temp2;
}
for (int i = 0; i < 8; ++i)
{
(*_message_digest)[i] += d[i];
}
return true;
}
else
{
return false;
}
}
bool Sha256::produceFinalHashValue(const std::vector<uint32_t>& input,
std::vector<uint8_t>* _output) const
{
if (_output)
{
_output->clear();
for (auto it = input.begin(); it != input.end(); ++it)
{
for (int i = 0; i < 4; i++)
{
_output->push_back(static_cast<uint8_t>((*it) >> (24 - 8 * i)));
}
}
return true;
}
else
{
return false;
}
}
} // namespace ly

View File

@@ -0,0 +1,144 @@
/*
* Filename: sha256.hpp
* Author: L.Y.
* Brief: SHA256算法实现
* Version: V1.0.0
* Update log:
* 120191108-20191113 V1.0.0
* 1、初次版本。
* TODO:
* Attention:
* 1输入信息中有中文时得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
* 原因是中文的编码方式不同。
*/
#ifndef SHA256_HPP
#define SHA256_HPP
#include <stdint.h>
#include <string>
#include <vector>
namespace digest
{
//
// \brief: SHA256算法实现
//
class Sha256
{
public:
//! 默认构造函数
Sha256() {}
//! 析构函数
virtual ~Sha256() {}
/** @brief: 使用SHA256算法获取输入信息的摘要数字指纹
@param[in] message: 输入信息
@param[out] _digest: 摘要(数字指纹)
@return: 是否成功
*/
bool encrypt(const std::vector<uint8_t>& message,
std::vector<uint8_t>* _digest);
/** @brief: 获取十六进制表示的信息摘要(数字指纹)
@param[in] message: 输入信息
@return: 十六进制表示的信息摘要(数字指纹)
*/
std::string getHexMessageDigest(const std::string& message);
protected:
/////// SHA256算法中定义的6种逻辑运算 ///////
inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) const;
inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) const;
inline uint32_t big_sigma0(uint32_t x) const;
inline uint32_t big_sigma1(uint32_t x) const;
inline uint32_t small_sigma0(uint32_t x) const;
inline uint32_t small_sigma1(uint32_t x) const;
/** @brief: SHA256算法对输入信息的预处理包括“附加填充比特”和“附加长度值”
附加填充比特: 在报文末尾进行填充先补第一个比特为1然后都补0直到长度满足对512取模后余数是448。需要注意的是信息必须进行填充。
附加长度值: 用一个64位的数据来表示原始消息填充前的消息的长度并将其补到已经进行了填充操作的消息后面。
@param[in][out] _message: 待处理的信息
@return: 是否成功
*/
bool preprocessing(std::vector<uint8_t>* _message) const;
/** @brief: 将信息分解成连续的64Byte大小的数据块
@param[in] message: 输入信息长度为64Byte的倍数
@param[out] _chunks: 输出数据块
@return: 是否成功
*/
bool breakTextInto64ByteChunks(const std::vector<uint8_t>& message,
std::vector<std::vector<uint8_t>>* _chunks) const;
/** @brief: 由64Byte大小的数据块构造出64个4Byte大小的字。
构造算法前16个字直接由数据块分解得到其余的字由如下迭代公式得到
W[t] = small_sigma1(W[t-2]) + W[t-7] + small_sigma0(W[t-15]) + W[t-16]
@param[in] chunk: 输入数据块大小为64Byte
@param[out] _words: 输出字
@return: 是否成功
*/
bool structureWords(const std::vector<uint8_t>& chunk,
std::vector<uint32_t>* _words) const;
/** @breif: 基于64个4Byte大小的字进行64次循环加密
@param[in] words: 64个4Byte大小的字
@param[in][out] _message_digest: 信息摘要
@return: 是否成功
*/
bool transform(const std::vector<uint32_t>& words,
std::vector<uint32_t>* _message_digest) const;
/** @brief: 输出最终的哈希值(数字指纹)
@param[in] input: 步长为32bit的哈希值
@param[out] _output: 步长为8bit的哈希值
@return: 是否成功
*/
bool produceFinalHashValue(const std::vector<uint32_t>& input,
std::vector<uint8_t>* _output) const;
private:
static std::vector<uint32_t> initial_message_digest_; // 在SHA256算法中的初始信息摘要这些常量是对自然数中前8个质数的平方根的小数部分取前32bit而来。
static std::vector<uint32_t> add_constant_; // 在SHA256算法中用到64个常量这些常量是对自然数中前64个质数的立方根的小数部分取前32bit而来。
};
///////////////////////////////// 内联函数&模版函数的定义 /////////////////////////////////////////
inline uint32_t Sha256::ch(uint32_t x, uint32_t y, uint32_t z) const
{
return (x & y) ^ ((~x) & z);
}
inline uint32_t Sha256::maj(uint32_t x, uint32_t y, uint32_t z) const
{
return (x & y) ^ (x & z) ^ (y & z);
}
inline uint32_t Sha256::big_sigma0(uint32_t x) const
{
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
}
inline uint32_t Sha256::big_sigma1(uint32_t x) const
{
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
}
inline uint32_t Sha256::small_sigma0(uint32_t x) const
{
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
}
inline uint32_t Sha256::small_sigma1(uint32_t x) const
{
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
}
} // namespace ly
#endif // SHA256_HPP

View File

@@ -0,0 +1,118 @@
#include <utility>
#include "../thirdparty/base64/base64.h"
#include "sign.h"
#include "RSASign.h"
#include "tool.h"
namespace signutil {
string createSign(map<string, string> params, const string& privateKeyFilepath, const string& signType) {
string content = getSignContent(std::move(params));
return sign(content, privateKeyFilepath, "");
}
string sign(const string& content, const string& privateKeyFilepath, const string& hash) {
BIO *bufio = NULL;
RSA *rsa = NULL;
EVP_PKEY *evpKey = NULL;
bool verify = false;
EVP_MD_CTX ctx;
int result = 0;
unsigned int size = 0;
char *sign = NULL;
std::string signStr = "";
//bufio = BIO_new_mem_buf((void*)private_key, -1);
//if (bufio == NULL) {
// ERR("BIO_new_mem_buf failed");
// goto safe_exit;
//}
bufio = BIO_new(BIO_s_file());
// 读取私钥文件
BIO_read_filename(bufio, privateKeyFilepath.c_str());
// 私钥字符串转换成私钥对象
rsa = PEM_read_bio_RSAPrivateKey(bufio, NULL, NULL, NULL);
if (rsa == NULL) {
ERR("PEM_read_bio_RSAPrivateKey failed");
goto safe_exit;
}
evpKey = EVP_PKEY_new();
if (evpKey == NULL) {
ERR("EVP_PKEY_new failed");
goto safe_exit;
}
if ((result = EVP_PKEY_set1_RSA(evpKey, rsa)) != 1) {
ERR("EVP_PKEY_set1_RSA failed");
goto safe_exit;
}
EVP_MD_CTX_init(&ctx);
// SHA256签名
if (result == 1 && (result = EVP_SignInit_ex(&ctx,
EVP_sha256(), NULL)) != 1) {
ERR("EVP_SignInit_ex failed");
}
if (result == 1 && (result = EVP_SignUpdate(&ctx,
content.c_str(), content.size())) != 1) {
ERR("EVP_SignUpdate failed");
}
size = EVP_PKEY_size(evpKey);
sign = (char*)malloc(size+1);
memset(sign, 0, size+1);
if (result == 1 && (result = EVP_SignFinal(&ctx,
(unsigned char*)sign,
&size, evpKey)) != 1) {
ERR("EVP_SignFinal failed");
}
if (result == 1) {
verify = true;
} else {
ERR("verify failed");
}
signStr = base64_encode((const unsigned char*)sign, size);
EVP_MD_CTX_cleanup(&ctx);
free(sign);
safe_exit:
if (rsa != NULL) {
RSA_free(rsa);
rsa = NULL;
}
if (evpKey != NULL) {
EVP_PKEY_free(evpKey);
evpKey = NULL;
}
if (bufio != NULL) {
BIO_free_all(bufio);
bufio = NULL;
}
return signStr;
}
string getSignContent(map<string, string> params){
map<string, string>::iterator iter;
string content;
for(iter = params.begin(); iter != params.end(); iter++) {
content.append("&").append(iter->first + "=" + iter->second);
}
return content.substr(1);
}
void ERR(const string &msg) {
throw msg;
}
}

View File

@@ -0,0 +1,30 @@
#ifndef SDK_CXX_SIGN_H
#define SDK_CXX_SIGN_H
#include <map>
#include <iostream>
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string>
using namespace std;
namespace signutil {
string createSign(map<string, string> params, const string& privateKeyFilepath, const string& signType);
string sign(const string& content, const string& privateKeyFilepath, const string& hash);
string getSignContent(map<string, string> params);
void ERR(const string &msg);
}
#endif //SDK_CXX_SIGN_H

View File

@@ -0,0 +1,2 @@
#include "stdafx.h"

View File

@@ -0,0 +1,6 @@
#pragma once
#include "targetver.h"

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,174 @@
#include <clocale>
#include "tool.h"
#include <map>
#include <fstream>
#include <sstream>
namespace tool {
bool endWith(const string &str, const string &tail) {
return str.compare(str.size() - tail.size(), tail.size(), tail) == 0;
}
bool startWith(const string &str, const string &head) {
return str.compare(0, head.size(), head) == 0;
}
string getTime() {
time_t timep;
time(&timep);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
return tmp;
}
int parse_url(char *url, char **serverstrp, int *portp, char **pathstrp) {
char buf[256];
int serverlen, numread = 0;
/* go through the url */
/* reset url to point PAST the http:// */
/* assume it's always 7 chars! */
string _url = url;
bool isHttps = startWith(_url, "https");
int len = 7;
if (isHttps) {
len = 8;
}
url = url + len;
/* no http:// now... server is simply up to the next / or : */
sscanf(url, "%255[^/:]", buf);
serverlen = strlen(buf);
*serverstrp = (char *) malloc(serverlen + 1);
strcpy(*serverstrp, buf);
if (url[serverlen] == ':') {
/* get the port */
sscanf(&url[serverlen + 1], "%d%n", portp, &numread);
/* add one to go PAST it */
numread++;
} else {
if (isHttps) {
*portp = 443;
} else {
*portp = 80;
}
}
/* the path is a pointer into the rest of url */
*pathstrp = &url[serverlen + numread];
return 0;
}
std::string url_encode(const std::string &str) {
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++) {
if (isalnum((unsigned char) str[i]) ||
(str[i] == '-') ||
(str[i] == '_') ||
(str[i] == '.') ||
(str[i] == '~'))
strTemp += str[i];
else if (str[i] == ' ')
strTemp += "+";
else {
strTemp += '%';
strTemp += ToHex((unsigned char) str[i] >> 4);
strTemp += ToHex((unsigned char) str[i] % 16);
}
}
return strTemp;
}
std::string url_decode(const std::string &str) {
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++) {
if (str[i] == '+') strTemp += ' ';
else if (str[i] == '%') {
assert(i + 2 < length);
unsigned char high = FromHex((unsigned char) str[++i]);
unsigned char low = FromHex((unsigned char) str[++i]);
strTemp += high * 16 + low;
} else strTemp += str[i];
}
return strTemp;
}
unsigned char ToHex(unsigned char x) {
return x > 9 ? x + 55 : x + 48;
}
unsigned char FromHex(unsigned char x) {
unsigned char y;
if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
else if (x >= '0' && x <= '9') y = x - '0';
else
assert(0);
return y;
}
string mapToJson(std::map<string, string> map_info) {
// Json::Value jObject;
// for (map<string, string>::const_iterator iter = map_info.begin( ); iter != map_info.end( ); ++iter)
// {
// jObject[iter->first] = iter->second;
// }
// return jObject.toStyledString();
return "{}";
}
string getFilename(string filepath) {
{
if (filepath.empty()) {
return "";
}
std::string::size_type iPos;
#ifdef Q_OS_WIN
iPos = strFullName.find_last_of('\\') + 1;
#else
iPos = filepath.find_last_of('/') + 1;
#endif
return filepath.substr(iPos, filepath.length() - iPos);
}
}
string getFileContent(string filepath) {
ifstream fin(filepath);
stringstream buffer;
buffer << fin.rdbuf();
string fileContent(buffer.str());
fin.close();
return fileContent;
}
std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew)
{
std::string strContent, strTemp;
strContent.assign( pszSrc );
std::string::size_type nPos = 0;
while( true )
{
nPos = strContent.find(pszOld, nPos);
strTemp = strContent.substr(nPos+strlen(pszOld), strContent.length());
if ( nPos == std::string::npos )
{
break;
}
strContent.replace(nPos,strContent.length(), pszNew );
strContent.append(strTemp);
nPos +=strlen(pszNew) - strlen(pszOld)+1; //防止重复替换 避免死循环
}
return strContent;
}
}

View File

@@ -0,0 +1,52 @@
#ifndef SDK_CXX_TOOL_H
#define SDK_CXX_TOOL_H
#include <string>
#include <map>
using namespace std;
namespace tool {
bool endWith(const string &str, const string &tail);
bool startWith(const string &str, const string &head);
string getTime();
int parse_url(char *url, char **serverstrp, int *portp, char **pathstrp);
std::string url_encode(const std::string &szToEncode);
std::string url_decode(const std::string &SRC);
unsigned char ToHex(unsigned char x);
unsigned char FromHex(unsigned char x);
string mapToJson(std::map<string, string> m);
string getFilename(string filepath);
string getFileContent(string filepath);
/**
* 函数:
* replace替换字符串
* 参数:
* pszSrc源字符串
* pszOld需要替换的字符串
* pszNew新字符串
* 返回值:
* 返回替换后的字符串
* 备注:
* 需要添加#include <string>头文件
* ssdwujianhua 2017/08/30
*/
std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew);
}
#endif //SDK_CXX_TOOL_H

41
sop-sdk/sdk-c++/main.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include <iostream>
#include "common/OpenClient.h"
#include "request/BaseRequest.h"
#include "request/MemberInfoGetRequest.hpp"
// 应用ID
string appId = "2020051325943082302177280";
// 存放私钥的文件路径
string privateKeyFile = "/Users/thc/IdeaProjects/opc/opc-sdk/sdk-c++/privateEx.pem";
// 请求接口
string url = "http://localhost:7071/prod/gw68uy85";
OpenClient openClient(appId, privateKeyFile, url);
int main() {
// 创建请求
MemberInfoGetRequest request;
// 业务参数
map<string, string> bizModel;
bizModel["name"] = "jim";
bizModel["age"] = "22";
bizModel["address"] = "xx";
request.bizModel = bizModel;
// 添加上传文件
// request->setFiles({
// FileInfo{"aa", "/Users/thc/IdeaProjects/opc/opc-sdk/sdk-c++/aa.txt"},
// FileInfo{"bb", "/Users/thc/IdeaProjects/opc/opc-sdk/sdk-c++/bb.txt"}
// });
// 发送请求
neb::CJsonObject jsonObj = openClient.execute(&request);
std::cout << jsonObj.ToString() << std::endl;
std::cout << "id:" << jsonObj["id"].ToString() << std::endl;
std::cout << "is_vip:" << jsonObj["member_info"]["is_vip"].ToString() << std::endl;
return 0;
}

View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCHJlAPN+1dCbgc3HiahQkT2W/skecGWOCkSX4CPvEc8oIk6544
xihEwShHnfrapiQdF2fndv5agrhg4FyOHheST42L5MnCk+4Km+mWm5GDvmFS7Sa2
aZ5o3regY0MUoJ7D74dYjE3UYFuTujAXiXjGpAwa9qOcKotov5LCkSfUeQIDAQAB
AoGAB1cyw8LYRQSHQCUO9Wiaq730jPNHSrJW4EGAIz/XMYjv/fCgx0lnDEX4CbzI
UGoz/bME4R721YRyXoutJ0h14/cGrt/TEn/TMI0xnISzJHr8VSlyBkQEdfO/W3LO
qjs/UYq2Bz4+kJROJHreM+7d5hiIWLzLBlyI8cSU92ySmHECQQDwju2SoRu88kQP
1qr4seZyKQa8DHTVyCoa6LtPLXyJsdgWgY4KyqJHwMUumEC2Zhhu833CR0ZXbfta
uQDmwAVJAkEAj9M225jrPasaD5vPO7thxtEqgV4F/ZyNKH0Z8bDH27KaKkQ+8GMt
kxwKVckZXs2bMvg/6tCiDZkWAxawNrvFsQJBANmTrPWOmpQPW9gnhYRjA9gFm33C
lno2DT9BeQloTtgL7zKMA3lnRdg4VyCJvR48waS4vupVpR228D1iT5pl22ECQF1M
JUzkcM0rPheb+h2EW1QOgWU0Keyvbj4ykO7gv3T78dezN6TWoUzJpsapUiTWeXPh
6AyZ1FW/1bChOiP3QLECQGAbObmsYlN0bjzPYChwWYeYjErXuv51a44GZCNWinFw
GGiHU9ZAqF8RzmBVW4htwj0j/Yry/V1Sp0uoP0zu3uA=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,3 @@
# SDK for C++
使用方式见main.cpp

View File

@@ -0,0 +1,17 @@
#include "BaseRequest.h"
#include <utility>
vector<FileInfo> BaseRequest::getFiles() {
return this->files;
}
void BaseRequest::addFile(const FileInfo& filepath) {
this->files.push_back(filepath);
}
void BaseRequest::setFiles(vector<FileInfo> files) {
this->files = std::move(files);
}

View File

@@ -0,0 +1,60 @@
#ifndef SDK_CXX_BASEREQUEST_H
#define SDK_CXX_BASEREQUEST_H
#include <string>
#include <map>
#include <vector>
#include "../common/RequestType.h"
using namespace std;
struct FileInfo {
/** 表单名称 */
string name;
/** 文件完整路径 */
string filepath;
};
/**
* 请求类基类,其它请求类需要继承这个类
*/
class BaseRequest {
public:
/**
* 业务参数
*/
map<string, string> bizModel;
/**
* 定义接口名称
* @return 返回接口名称
*/
virtual string getMethod() = 0;
/**
* 定义接口版本号
* @return 返回版本号
*/
virtual string getVersion() = 0;
/**
* 定义请求方式
* @return 返回请求方式
*/
virtual RequestType getRequestType() = 0;
vector<FileInfo> getFiles();
void setFiles(vector<FileInfo> files);
private:
vector<FileInfo> files = {};
void addFile(const FileInfo& filepath);
};
#endif //SDK_CXX_BASEREQUEST_H

View File

@@ -0,0 +1,29 @@
#ifndef SDK_CXX_MEMBERINFOGETREQUEST_HPP
#define SDK_CXX_MEMBERINFOGETREQUEST_HPP
#include <string>
#include "BaseRequest.h"
using namespace std;
class MemberInfoGetRequest : public BaseRequest {
public:
string getMethod() override;
string getVersion() override;
RequestType getRequestType() override;
};
string MemberInfoGetRequest::getMethod() {
return "member.info.get";
}
string MemberInfoGetRequest::getVersion() {
return "1.0";
}
RequestType MemberInfoGetRequest::getRequestType() {
return GET;
}
#endif //SDK_CXX_MEMBERINFOGETREQUEST_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/*******************************************************************************
* Project: neb
* @file CJsonObject.hpp
* @brief Json
* @author bwarliao
* @date: 2014-7-16
* @note
* Modify history:
******************************************************************************/
#ifndef CJSONOBJECT_HPP_
#define CJSONOBJECT_HPP_
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <string>
#include <map>
#include <list>
#ifdef __cplusplus
extern "C" {
#endif
#include "cJSON.h"
#ifdef __cplusplus
}
#endif
namespace neb
{
class CJsonObject
{
public: // method of ordinary json object or json array
CJsonObject();
CJsonObject(const std::string& strJson);
CJsonObject(const CJsonObject* pJsonObject);
CJsonObject(const CJsonObject& oJsonObject);
virtual ~CJsonObject();
CJsonObject& operator=(const CJsonObject& oJsonObject);
bool operator==(const CJsonObject& oJsonObject) const;
bool Parse(const std::string& strJson);
void Clear();
bool IsEmpty() const;
bool IsArray() const;
std::string ToString() const;
std::string ToFormattedString() const;
const std::string& GetErrMsg() const
{
return(m_strErrMsg);
}
public: // method of ordinary json object
bool AddEmptySubObject(const std::string& strKey);
bool AddEmptySubArray(const std::string& strKey);
bool GetKey(std::string& strKey);
void ResetTraversing();
CJsonObject& operator[](const std::string& strKey);
std::string operator()(const std::string& strKey) const;
bool Get(const std::string& strKey, CJsonObject& oJsonObject) const;
bool Get(const std::string& strKey, std::string& strValue) const;
bool Get(const std::string& strKey, int32& iValue) const;
bool Get(const std::string& strKey, uint32& uiValue) const;
bool Get(const std::string& strKey, int64& llValue) const;
bool Get(const std::string& strKey, uint64& ullValue) const;
bool Get(const std::string& strKey, bool& bValue) const;
bool Get(const std::string& strKey, float& fValue) const;
bool Get(const std::string& strKey, double& dValue) const;
bool IsNull(const std::string& strKey) const;
bool Add(const std::string& strKey, const CJsonObject& oJsonObject);
bool Add(const std::string& strKey, const std::string& strValue);
bool Add(const std::string& strKey, int32 iValue);
bool Add(const std::string& strKey, uint32 uiValue);
bool Add(const std::string& strKey, int64 llValue);
bool Add(const std::string& strKey, uint64 ullValue);
bool Add(const std::string& strKey, bool bValue, bool bValueAgain);
bool Add(const std::string& strKey, float fValue);
bool Add(const std::string& strKey, double dValue);
bool AddNull(const std::string& strKey); // add null like this: "key":null
bool Delete(const std::string& strKey);
bool Replace(const std::string& strKey, const CJsonObject& oJsonObject);
bool Replace(const std::string& strKey, const std::string& strValue);
bool Replace(const std::string& strKey, int32 iValue);
bool Replace(const std::string& strKey, uint32 uiValue);
bool Replace(const std::string& strKey, int64 llValue);
bool Replace(const std::string& strKey, uint64 ullValue);
bool Replace(const std::string& strKey, bool bValue, bool bValueAgain);
bool Replace(const std::string& strKey, float fValue);
bool Replace(const std::string& strKey, double dValue);
bool ReplaceWithNull(const std::string& strKey); // replace value with null
public: // method of json array
int GetArraySize();
CJsonObject& operator[](unsigned int uiWhich);
std::string operator()(unsigned int uiWhich) const;
bool Get(int iWhich, CJsonObject& oJsonObject) const;
bool Get(int iWhich, std::string& strValue) const;
bool Get(int iWhich, int32& iValue) const;
bool Get(int iWhich, uint32& uiValue) const;
bool Get(int iWhich, int64& llValue) const;
bool Get(int iWhich, uint64& ullValue) const;
bool Get(int iWhich, bool& bValue) const;
bool Get(int iWhich, float& fValue) const;
bool Get(int iWhich, double& dValue) const;
bool IsNull(int iWhich) const;
bool Add(const CJsonObject& oJsonObject);
bool Add(const std::string& strValue);
bool Add(int32 iValue);
bool Add(uint32 uiValue);
bool Add(int64 llValue);
bool Add(uint64 ullValue);
bool Add(int iAnywhere, bool bValue);
bool Add(float fValue);
bool Add(double dValue);
bool AddNull(); // add a null value
bool AddAsFirst(const CJsonObject& oJsonObject);
bool AddAsFirst(const std::string& strValue);
bool AddAsFirst(int32 iValue);
bool AddAsFirst(uint32 uiValue);
bool AddAsFirst(int64 llValue);
bool AddAsFirst(uint64 ullValue);
bool AddAsFirst(int iAnywhere, bool bValue);
bool AddAsFirst(float fValue);
bool AddAsFirst(double dValue);
bool AddNullAsFirst(); // add a null value
bool Delete(int iWhich);
bool Replace(int iWhich, const CJsonObject& oJsonObject);
bool Replace(int iWhich, const std::string& strValue);
bool Replace(int iWhich, int32 iValue);
bool Replace(int iWhich, uint32 uiValue);
bool Replace(int iWhich, int64 llValue);
bool Replace(int iWhich, uint64 ullValue);
bool Replace(int iWhich, bool bValue, bool bValueAgain);
bool Replace(int iWhich, float fValue);
bool Replace(int iWhich, double dValue);
bool ReplaceWithNull(int iWhich); // replace with a null value
private:
CJsonObject(cJSON* pJsonData);
private:
cJSON* m_pJsonData;
cJSON* m_pExternJsonDataRef;
cJSON* m_pKeyTravers;
std::string m_strErrMsg;
std::map<unsigned int, CJsonObject*> m_mapJsonArrayRef;
std::map<std::string, CJsonObject*> m_mapJsonObjectRef;
};
}
#endif /* CJSONHELPER_HPP_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#include <stdint.h>
typedef int int32;
typedef unsigned int uint32;
#ifndef _WIN32
#if __WORDSIZE == 64
typedef long int64;
typedef unsigned long uint64;
#endif
#else
typedef long long int64;
typedef unsigned long long uint64;
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Int 3
#define cJSON_Double 4
#define cJSON_String 5
#define cJSON_Array 6
#define cJSON_Object 7
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON
{
struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int64 valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
int sign; /* sign of valueint, 1(unsigned), -1(signed) */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks
{
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array, int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr();
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull();
extern cJSON *cJSON_CreateTrue();
extern cJSON *cJSON_CreateFalse();
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateDouble(double num, int sign);
extern cJSON *cJSON_CreateInt(uint64 num, int sign);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray();
extern cJSON *cJSON_CreateObject();
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(int *numbers, int sign, int count);
extern cJSON *cJSON_CreateFloatArray(float *numbers, int count);
extern cJSON *cJSON_CreateDoubleArray(double *numbers, int count);
extern cJSON *cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToArrayHead(cJSON *array, cJSON *item); /* add by Bwar on 2015-01-28 */
extern void cJSON_AddItemToObject(cJSON *object, const char *string,
cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string,
cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
extern void cJSON_DeleteItemFromArray(cJSON *array, int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string,
cJSON *newitem);
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,103 @@
//
// base64.cpp
// CPPWork
//
// Created by cocoa on 16/8/5.
// Copyright © 2016年 cc. All rights reserved.
//
#include "base64.h"
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string 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_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
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];
}
return ret;
}

10
sop-sdk/sdk-c++/thirdparty/base64/base64.h vendored Executable file
View File

@@ -0,0 +1,10 @@
#ifndef base64_h
#define base64_h
#include <string>
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
std::string base64_decode(std::string const& encoded_string);
#endif /* base64_h */