
c++ 实现阿里云短信服务接口不使用第三方库
发布日期:2021-05-10 05:47:03
浏览次数:30
分类:原创文章
本文共 6897 字,大约阅读时间需要 22 分钟。
加密类文件在里,本章未用到三方库。参考里用了三方库,有需要的也可以参考。http/https协议皆可。
header为最终参数串,带入报文即可;postman测试通过。ASCII2UTF_8函数相关调用到参考里查找。
std::string getCurentTime() { time_t _t = time(NULL); char bufTime[64] = { 0 }; struct tm _tt; //localtime_s(&_tt, &_t);//系统本地时间 gmtime_s(&_tt ,&_t);//格林时间 _tt.tm_year += 1900; _tt.tm_mon += 1; sprintf_s(bufTime, 64,"%04d-%02d-%02dT%02d:%02d:%02dZ" , _tt.tm_year, _tt.tm_mon, _tt.tm_mday, _tt.tm_hour, _tt.tm_min, _tt.tm_sec); return std::string(bufTime); } unsigned char ToHex(unsigned char x) { return x > 9 ? x + 55 : x + 48; } std::string getUUID() {#ifdef WIN32 char buffer[BYTE_64] = { 0 }; GUID guid; if (CoCreateGuid(&guid)) { fprintf(stderr, "create guid error\n"); return ""; } _snprintf_s(buffer, BYTE_64, "%08X%04X%04x%02X%02X%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); printf("guid: %s\n", buffer); return std::string(buffer);#else uuid_t uuid; uuid_generate(uuid); char buf[64] = { 0 }; uuid_unparse(uuid, buf); return std::string(buf);#endif }; std::string specialUrlEncode(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; } //ascii to Utf8 std::string ASCII2UTF_8(std::string& strAsciiCode) {#ifdef WIN32 std::string strRet(""); // std::wstring wstr = Acsi2WideByte(strAsciiCode); // strRet = Unicode2Utf8(wstr); return strRet;#endif#ifdef __linux__ char lpszBuf[256] = { 0 }; k2u(const_cast<char*>(strAsciiCode.c_str()), strAsciiCode.size(), lpszBuf, 256); return std::string(lpszBuf); // char lpszBuf[256]={0}; // a2u(const_cast<char*>(strAsciiCode.c_str()),strAsciiCode.size(),lpszBuf,256); // return std::string(lpszBuf); // return std::string(strAsciiCode);#endif };
struct HttpMsgArg { HttpMsgArg() : addr_("dysmsapi.aliyuncs.com") , AccessKeyId(ACCESS_KEY_ID) , AccessKeySecret(ACCESS_KEY_SECRET) , Timestamp("2018-04-13T10:10:10Z") , Format("JSON") , SignatureMethod("HMAC-SHA1") , SignatureVersion("1.0") , SignatureNonce("1") , Signature("") // , Action("SendSms") , Version("2017-05-25") , RegionId("cn-hangzhou") , PhoneNumbers("17090833800") , SignName("阿里云短信测试专用")//阿里云短信测试专用 , TemplateCode("SMS_105240742")//SMS_105240742 , TemplateParam("") //, SmsUpExtendCode("") //, OutId("123") { }; // std::string addr_; // web 服务器地址 // std::string AccessKeyId; // std::string AccessKeySecret; // std::string Timestamp; //格式为:yyyy-MM-dd’T’HH:mm:ss’Z’;时区为:GMT std::string Format; //没传默认为JSON,可选填值:XML std::string SignatureMethod; //建议固定值:HMAC-SHA1 std::string SignatureVersion; //建议固定值:1.0 std::string SignatureNonce; //用于请求的防重放攻击,每次请求唯一,JAVA语言建议用:java.util.UUID.randomUUID()生成即可 std::string Signature; //最终生成的签名结果值 std::string Action; //API的命名,固定值,如发送短信API的值为:SendSms std::string Version; //API的版本,固定值,如短信API的值为:2017-05-25 std::string RegionId; //API支持的RegionID,如短信API的值为:cn-hangzhou /* *短信接收号码,支持以逗号分隔的形式进行批量调用, *批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟, *验证码类型的短信推荐使用单条调用的方式 */ std::string PhoneNumbers; std::string SignName; //短信签名 std::string TemplateCode; //短信模板ID /* 短信模板变量替换JSON串,友情提示:如果JSON中需要带换行符,请参照标准的JSON协议。 */ std::string TemplateParam; //std::string SmsUpExtendCode; //上行短信扩展码,无特殊需要此字段的用户请忽略此字段 //std::string OutId; //外部流水扩展字段 };
HttpMsgArg myArgHttp; //签名内容缓存 std::string sortQueryStringTmp = ""; sortQueryStringTmp.append("GET&").append(specialUrlEncode("/")); //签名内容项,参数key的字符串排序 myArgHttp.TemplateParam = "{'customer':'test'}"; std::map<std::string, std::string> coder; //acl::url_coder coder;//注意中文字段UTF-8表述 coder.insert(pair<std::string, std::string>("AccessKeyId", myArgHttp.AccessKeyId.c_str())); coder.insert(pair<std::string, std::string>("Action", myArgHttp.Action.c_str())); coder.insert(pair<std::string, std::string>("Format", myArgHttp.Format.c_str())); //coder.insert(pair<std::string, std::string>("OutId", myArgHttp.OutId.c_str())); coder.insert(pair<std::string, std::string>("PhoneNumbers", myArgHttp.PhoneNumbers.c_str())); coder.insert(pair<std::string, std::string>("RegionId", myArgHttp.RegionId.c_str())); coder.insert(pair<std::string, std::string>("SignName", ASCII2UTF_8(myArgHttp.SignName).c_str())); coder.insert(pair<std::string, std::string>("SignatureMethod", myArgHttp.SignatureMethod.c_str())); coder.insert(pair<std::string, std::string>("SignatureNonce", getUUID().c_str())); coder.insert(pair<std::string, std::string>("SignatureVersion", myArgHttp.SignatureVersion.c_str())); coder.insert(pair<std::string, std::string>("TemplateCode", myArgHttp.TemplateCode.c_str())); coder.insert(pair<std::string, std::string>("TemplateParam", ASCII2UTF_8(myArgHttp.TemplateParam).c_str())); coder.insert(pair<std::string, std::string>("Timestamp", getCurentTime().c_str())); coder.insert(pair<std::string, std::string>("Version", myArgHttp.Version.c_str())); // int index = 1; std::string urlcodeadd; std::map<std::string, std::string>::iterator mapitem = coder.begin(); for (; mapitem != coder.end(); mapitem++, ++index) { urlcodeadd.append(mapitem->first).append("=").append(specialUrlEncode(mapitem->second)); if (index != coder.size()) urlcodeadd.append("&"); } //printf("排序参数集:\r\n%s\r\n", urlcodeadd.c_str()); sortQueryStringTmp.append("&").append(specialUrlEncode(urlcodeadd)); //printf("待签名的请求字符串specialUrlEncode:\r\n%s\r\n", sortQueryStringTmp.c_str()); //生成签名,调用签名算法函数,注意阿里的AccessKeySecret+&才是真正的AccessKeySecret int hmaclen = 20; char hmac_buf[32] = { 0 }; std::string KeySecret_ali = (myArgHttp.AccessKeySecret + "&"); hmac_sha((char*)(ASCII2UTF_8(KeySecret_ali)).c_str(), (int)KeySecret_ali.length() , (char*)ASCII2UTF_8(sortQueryStringTmp).c_str(), (int)sortQueryStringTmp.length(), hmac_buf, hmaclen); std::string hmac = std::string(hmac_buf, hmaclen); printf("密钥+HmacSHA1算法:\r\n%s\r\n", hmac.c_str()); //printf("%s\n", get_slip_time_milliseconds()); //base64算法调用,前面签名算法结果作为输入参数,得到最终签名 unsigned char hmacbase64[29] = {0}; //base64_encode((const unsigned char*)hmac.c_str(), static_cast<int>(hmac.length()), hmacbase64); hmac = Base64::Encode((const unsigned char*)hmac.c_str(), static_cast<int>(hmac.length())); printf("HmacSHA1算法+Base64:\r\n%s\r\n", hmacbase64); //将签名加入请求字段 std::string header="?"; header += urlcodeadd; header += "&Signature="; header += specialUrlEncode((char*)hmacbase64); printf("header:\r\n%s\r\n", header.c_str());
有问题请留言。。。
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年03月30日 22时39分17秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
静态数组类的封装(泛型)
2021-05-10
操作记录-2021-03-15: sunxiaoyu_project
2021-05-10
Android DEX加固方案与原理
2021-05-10
Android Retrofit2.0 上传单张图片和多张图片
2021-05-10
android 常用的代码
2021-05-10
vue 导出Excel乱码问题解决方案
2021-05-10
eggjs validate no function 解决方案
2021-05-10
Permission denied 解决方案
2021-05-10
iOS_图片添加水印_文本倾斜
2021-05-10
iOS_Runtime3_动态添加方法
2021-05-10
Docker配置文件
2021-05-10
PNFT邮票数字资产化,科技、美学与价值的完美融合
2021-05-10
5G赋能新文旅 巡天遥看一千河
2021-05-10
Leetcode第557题---翻转字符串中的单词
2021-05-10
IDEA:修改编辑区背景色
2021-05-10
C# WinForm 圆角button
2021-05-10
Problem G. The Stones Game【取石子博弈 & 思维】
2021-05-10
HRBUST—1891 A + B Problem VII
2021-05-10
装饰模式
2021-05-10