Libb64:c/c++實現的base64編碼解碼庫函式
阿新 • • 發佈:2019-01-10
base64編碼解碼本身也不復雜,但要自己寫,還是得花點時間,如果能找到現成的可靠的程式碼,抄來最好,節省了測試的時間。
libb64就是實現base64編碼解碼的開源庫,還提供了C++封裝,用起來也挺方便
下面是使用libb64 C++封裝介面進行base64編碼解碼的呼叫程式碼
/*
* b64_wrapper.h
* Created on: 2016年3月31日
* Author: guyadong
*/
#ifndef INCLUDE_B64_WRAPPER_H_
#define INCLUDE_B64_WRAPPER_H_
#include <vector>
#include <memory>
#include <string>
#include <stdexcept>
#include "b64/encode.h"
#include "b64/decode.h"
#define _DEF_STRING(x) #x
#define DEF_TO_STRING(x) _DEF_STRING(x)
#define SOURCE_AT __FILE__ ":" DEF_TO_STRING(__LINE__)
#define ERROR_STR(msg) std::string(SOURCE_AT ":").append(msg)
#define throw_except_if_msg(except,expression,msg) \
if(expression)\
throw except(ERROR_STR(msg));
#define throw_except_if(except,expression) throw_except_if_msg(except,expression,#expression)
#define throw_if_msg(expression,msg) throw_except_if_msg(std::invalid_argument,expression,msg)
#define throw_if(expression) throw_except_if(std::invalid_argument,expression)
namespace base64{
/* b64異常類 */
class b64_exception:public std::logic_error{
// 繼承基類建構函式
using std::logic_error::logic_error;
};
/* 呼叫libb64對資料進行base64編碼
* input為nullptr或size為0丟擲std::invalid_argument異常
* */
inline std::string encode(const void* input,size_t size){
throw_if(nullptr==input||0==size)
std::vector<char> buffer(size<<1);
encoder ec;
base64_init_encodestate(&ec._state);
// count為base64編碼後的資料長度
auto count=ec.encode(reinterpret_cast<const char*>(input),int(size),buffer.data());
count+=ec.encode_end(buffer.data()+count);
assert(count<=buffer.size());
return std::string(buffer.data(),buffer.data()+count);
}
/* 對資料物件進行base64編碼 */
template<typename T>
inline typename std::enable_if<std::is_class<T>::value,std::string>::type
encode_obj(const T& input){
return encode(std::addressof(input),sizeof(T));
}
/* 對陣列物件進行base64編碼 */
template<typename T>
inline std::string encode_vector(const std::vector<T>& input){
return encode(input.data(),input.size()*sizeof(T));
}
/* 呼叫libb64對base64編碼的字串進行解碼,返回解碼後的二進位制陣列
* input為空丟擲std::invalid_argument異常
* */
inline std::vector<uint8_t> decode(const std::string&input){
throw_if(input.empty())
std::vector<uint8_t> buffer(input.size());
decoder dc;
base64_init_decodestate(&dc._state);
// count為base64解碼後的資料長度
auto count=dc.decode(input.data(),int(input.size()),reinterpret_cast<char*>(buffer.data()));
assert(count<=buffer.size());
return std::vector<uint8_t>(buffer.data(),buffer.data()+count);
}
/* 將base64字串解碼為物件資料 */
template<typename T>
inline typename std::enable_if<std::is_class<T>::value,T>::type
decode_obj(const std::string&input){
auto decoded_data=decode(input);
throw_except_if_msg(b64_exception,decoded_data.size()!=sizeof(T),"decode data is invalid obj for T")
return reinterpret_cast<T&>(decoded_data.data());
}
/* 將base64字串解碼為陣列 */
template<typename T>
inline std::vector<T> decode_vector(const std::string&input){
auto decoded_data=decode(input);
throw_except_if_msg(b64_exception,0!=decoded_data.size()%sizeof(T),"decode data is invalid obj for std::vector<T>")
auto p=reinterpret_cast<T*>(decoded_data.data());
return std::vector<T>(p,p+decoded_data.size()/sizeof(T));
}
} /* namespace base64 */
#endif /* INCLUDE_B64_WRAPPER_H_ */