1 cocos2dx自带base64
#include <base/base64.h>
std::string OpensslTool::baseBase64Decode(const char *in)
{
int inLen = strlen(in);
unsigned char *out ;
int outLen = cocos2d::base64Decode((const unsigned char*)in, inLen, &out);
std::string retStr((char*)out);
if (out)
free(out);
return retStr.c_str();
}
std::string OpensslTool::baseBase64Encode(const char *in )
{
int inLen = strlen(in);
char* out;
int outLen = cocos2d::base64Encode((const unsigned char*)in, inLen, &out);
std::string retStr(out);
if (out) {
free(out);
}
return retStr.c_str();
}
2, bio编码解码
#include <openssl/evp.h>
std::string OpensslTool::bioBase64Encode(const char *in)
{
int len = strlen(in);
char* out;
int outLen = this->bioBase64Encode(in, len, &out);
std::string retStr(out);
if (out) {
delete[] out;
}
return retStr;
}
int OpensslTool::bioBase64Encode(const char *in, int inLen, char **out)
{
int outLen = 0;
//1 创建b64类型bio
BIO* b64 = BIO_new(BIO_f_base64());
// 创建 mem类型bio
BIO* bmem = BIO_new(BIO_s_mem());
BUF_MEM* bptr = NULL;
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
//2 构建bio链 b64 ->mem
BIO_push(b64, bmem);
//3 write操作 从前往后 b64编码->mem
BIO_write(b64, in, inLen);
BIO_flush(b64);
//4 取出mem数据
BIO_get_mem_ptr(b64, &bptr);
outLen = bptr->length;
*out = new char[outLen+1];
memcpy(*out,bptr->data, outLen);
out[outLen] = 0;
BIO_free_all(b64);
return outLen;
}
std::string OpensslTool::bioBase64Decode(const char *in)
{
int len = strlen(in);
char* out;
int outLen = this->bioBase64Decode(in, len, &out);
std::string retStr(out);
if (out) {
delete[] out;
}
return retStr;
}
int OpensslTool::bioBase64Decode( const char *in, int inLen, char **out )
{
BIO* b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
// 1 把数据存入mem类型bio
BIO* bmem = BIO_new_mem_buf(in, inLen);//创建一个只读型bio(速度更快)
// 2 构建bio链 b64 -> mem
BIO_push(b64, bmem);
*out = new char[inLen+1];
memset(*out, 0, inLen+1);
// 3 read操作 将从后往前执行 mem->b64解码->out
BIO_read(b64, *out, inLen);
//4 释放链
BIO_free_all(bmem);
return inLen;
}
3,evp编码解码
#include <openssl/evp.h>
std::string OpensslTool::evpBase64Encode(const char* in)
{
int inLen = strlen(in);
unsigned char* inBuffer = new unsigned char[inLen];
memcpy(inBuffer, in, inLen);
int decodeLen = inLen*2+1;
unsigned char* decodeBuffer = new unsigned char[decodeLen];
memset(decodeBuffer, 0, decodeLen);
int outLen;
EVP_ENCODE_CTX* ctx;
ctx = EVP_ENCODE_CTX_new();
EVP_EncodeInit(ctx);
EVP_EncodeUpdate(ctx, decodeBuffer, &outLen, inBuffer, inLen);
int tempLen;
EVP_EncodeFinal(ctx, decodeBuffer, &tempLen);
outLen += tempLen;
char* out = new char[outLen+1];
memcpy(out, decodeBuffer, outLen+1);
out[outLen] = 0;
std::string retStr(out);
delete []inBuffer;
delete []decodeBuffer;
delete []out;
EVP_cleanup();
return retStr.c_str();
}
std::string OpensslTool::evpBase64Decode(const char*in)
{
int inLen = strlen(in);
unsigned char* inBuffer = new unsigned char[inLen];
memcpy(inBuffer, in, inLen);
int decodeLen = (((inLen+2)/4)*3)+1;
unsigned char* decodeBuffer = new unsigned char[decodeLen];
memset(decodeBuffer, 0, decodeLen);
int outLen;
EVP_ENCODE_CTX* ctx;
ctx = EVP_ENCODE_CTX_new();
EVP_DecodeInit(ctx);
EVP_DecodeUpdate(ctx, decodeBuffer, &outLen, inBuffer, inLen);
int tempLen;
EVP_DecodeFinal(ctx, decodeBuffer, &tempLen);
outLen += tempLen;
char* out = new char[outLen];
memcpy(out, decodeBuffer, outLen);
std::string retStr(out);
delete []inBuffer;
delete []decodeBuffer;
delete []out;
return retStr.c_str();
}
遇到的问题
1,api需要的参数基本都是unsigned char*类型,返回类型也有些是unsigned char*,最开始我是直接将char*强转为unsigned char*,然后返回unsigned char* 强转为char*,结果发现总有些数据返回不对。后来改成用memcpy直接复制,ok了。大致猜测是char*遇到\0就停止了
2,最开始写的时候,new空间使用的是固定值,导致数据超出我预设值时出错,后来改为动态申请了
3,EVP_ENCODE_CTX 网上找的资料用的不是指针,但是我这边会提示错误,提示Variable has incomplete type 'EVP_ENCODE_CTX' (aka 'evp_Encode_Ctx_st'),所以我这里改为指针了(evp.h里其他 结构体也会有这个错误提示,一样改为指针)
4,返回的unsigned char* 转char*时,可能需要补0