首页 > 编程语言 >65、记录使用科大讯飞的声纹识别从官方的Python Demo转C++ Demo路程

65、记录使用科大讯飞的声纹识别从官方的Python Demo转C++ Demo路程

时间:2022-10-16 22:37:06浏览次数:81  
标签:std string Python Demo C++ str doc SHA256 rapidjson


基本思想:需要将声纹识别的demo集成到项目中,奈何官方只提供了py版本和java版本,需要c++版本,逐开发和记录一下,只是简单复现其py代码

一、官方代码的和手册的地址

65、记录使用科大讯飞的声纹识别从官方的Python Demo转C++ Demo路程_文件路径

 这里将py代码贴一下

import base64
import hashlib
import hmac
import json
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time

import requests


# 填写在开放平台申请的APPID、APIKey、APISecret
# 相应编码音频base64编码后数据(不超过4M)


class Gen_req_url(object):
"""生成请求的url"""

def sha256base64(self, data):
sha256 = hashlib.sha256()
sha256.update(data)
digest = base64.b64encode(sha256.digest()).decode(encoding='utf-8')
return digest

def parse_url(self, requset_url):
stidx = requset_url.index("://")
host = requset_url[stidx + 3:]
# self.schema = requset_url[:stidx + 3]
edidx = host.index("/")
if edidx <= 0:
raise Exception("invalid request url:" + requset_url)
self.path = host[edidx:]
self.host = host[:edidx]

# build websocket auth request url
def assemble_ws_auth_url(self, requset_url, api_key, api_secret, method="GET"):
self.parse_url(requset_url)
now = datetime.now()
date = format_date_time(mktime(now.timetuple()))
#date = "Wed, 12 Oct 2022 09:22:43 GMT"
signature_origin = "host: {}\ndate: {}\n{} {} HTTP/1.1".format(self.host, date, method, self.path)
signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'),
digestmod=hashlib.sha256).digest()
print(hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'),
digestmod=hashlib.sha256).hexdigest())
signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
api_key, "hmac-sha256", "host date request-line", signature_sha)
print(authorization_origin)
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
values = {
"host": self.host,
"date": date,
"authorization": authorization
}
x=requset_url + "?" + urlencode(values)
print(x)
return x


def gen_req_body(apiname, APPId, file_path=None):
"""
生成请求的body
:param apiname
:param APPId: Appid
:param file_name: 文件路径
:return:
"""
if apiname == 'createFeature':

with open(file_path, "rb") as f:
audioBytes = f.read()
body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "createFeature",
"groupId": "iFLYTEK_examples_groupId",
"featureId": "iFLYTEK_examples_featureId",
"featureInfo": "iFLYTEK_examples_featureInfo",
"createFeatureRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
},
"payload": {
"resource": {
"encoding": "lame",
"sample_rate": 16000,
"channels": 1,
"bit_depth": 16,
"status": 3,
"audio": str(base64.b64encode(audioBytes), 'UTF-8')
}
}
}
elif apiname == 'createGroup':

body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "createGroup",
"groupId": "iFLYTEK_examples_groupId",
"groupName": "iFLYTEK_examples_groupName",
"groupInfo": "iFLYTEK_examples_groupInfo",
"createGroupRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
}
}
elif apiname == 'deleteFeature':

body = {
"header": {
"app_id": APPId,
"status": 3

},
"parameter": {
"s782b4996": {
"func": "deleteFeature",
"groupId": "iFLYTEK_examples_groupId",
"featureId": "iFLYTEK_examples_featureId",
"deleteFeatureRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
}
}
elif apiname == 'queryFeatureList':

body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "queryFeatureList",
"groupId": "iFLYTEK_examples_groupId",
"queryFeatureListRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
}
}
elif apiname == 'searchFea':

with open(file_path, "rb") as f:
audioBytes = f.read()
body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "searchFea",
"groupId": "iFLYTEK_examples_groupId",
"topK": 1,
"searchFeaRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
},
"payload": {
"resource": {
"encoding": "lame",
"sample_rate": 16000,
"channels": 1,
"bit_depth": 16,
"status": 3,
"audio": str(base64.b64encode(audioBytes), 'UTF-8')
}
}
}
elif apiname == 'searchScoreFea':

with open(file_path, "rb") as f:
audioBytes = f.read()
body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "searchScoreFea",
"groupId": "iFLYTEK_examples_groupId",
"dstFeatureId": "iFLYTEK_examples_featureId",
"searchScoreFeaRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
},
"payload": {
"resource": {
"encoding": "lame",
"sample_rate": 16000,
"channels": 1,
"bit_depth": 16,
"status": 3,
"audio": str(base64.b64encode(audioBytes), 'UTF-8')
}
}
}
elif apiname == 'updateFeature':

with open(file_path, "rb") as f:
audioBytes = f.read()
body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "updateFeature",
"groupId": "iFLYTEK_examples_groupId",
"featureId": "iFLYTEK_examples_featureId",
"featureInfo": "iFLYTEK_examples_featureInfo_update",
"updateFeatureRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
},
"payload": {
"resource": {
"encoding": "lame",
"sample_rate": 16000,
"channels": 1,
"bit_depth": 16,
"status": 3,
"audio": str(base64.b64encode(audioBytes), 'UTF-8')
}
}
}
elif apiname == 'deleteGroup':
body = {
"header": {
"app_id": APPId,
"status": 3
},
"parameter": {
"s782b4996": {
"func": "deleteGroup",
"groupId": "iFLYTEK_examples_groupId",
"deleteGroupRes": {
"encoding": "utf8",
"compress": "raw",
"format": "json"
}
}
}
}
else:
raise Exception(
"输入的apiname不在[createFeature, createGroup, deleteFeature, queryFeatureList, searchFea, searchScoreFea,updateFeature]内,请检查")
return body


def req_url(api_name, APPId, APIKey, APISecret, file_path=None):
"""
开始请求
:param APPId: APPID
:param APIKey: APIKEY
:param APISecret: APISecret
:param file_path: body里的文件路径
:return:
"""
gen_req_url = Gen_req_url()
body = gen_req_body(apiname=api_name, APPId=APPId, file_path=file_path)
bodystr = json.dumps(body)
print("body=",body)
print("bodystr=",bodystr)
#https://www.sojson.com/ 添加转移字符
request_url = gen_req_url.assemble_ws_auth_url(requset_url='https://api.xf-yun.com/v1/private/s782b4996', method="POST", api_key=APIKey, api_secret=APISecret)
print(request_url)
headers = {'content-type': "application/json", 'host': 'api.xf-yun.com', 'appid': '$APPID'}
response = requests.post(request_url, data=json.dumps(body), headers=headers)
tempResult = json.loads(response.content.decode('utf-8'))
print(tempResult)


"""
* 1.声纹识别接口,请填写在讯飞开放平台-控制台-对应能力页面获取的APPID、APIKey、APISecret
* 2.groupId要先创建,然后再在createFeature里使用,不然会报错23005,修改时需要注意保持统一
* 3.音频base64编码后数据(不超过4M),音频格式需要16K、16BIT的MP3音频。
* 4.主函数只提供调用示例,其他参数请到对应类去更改,以适应实际的应用场景。
"""

if __name__ == '__main__':
APPId = "sxj"
APISecret = "sxj"
APIKey = "sxj"
file_path = '0.mp3'
# apiname取值:
# 1.创建声纹特征库 createGroup
# 2.添加音频特征 createFeature
# 3.查询特征列表 queryFeatureList
# 4.特征比对1:1 searchScoreFea
# 5.特征比对1:N searchFea
# 6.更新音频特征 updateFeature
# 7.删除指定特征 deleteFeature
# 8.删除声纹特征库 deleteGroup
req_url(api_name='createFeature', APPId=APPId,
APIKey=APIKey, APISecret=APISecret, file_path=file_path)

填入对应的APPId、 APISecret、 APIKey,返回结果

{'header': {'code': 0, 'message': 'success', 'sid': '**@***'}, 'payload': {'createFeatureRes': {'compress': 'raw', 'encoding': 'utf8', 'format': 'json', 'status': '3', 'text': 'eyJmZWF0dXJlSWQiOiJpRkxZVEVLX2V4YW1wbGVzX2ZlYXR1cmVJZCJ9'}}}

二、c++代码复现,自己优化去~

cmakelists.txt

cmake_minimum_required(VERSION 3.16)
project(audio_feature)

set(CMAKE_CXX_STANDARD 14)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(audio_feature main.cpp hmacsha256.cpp hmacsha256.h Base64.cpp Base64.h url.cpp url.h)
target_link_libraries(audio_feature -lcurl)

c++代码的main.cpp函数

#include<stdio.h>
#include<curl/curl.h>
#include "string.h"
#include <locale>
#include <codecvt>
#include <string>
#include <iostream>
#include <fstream>
#include "hmacsha256.h"
#include "Base64.h"
#include "url.h"

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

using namespace rapidjson;

std::string createGroupJson(const char *APPId) {
rapidjson::Document doc;
doc.SetObject();
rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();
rapidjson::Value header(rapidjson::kStringType);
rapidjson::Document header_doc, parameter_doc, s782b4996_doc, createGroupRes_doc;
header_doc.SetObject();
parameter_doc.SetObject();
s782b4996_doc.SetObject();
createGroupRes_doc.SetObject();

rapidjson::Value app_id(rapidjson::kStringType);
std::string app_id_str = APPId;
app_id.SetString(app_id_str.c_str(), app_id_str.length(), allocator);
header_doc.AddMember("app_id", app_id, allocator);
header_doc.AddMember("status", 3, allocator);
doc.AddMember("header", header_doc, allocator);


rapidjson::Value parameter(rapidjson::kStringType);

rapidjson::Value s782b4996(rapidjson::kStringType);

rapidjson::Value func(rapidjson::kStringType);
std::string func_str = "createGroup";
func.SetString(func_str.c_str(), func_str.length(), allocator);
s782b4996_doc.AddMember("func", func, allocator);

rapidjson::Value groupId(rapidjson::kStringType);
std::string groupId_str = "iFLYTEK_examples_groupId";
groupId.SetString(groupId_str.c_str(), groupId_str.length(), allocator);
s782b4996_doc.AddMember("groupId", groupId, allocator);

rapidjson::Value groupName(rapidjson::kStringType);
std::string groupName_str = "iFLYTEK_examples_groupName";
groupName.SetString(groupName_str.c_str(), groupName_str.length(), allocator);
s782b4996_doc.AddMember("groupName", groupName, allocator);

rapidjson::Value groupInfo(rapidjson::kStringType);
std::string groupInfo_str = "iFLYTEK_examples_groupInfo";
groupInfo.SetString(groupInfo_str.c_str(), groupInfo_str.length(), allocator);
s782b4996_doc.AddMember("groupInfo", groupInfo, allocator);

rapidjson::Value encoding(rapidjson::kStringType);
std::string encoding_str = "utf8";
encoding.SetString(encoding_str.c_str(), encoding_str.length(), allocator);
createGroupRes_doc.AddMember("encoding", encoding, allocator);

rapidjson::Value raw(rapidjson::kStringType);
std::string raw_str = "raw";
raw.SetString(raw_str.c_str(), raw_str.length(), allocator);
createGroupRes_doc.AddMember("compress", raw, allocator);

rapidjson::Value json(rapidjson::kStringType);
std::string json_str = "json";
json.SetString(json_str.c_str(), json_str.length(), allocator);
createGroupRes_doc.AddMember("format", json, allocator);


s782b4996_doc.AddMember("createGroupRes", createGroupRes_doc, allocator);
parameter_doc.AddMember("s782b4996", s782b4996_doc, allocator);
doc.AddMember("parameter", parameter_doc, allocator);

rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> write(buffer);
doc.Accept(write);
std::string buf_json_str = buffer.GetString();
return buf_json_str.c_str();

}

void acqure_audio_info(const char *file_path, std::string &readStr, int &audio_length) {
readStr="";
FILE *fp = fopen(file_path, "rb");
char c;
audio_length = -1;
while (!feof(fp)) //我们已在文件的末尾加上结束标志-1
{
c = fgetc(fp);
readStr = readStr + c;
audio_length++;
}
fclose(fp);
}

std::string createFeature(const char *APPId, const char *file_path) {
rapidjson::Document doc;
doc.SetObject();
rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();
rapidjson::Value header(rapidjson::kStringType);
rapidjson::Document header_doc, parameter_doc, s782b4996_doc, createFeatureRes_doc, payload_doc, resource_doc;
header_doc.SetObject();
parameter_doc.SetObject();
s782b4996_doc.SetObject();
createFeatureRes_doc.SetObject();
payload_doc.SetObject();
resource_doc.SetObject();

rapidjson::Value app_id(rapidjson::kStringType);
std::string app_id_str = APPId;
app_id.SetString(app_id_str.c_str(), app_id_str.length(), allocator);
header_doc.AddMember("app_id", app_id, allocator);
header_doc.AddMember("status", 3, allocator);
doc.AddMember("header", header_doc, allocator);


rapidjson::Value parameter(rapidjson::kStringType);

rapidjson::Value s782b4996(rapidjson::kStringType);

rapidjson::Value func(rapidjson::kStringType);
std::string func_str = "createFeature";
func.SetString(func_str.c_str(), func_str.length(), allocator);
s782b4996_doc.AddMember("func", func, allocator);

rapidjson::Value groupId(rapidjson::kStringType);
std::string groupId_str = "iFLYTEK_examples_groupId";
groupId.SetString(groupId_str.c_str(), groupId_str.length(), allocator);
s782b4996_doc.AddMember("groupId", groupId, allocator);

rapidjson::Value groupName(rapidjson::kStringType);
std::string groupName_str = "iFLYTEK_examples_featureId";
groupName.SetString(groupName_str.c_str(), groupName_str.length(), allocator);
s782b4996_doc.AddMember("featureId", groupName, allocator);

rapidjson::Value groupInfo(rapidjson::kStringType);
std::string groupInfo_str = "iFLYTEK_examples_featureInfo";
groupInfo.SetString(groupInfo_str.c_str(), groupInfo_str.length(), allocator);
s782b4996_doc.AddMember("featureInfo", groupInfo, allocator);

rapidjson::Value encoding(rapidjson::kStringType);
std::string encoding_str = "utf8";
encoding.SetString(encoding_str.c_str(), encoding_str.length(), allocator);
createFeatureRes_doc.AddMember("encoding", encoding, allocator);

rapidjson::Value raw(rapidjson::kStringType);
std::string raw_str = "raw";
raw.SetString(raw_str.c_str(), raw_str.length(), allocator);
createFeatureRes_doc.AddMember("compress", raw, allocator);

rapidjson::Value json(rapidjson::kStringType);
std::string json_str = "json";
json.SetString(json_str.c_str(), json_str.length(), allocator);
createFeatureRes_doc.AddMember("format", json, allocator);


rapidjson::Value encoding_(rapidjson::kStringType);
std::string encoding__str = "lame";
encoding_.SetString(encoding__str.c_str(), encoding__str.length(), allocator);
resource_doc.AddMember("encoding", encoding_, allocator);

resource_doc.AddMember("sample_rate", 16000, allocator);
resource_doc.AddMember("channels", 1, allocator);

resource_doc.AddMember("bit_depth", 16, allocator);
resource_doc.AddMember("status", 3, allocator);

std::string readStr="";
int length_audo=-1;
acqure_audio_info(file_path,readStr,length_audo);
std::string audio_info = Base64Encode(reinterpret_cast<const unsigned char *>(readStr.c_str()), length_audo);
rapidjson::Value audio(rapidjson::kStringType);
std::string audio_str = audio_info;
audio.SetString(audio_str.c_str(), audio_str.length(), allocator);
resource_doc.AddMember("audio", audio, allocator);


payload_doc.AddMember("resource", resource_doc, allocator);
doc.AddMember("payload", payload_doc, allocator);
s782b4996_doc.AddMember("createFeatureRes", createFeatureRes_doc, allocator);
parameter_doc.AddMember("s782b4996", s782b4996_doc, allocator);
doc.AddMember("parameter", parameter_doc, allocator);

rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> write(buffer);
doc.Accept(write);
std::string buf_json_str = buffer.GetString();
return buf_json_str.c_str();

}

std::string gen_req_body(const char *apiname, const char *APPId, const char *file_path) {
std::string body;
if (strcmp(apiname, "createGroup") == 0) {
body = createGroupJson(APPId);
} else if (strcmp(apiname, "createFeature") == 0) {
body = createFeature(APPId, file_path);
}

return body;

}

std::string http_gmtime() {
time_t now = time(0);
tm *gmt = gmtime(&now);

// http://en.cppreference.com/w/c/chrono/strftime
// e.g.: Sat, 22 Aug 2015 11:48:50 GMT
// 5+ 3+4+ 5+ 9+ 3 = 29
const char *fmt = "%a, %d %b %Y %H:%M:%S GMT";
char tstr[30];

strftime(tstr, sizeof(tstr), fmt, gmt);

return tstr;
}

void compute_sha_ex(unsigned char *dest, const uint8_t *msg, uint32_t mlen) {
uint8_t md[SHA256_DIGESTLEN] = {0};
SHA256_CTX sha;
sha256_init(&sha);
sha256_update(&sha, msg, mlen);
sha256_final(&sha, md);
memcpy(dest, md, SHA256_DIGESTLEN);
}

void compute_hmac_ex(unsigned char *dest, const uint8_t *key, uint32_t klen, const uint8_t *msg, uint32_t mlen) {
uint8_t md[SHA256_DIGESTLEN] = {0};
HMAC_SHA256_CTX hmac;
hmac_sha256_init(&hmac, key, klen);
hmac_sha256_update(&hmac, msg, mlen);
hmac_sha256_final(&hmac, md);
memcpy(dest, md, SHA256_DIGESTLEN);
}

std::string base64_add_encode(unsigned char *dest, int length) {

std::string base_64_out = Base64Encode(dest, length);
//std::cout << base_64_out << std::endl;
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::wstring wide_string = converter.from_bytes(base_64_out);
std::string signature_sha(wide_string.begin(), wide_string.end());
return signature_sha;
}

std::string make_hmac_sha256(std::string wsignature_origin, std::string wapi_secret_origin, const char *api_key) {

unsigned char dest[1024] = {0};
compute_hmac_ex(dest, (const uint8_t *) wapi_secret_origin.c_str(), wapi_secret_origin.length(),
(const uint8_t *) wsignature_origin.c_str(), wsignature_origin.length());


std::string outdata_str = sha256_toString(dest);
//std::cout << outdata_str <<" "<<outdata_str.size()<<std::endl;
//std::cout << dest << std::endl;
std::string signature_sha = base64_add_encode(dest, outdata_str.size() / 2);
//std::cout << signature_sha <<" "<< signature_sha.size()<<std::endl;
char authorization_origin[1024] = {0};
sprintf(authorization_origin, "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", api_key,
"hmac-sha256", "host date request-line", signature_sha.c_str());
//std::cout << authorization_origin << std::endl;
std::string str_authorization_origin = authorization_origin;
int length = str_authorization_origin.size();
std::string authorization = base64_add_encode(reinterpret_cast<unsigned char *>(authorization_origin), length);
//std::cout << authorization << std::endl;
return authorization;

}

std::string
assemble_ws_auth_url(const char *requset_url, const char *api_key, const char *api_secret, const char *method = "GET") {
std::string request_str = requset_url;
int firstPosition = request_str.find_first_of('/'); //window 使用\\ linux 使用/
std::string pre_host = request_str.substr(firstPosition + 2, request_str.size());
int secondPosition = pre_host.find_first_of('/');
std::string host = pre_host.substr(0, secondPosition);
std::string path = pre_host.substr(secondPosition, pre_host.size());

std::string data_time = http_gmtime();
//::string data_time = "Wed, 12 Oct 2022 09:22:43 GMT";
printf("%s\n", data_time.c_str());

char signature[1024];
sprintf(signature, "host: %s\ndate: %s\n%s %s HTTP/1.1", host.c_str(), data_time.c_str(), method, path.c_str());
std::string signature_origin = signature;
std::wstring wsignature(signature_origin.begin(), signature_origin.end());
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::string wsignature_origin = converter.to_bytes(wsignature);

std::string s_api_secret = api_secret;
std::wstring wapi_secret(s_api_secret.begin(), s_api_secret.end());
std::string wapi_secret_origin = converter.to_bytes(wapi_secret);
//在线加密测试网站
// http://www.jsons.cn/allencrypt/

std::string authorization = make_hmac_sha256(wsignature_origin, wapi_secret_origin, api_key);
char value[1024] = {0};
sprintf(value, "host=%s&date=%s&authorization=%s", host.c_str(), data_time.c_str(), authorization.c_str());
std::string append_url = UrlEncode(value);
std::string full_request_url = request_str + "?" + append_url;
//std::cout<<append_url<<std::endl;
return full_request_url;
}

void
req_url(const char *api_name, const char *APPId, const char *APIKey, const char *APISecret, const char *requset_url,
const char *file_path) {
char appid[1024] = {0};
sprintf(appid, "appid: %s", APPId);
std::string body = gen_req_body(api_name, APPId, file_path);
const char *method = "POST";
std::string request_url = assemble_ws_auth_url(requset_url, APIKey, APISecret, method);

CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
curl_easy_setopt(curl, CURLOPT_URL, request_url.c_str());
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, appid);
headers = curl_slist_append(headers, "content-type: application/json");
headers = curl_slist_append(headers, "host: api.xf-yun.com");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
const char *data = body.c_str();
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}

curl_global_cleanup();

}

int main(int argc, char *argv[]) {
const char *APPId = "sxj";
const char *APISecret = "sxj";
const char *APIKey = "sxj";
//# apiname取值:
//# 1.创建声纹特征库 createGroup
//# 2.添加音频特征 createFeature
//# 3.查询特征列表 queryFeatureList
//# 4.特征比对1:1 searchScoreFea
//# 5.特征比对1:N searchFea
//# 6.更新音频特征 updateFeature
//# 7.删除指定特征 deleteFeature
//# 8.删除声纹特征库 deleteGroup

// 仅实现了两个 其他类似 不重复实现,集成项目中
//const char *api_name = "createGroup";
const char *api_name = "createFeature";

const char *file_path = "../0.mp3";
const char *request_url = "http://api.xf-yun.com/v1/private/s782b4996";
req_url(api_name, APPId, APIKey, APISecret, request_url, file_path);


return 0;
}

Base64.h

#ifndef UNTITLED2_BASE64_H
#define UNTITLED2_BASE64_H
#include <string>

std::string Base64Encode(const unsigned char* Data, int DataByte);
std::string Base64Decode(const char *Data, int DataByte);


#endif //UNTITLED2_BASE64_H

Base.cpp


#include "Base64.h"
std::string Base64Encode(const unsigned char* Data, int DataByte)
{
//编码表
const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//返回值
std::string strEncode;
unsigned char Tmp[4] = { 0 };
int LineLength = 0;
for (int i = 0; i<(int)(DataByte / 3); i++)
{
Tmp[1] = *Data++;
Tmp[2] = *Data++;
Tmp[3] = *Data++;
strEncode += EncodeTable[Tmp[1] >> 2];
strEncode += EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F];
strEncode += EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F];
strEncode += EncodeTable[Tmp[3] & 0x3F];
if (LineLength += 4, LineLength == 76) { strEncode += "\r\n"; LineLength = 0; }
}
//对剩余数据进行编码
int Mod = DataByte % 3;
if (Mod == 1)
{
Tmp[1] = *Data++;
strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
strEncode += EncodeTable[((Tmp[1] & 0x03) << 4)];
strEncode += "==";
}
else if (Mod == 2)
{
Tmp[1] = *Data++;
Tmp[2] = *Data++;
strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
strEncode += EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)];
strEncode += EncodeTable[((Tmp[2] & 0x0F) << 2)];
strEncode += "=";
}

return strEncode;
}

std::string Base64Decode(const char *Data, int DataByte)
{
//解码表
const char DecodeTable[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};
//返回值
std::string strDecode;
int nValue;
int i = 0;
while (i < DataByte)
{
if (*Data != '\r' && *Data != '\n')
{
nValue = DecodeTable[*Data++] << 18;
nValue += DecodeTable[*Data++] << 12;
strDecode += (nValue & 0x00FF0000) >> 16;
//OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++] << 6;
strDecode += (nValue & 0x0000FF00) >> 8;
//OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++];
strDecode += nValue & 0x000000FF;
// OutByte++;
}
}
i += 4;
}
else// 回车换行,跳过
{
Data++;
i++;
}
}
return strDecode;
}

hmachsa256.h

#ifndef _HMAC_SHA_256_H_
#define _HMAC_SHA_256_H_

#define SHA256_BLOCKLEN 64ul //size of message block buffer
#define SHA256_DIGESTLEN 32ul //size of digest in uint8_t
#define SHA256_DIGESTINT 8ul //size of digest in uint32_t

// #ifndef PBKDF2_SHA256_STATIC
// #define PBKDF2_SHA256_DEF extern
// #else
// #define PBKDF2_SHA256_DEF static
// #endif

#include <stdint.h>
#include <string.h>
#include <string>
#include <iomanip>

typedef struct sha256_ctx_t
{
uint64_t len; // processed message length
uint32_t h[SHA256_DIGESTINT]; // hash state
uint8_t buf[SHA256_BLOCKLEN]; // message block buffer
} SHA256_CTX;

void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const uint8_t *m, uint32_t mlen);
// resets state: calls sha256_init
void sha256_final(SHA256_CTX *ctx, uint8_t *md);

typedef struct hmac_sha256_ctx_t
{
uint8_t buf[SHA256_BLOCKLEN]; // key block buffer, not needed after init
uint32_t h_inner[SHA256_DIGESTINT];
uint32_t h_outer[SHA256_DIGESTINT];
SHA256_CTX sha;
} HMAC_SHA256_CTX;

void hmac_sha256_init(HMAC_SHA256_CTX *hmac, const uint8_t *key, uint32_t keylen);
void hmac_sha256_update(HMAC_SHA256_CTX *hmac, const uint8_t *m, uint32_t mlen);
void hmac_sha256_final(HMAC_SHA256_CTX *hmac, uint8_t *md);
std::string sha256_toString(const uint8_t * digest);
void pbkdf2_sha256(HMAC_SHA256_CTX *ctx,const uint8_t *key, uint32_t keylen, const uint8_t *salt, uint32_t saltlen, uint32_t rounds,uint8_t *dk, uint32_t dklen);

#endif // _HMAC_SHA_256_H_

hmachsa256.cpp

#include "hmacsha256.h"


//#define ROR(n,k) ((n >> k) | (n << (32 - k)))

static uint32_t ror(uint32_t n, uint32_t k)
{
return (n >> k) | (n << (32 - k));
}

#define ROR(n,k) ror(n,k)

#define CH(x,y,z) (z ^ (x & (y ^ z)))
#define MAJ(x,y,z) ((x & y) | (z & (x | y)))
#define S0(x) (ROR(x, 2) ^ ROR(x,13) ^ ROR(x,22))
#define S1(x) (ROR(x, 6) ^ ROR(x,11) ^ ROR(x,25))
#define R0(x) (ROR(x, 7) ^ ROR(x,18) ^ (x>>3))
#define R1(x) (ROR(x,17) ^ ROR(x,19) ^ (x>>10))

static const uint32_t K[64] =
{
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
};

static void sha256_transform(SHA256_CTX *s, const uint8_t *buf)
{
uint32_t t1, t2, a, b, c, d, e, f, g, h, m[64];
uint32_t i, j;

for (i = 0, j = 0; i < 16; i++, j += 4)
{
m[i] = (uint32_t) buf[j] << 24 | (uint32_t) buf[j + 1] << 16 |
(uint32_t) buf[j + 2] << 8 | (uint32_t) buf[j + 3];
}
for (; i < 64; i++)
{
m[i] = R1(m[i - 2]) + m[i - 7] + R0(m[i - 15]) + m[i - 16];
}
a = s->h[0];
b = s->h[1];
c = s->h[2];
d = s->h[3];
e = s->h[4];
f = s->h[5];
g = s->h[6];
h = s->h[7];
for (i = 0; i < 64; i++)
{
t1 = h + S1(e) + CH(e, f, g) + K[i] + m[i];
t2 = S0(a) + MAJ(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
s->h[0] += a;
s->h[1] += b;
s->h[2] += c;
s->h[3] += d;
s->h[4] += e;
s->h[5] += f;
s->h[6] += g;
s->h[7] += h;
}

void sha256_init(SHA256_CTX *s)
{
s->len = 0;

s->h[0] = 0x6a09e667;
s->h[1] = 0xbb67ae85;
s->h[2] = 0x3c6ef372;
s->h[3] = 0xa54ff53a;
s->h[4] = 0x510e527f;
s->h[5] = 0x9b05688c;
s->h[6] = 0x1f83d9ab;
s->h[7] = 0x5be0cd19;
}

void sha256_final(SHA256_CTX *s, uint8_t *md)
{
uint32_t r = s->len % SHA256_BLOCKLEN;
int i;

//pad
s->buf[r++] = 0x80;
if (r > 56)
{
memset(s->buf + r, 0, SHA256_BLOCKLEN - r);
r = 0;
sha256_transform(s, s->buf);
}
memset(s->buf + r, 0, 56 - r);
s->len *= 8;
s->buf[56] = s->len >> 56;
s->buf[57] = s->len >> 48;
s->buf[58] = s->len >> 40;
s->buf[59] = s->len >> 32;
s->buf[60] = s->len >> 24;
s->buf[61] = s->len >> 16;
s->buf[62] = s->len >> 8;
s->buf[63] = s->len;
sha256_transform(s, s->buf);

for (i = 0; i < SHA256_DIGESTINT; i++)
{
md[4 * i ] = s->h[i] >> 24;
md[4 * i + 1] = s->h[i] >> 16;
md[4 * i + 2] = s->h[i] >> 8;
md[4 * i + 3] = s->h[i];
}
sha256_init(s);
}

void sha256_update(SHA256_CTX *s, const uint8_t *m, uint32_t len)
{
const uint8_t *p = m;
uint32_t r = s->len % SHA256_BLOCKLEN;

s->len += len;
if (r)
{
if (len + r < SHA256_BLOCKLEN)
{
memcpy(s->buf + r, p, len);
return;
}
memcpy(s->buf + r, p, SHA256_BLOCKLEN - r);
len -= SHA256_BLOCKLEN - r;
p += SHA256_BLOCKLEN - r;
sha256_transform(s, s->buf);
}
for (; len >= SHA256_BLOCKLEN; len -= SHA256_BLOCKLEN, p += SHA256_BLOCKLEN)
{
sha256_transform(s, p);
}
memcpy(s->buf, p, len);
}

#define INNER_PAD '\x36'
#define OUTER_PAD '\x5c'
std::string sha256_toString(const uint8_t * digest) {
std::stringstream s;
s << std::setfill('0') << std::hex;

for(uint8_t i = 0 ; i < 32 ; i++) {
s << std::setw(2) << (unsigned int) digest[i];
}

return s.str();
}
void hmac_sha256_init(HMAC_SHA256_CTX *hmac, const uint8_t *key, uint32_t keylen)
{
SHA256_CTX *sha = &hmac->sha;
uint32_t i;

if (keylen <= SHA256_BLOCKLEN)
{
memcpy(hmac->buf, key, keylen);
memset(hmac->buf + keylen, '\0', SHA256_BLOCKLEN - keylen);
}
else
{
sha256_init(sha);
sha256_update(sha, key, keylen);
sha256_final(sha, hmac->buf);
memset(hmac->buf + SHA256_DIGESTLEN, '\0', SHA256_BLOCKLEN - SHA256_DIGESTLEN);
}

for (i = 0; i < SHA256_BLOCKLEN; i++)
{
hmac->buf[ i ] = hmac->buf[ i ] ^ OUTER_PAD;
}

sha256_init(sha);
sha256_update(sha, hmac->buf, SHA256_BLOCKLEN);
// copy outer state
memcpy(hmac->h_outer, sha->h, SHA256_DIGESTLEN);

for (i = 0; i < SHA256_BLOCKLEN; i++)
{
hmac->buf[ i ] = (hmac->buf[ i ] ^ OUTER_PAD) ^ INNER_PAD;
}

sha256_init(sha);
sha256_update(sha, hmac->buf, SHA256_BLOCKLEN);
// copy inner state
memcpy(hmac->h_inner, sha->h, SHA256_DIGESTLEN);
}

void hmac_sha256_update(HMAC_SHA256_CTX *hmac, const uint8_t *m, uint32_t mlen)
{
sha256_update(&hmac->sha, m, mlen);
}

void hmac_sha256_final(HMAC_SHA256_CTX *hmac, uint8_t *md)
{
SHA256_CTX *sha = &hmac->sha;
sha256_final(sha, md);

// reset sha to outer state
memcpy(sha->h, hmac->h_outer, SHA256_DIGESTLEN);
sha->len = SHA256_BLOCKLEN;

sha256_update(sha, md, SHA256_DIGESTLEN);
sha256_final(sha, md); // md = D(outer || D(inner || msg))

// reset sha to inner state -> reset hmac
memcpy(sha->h, hmac->h_inner, SHA256_DIGESTLEN);
sha->len = SHA256_BLOCKLEN;
}

void pbkdf2_sha256(HMAC_SHA256_CTX *hmac,
const uint8_t *key, uint32_t keylen, const uint8_t *salt, uint32_t saltlen, uint32_t rounds,
uint8_t *dk, uint32_t dklen)
{
uint8_t *U;
uint8_t *T;
uint8_t count[4];
uint32_t i, j, k;
uint32_t len;

uint32_t hlen = SHA256_DIGESTLEN;
uint32_t l = dklen / hlen + ((dklen % hlen) ? 1 : 0);
uint32_t r = dklen - (l - 1) * hlen;

hmac_sha256_init(hmac, key, keylen);

U = hmac->buf;
T = dk;

len = hlen;
for (i = 1; i <= l; i++)
{
if (i == l) { len = r; }
count[0] = (i >> 24) & 0xFF;
count[1] = (i >> 16) & 0xFF;
count[2] = (i >> 8) & 0xFF;
count[3] = (i) & 0xFF;
hmac_sha256_update(hmac, salt, saltlen);
hmac_sha256_update(hmac, count, 4);
hmac_sha256_final(hmac, U);
memcpy(T, U, len);
for (j = 1; j < rounds; j++)
{
hmac_sha256_update(hmac, U, hlen);
hmac_sha256_final(hmac, U);
for (k = 0; k < len; k++)
{
T[k] ^= U[k];
}
}
T += len;
}

}

url.h


#ifndef UNTITLED2_URL_H
#define UNTITLED2_URL_H
#include <cassert>
#include <string>

unsigned char ToHex(unsigned char x);
unsigned char FromHex(unsigned char x);
std::string UrlEncode(const std::string& str);
std::string UrlDecode(const std::string& str);


#endif //UNTITLED2_URL_H

url.cpp

//
// Created by ubuntu on 2022/10/12.
//


#include "url.h"
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;
}

std::string UrlEncode(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 += "+";
///sxj731533730 添加
else if(str[i]=='\r')
continue;
else if(str[i]=='\n')
continue;
else if(str[i]=='=')
strTemp +='=';
else if(str[i]=='&')
strTemp+='&';
///sxj731533730 添加
else
{
strTemp += '%';
strTemp += ToHex((unsigned char)str[i] >> 4);
strTemp += ToHex((unsigned char)str[i] % 16);
}
}
return strTemp;
}

std::string UrlDecode(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;
}

测试结果

/home/ubuntu/audio_feature/cmake-build-debug/audio_feature
Thu, 13 Oct 2022 02:09:36 GMT
{"header":{"code":0,"message":"success","sid":"××@×××"},"payload":{"createFeatureRes":{"compress":"raw","encoding":"utf8","format":"json","status":"3","text":"eyJmZWF0dXJlSWQiOiJpRkxZVEVLX2V4YW1wbGVzX2ZlYXR1cmVJZCJ9"}}}
Process finished with exit code 0

附上clion的文件目录

65、记录使用科大讯飞的声纹识别从官方的Python Demo转C++ Demo路程_开放平台_02

 

参考:

​https://cplusplus.com/​

​声纹识别 API 文档 | 讯飞开放平台文档中心​

标签:std,string,Python,Demo,C++,str,doc,SHA256,rapidjson
From: https://blog.51cto.com/u_12504263/5760733

相关文章

  • c++ container容器(string,vector,map,queue,stack等等)
    STL和c++标准库标准模板库STL部分包含在C++标准库中的软件库。c++标准库:即以std::开头,但是部分编译器厂商也会把STL的内容放在std::namespace里面由于​​一个常见的误解​......
  • C++实现链表反转
    #include"stdio.h"structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};classSolution{public:ListNode*Rev......
  • 【Python】Centos7安装Python3和pip
    安装Python3#wgethttps://www.python.org/ftp/python/3.6.2/Python-3.6.2.tar.xz#tar-xvJfPython-3.6.2.tar.xz#cdPython-3.6.2#./configure--prefix=/data......
  • python第三周总结
    每周总结文件操作1.文件概念与打开方式1.文件的概念就是操作系统暴露给用户操作硬盘的快捷方式eg:双击一个文件其实是从硬盘将数据加载到内存ctrl......
  • C++二叉树动画演示
    C++二叉树动画演示题目2:基于前序、中序、后序序列构造二叉树需求:1、任意输入前序+中序序列或者中序+后序序列,生成二叉树,请使用三叉链表,在构造链表的过程中同步更新每......
  • C++提高编程
    目录C++提高编程1模板1.1模板的概念1.2函数模板1.2.1函数模板语法1.2.2函数模板注意事项1.2.3函数模板案例1.2.4普通函数与函数模板的区别1.2.5普通函数与函数模板......
  • python 包
    1.python包init.py其实是一个特殊的文件,只要这个文件存在这个文件夹里,那么这个文件夹就是python包,如果没有__init__.py,那这个文件夹就只是文件夹。创建包的步骤:2.导......
  • python新类似乎违背了广度优先的执行顺序, 对象自定义计数实例化的多少
    classTSSS():deff1(self):print('fromTSSS')classSSS(TSSS):deff1(self):print('fromSSS')classSS():deff1(self):......
  • Python函数
    5.1函数相关基础概念5.1.1函数是什么函数是指一段可以直接被另一段程序或代码引用的程序或代码。也叫做子程序、(OOP中)方法。一个较大的程序一般应分为若干个程序块,每......
  • 基于QT和C++实现的翻金币游戏
    基于QT和C++的翻金币游戏声明:QT翻金币项目可以说是每个新学QT的同学都会去写的一个项目,网上的源码也很多,我也是最近刚开始学QT,所以也参考了很多前辈的代码自己重新敲了一......