wbi、av2bv、bv2av 的 c++ 实现 (#1035)
* + wbi 添加 c++ demo * + bv<-->av 算法 c++ 实现 * + App API 签名的 C++ 实现
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
|
||||
## Demo
|
||||
|
||||
该 Demo 提供 [Python](#Python) 和 [Java](#Java) 和 [TS/JS](#TypeScript/JavaScript) 和 [Swift](#Swift) 语言例程
|
||||
该 Demo 提供 [Python](#Python)、[Java](#Java)、[TS/JS](#TypeScript/JavaScript)、[Swift](#Swift)、[C++](#CplusPlus) 语言例程
|
||||
|
||||
使用 appkey = `1d8b6e7d45233436`, appsec = `560c52ccd288fed045859ed18bffd973` 对如下 `params` 参数进行签名
|
||||
|
||||
@@ -214,3 +214,76 @@ print(signResult)
|
||||
|
||||
输出结果为:01479cf20504d865519ac50f33ba3a7d
|
||||
|
||||
|
||||
|
||||
### CplusPlus
|
||||
|
||||
需要 c++ 23 标准库,[cpr](https://github.com/libcpr/cpr)、[cryptopp](https://github.com/weidai11/cryptopp)、[nlohmann/json](https://github.com/nlohmann/json) 等依赖
|
||||
|
||||
```c++
|
||||
#include <print> // std::println
|
||||
|
||||
/// thrid party libraries
|
||||
#include <cpr/cpr.h> // cpr::util::urlEncode()
|
||||
#include <cryptopp/md5.h>
|
||||
#include <cryptopp/hex.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
/*
|
||||
* 注意,假定不会发生错误!
|
||||
*/
|
||||
|
||||
/* 获取 md5 hex(lower) */
|
||||
std::string Get_md5_hex(const std::string &Input_str) {
|
||||
CryptoPP::Weak1::MD5 hash;
|
||||
std::string md5_hex;
|
||||
|
||||
CryptoPP::StringSource ss(Input_str, true,
|
||||
new CryptoPP::HashFilter(hash,
|
||||
new CryptoPP::HexEncoder(
|
||||
new CryptoPP::StringSink(md5_hex)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
std::ranges::for_each(md5_hex, [](char &x) { x = std::tolower(x); });
|
||||
return md5_hex;
|
||||
}
|
||||
|
||||
/* 将 json 转换为 url 编码字符串 */
|
||||
std::string Json_to_url_encode_str(const nlohmann::json &Json) {
|
||||
std::string encode_str;
|
||||
for (const auto &[key, value]: Json.items()) {
|
||||
encode_str.append(key).append("=").append(cpr::util::urlEncode(value.is_string() ? value.get<std::string>() : to_string(value))).append("&");
|
||||
}
|
||||
|
||||
// remove the last '&'
|
||||
encode_str.resize(encode_str.size() - 1, '\0');
|
||||
return encode_str;
|
||||
}
|
||||
|
||||
std::string App_sign(nlohmann::json &Params, const std::string &App_key, const std::string &App_sec) {
|
||||
Params["appkey"] = App_key;
|
||||
Params["sign"] = Get_md5_hex(Json_to_url_encode_str(Params) + App_sec);
|
||||
return Json_to_url_encode_str(Params);
|
||||
}
|
||||
|
||||
int main() {
|
||||
nlohmann::json Params;
|
||||
Params["id"] = 114514;
|
||||
Params["str"] = "1919810";
|
||||
Params["test"] = "いいよ,こいよ";
|
||||
|
||||
constexpr auto App_key = "1d8b6e7d45233436";
|
||||
constexpr auto App_sec = "560c52ccd288fed045859ed18bffd973";
|
||||
std::string sign = App_sign(Params, App_key, App_sec);
|
||||
std::println("{}", to_string(Params));
|
||||
std::println("{}", sign);
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
{"appkey":"1d8b6e7d45233436","id":114514,"sign":"01479cf20504d865519ac50f33ba3a7d","str":"1919810","test":"いいよ,こいよ"}
|
||||
appkey=1d8b6e7d45233436&id=114514&sign=01479cf20504d865519ac50f33ba3a7d&str=1919810&test=%E3%81%84%E3%81%84%E3%82%88%EF%BC%8C%E3%81%93%E3%81%84%E3%82%88
|
||||
```
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
## Demo
|
||||
|
||||
含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java) 和 [Swift](#Swift) 语言编写的 Demo 。
|
||||
含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java)、[Swift](#Swift)、[C++](#CPlusPlus) 语言编写的 Demo 。
|
||||
|
||||
### Python
|
||||
|
||||
@@ -934,3 +934,125 @@ func biliWbiSign(param: String, completion: @escaping (String?) -> Void) {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### CPlusPlus
|
||||
|
||||
需要 c++ 23 标准库,[cpr](https://github.com/libcpr/cpr)、[cryptopp](https://github.com/weidai11/cryptopp)、[nlohmann/json](https://github.com/nlohmann/json) 等依赖
|
||||
|
||||
```c++
|
||||
#include <array> // std::array
|
||||
#include <locale> // std::locale
|
||||
#include <print> // std::println
|
||||
|
||||
/// thrid party libraries
|
||||
#include <cpr/cpr.h>
|
||||
#include <cryptopp/md5.h>
|
||||
#include <cryptopp/hex.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
/*
|
||||
* 注意,假定不会发生错误!
|
||||
*/
|
||||
class Wbi {
|
||||
constexpr static std::array<uint8_t, 64> MIXIN_KEY_ENC_TAB_ = {
|
||||
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35,
|
||||
27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13,
|
||||
37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4,
|
||||
22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
|
||||
};
|
||||
|
||||
/* 获取 md5 hex(lower) */
|
||||
static std::string Get_md5_hex(const std::string &Input_str) {
|
||||
CryptoPP::Weak1::MD5 hash;
|
||||
std::string md5_hex;
|
||||
|
||||
CryptoPP::StringSource ss(Input_str, true,
|
||||
new CryptoPP::HashFilter(hash,
|
||||
new CryptoPP::HexEncoder(
|
||||
new CryptoPP::StringSink(md5_hex)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
std::ranges::for_each(md5_hex, [](char &x) { x = std::tolower(x); });
|
||||
return md5_hex;
|
||||
}
|
||||
|
||||
public:
|
||||
/* 将 json 转换为 url 编码字符串 */
|
||||
static std::string Json_to_url_encode_str(const nlohmann::json &Json) {
|
||||
std::string encode_str;
|
||||
for (const auto &[key, value]: Json.items()) {
|
||||
encode_str.append(key).append("=").append(cpr::util::urlEncode(value.is_string() ? value.get<std::string>() : to_string(value))).append("&");
|
||||
}
|
||||
|
||||
// remove the last '&'
|
||||
encode_str.resize(encode_str.size() - 1, '\0');
|
||||
return encode_str;
|
||||
}
|
||||
|
||||
/* 获取 wbi key */
|
||||
static std::pair<std::string, std::string> Get_wbi_key() {
|
||||
const auto url = cpr::Url {"https://api.bilibili.com/x/web-interface/nav"};
|
||||
const auto cookie = cpr::Cookies {
|
||||
{"SESSDATA", "xxxxxxxxxxxx"},
|
||||
};
|
||||
const auto header = cpr::Header {
|
||||
{"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"},
|
||||
{"Referer", "https://www.bilibili.com/"},
|
||||
};
|
||||
const auto response = cpr::Get(url, cookie, header);
|
||||
|
||||
nlohmann::json json = nlohmann::json::parse(response.text);
|
||||
|
||||
const std::string img_url = json["data"]["wbi_img"]["img_url"];
|
||||
const std::string sub_url = json["data"]["wbi_img"]["sub_url"];
|
||||
|
||||
std::string img_key = img_url.substr(img_url.find("wbi/") + 4, img_url.find(".png") - img_url.find("wbi/") - 4);
|
||||
std::string sub_key = sub_url.substr(sub_url.find("wbi/") + 4, sub_url.find(".png") - sub_url.find("wbi/") - 4);
|
||||
return {img_key, sub_key};
|
||||
}
|
||||
|
||||
/* 获取 mixin key */
|
||||
static std::string Get_mixin_key(const std::string &Img_key, const std::string &Sub_key) {
|
||||
std::string raw_wbi_key_str = Img_key + Sub_key;
|
||||
std::string result;
|
||||
|
||||
std::ranges::for_each(MIXIN_KEY_ENC_TAB_, [&result, &raw_wbi_key_str](const uint8_t x) {
|
||||
result.push_back(raw_wbi_key_str.at(x));
|
||||
});
|
||||
|
||||
return result.substr(0, 32);
|
||||
}
|
||||
|
||||
/* 计算签名(w_rid) */
|
||||
static std::string Calc_sign(nlohmann::json &Params, const std::string &Mixin_key) {
|
||||
Params["wts"] = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
const std::string encode_str = Json_to_url_encode_str(Params).append(Mixin_key);
|
||||
return Get_md5_hex(encode_str);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
nlohmann::json Params;
|
||||
// qn=32&fnver=0&fnval=4048&fourk=1&avid=1755630705&cid=1574294582
|
||||
Params["qn"] = 32;
|
||||
Params["fnver"] = 0;
|
||||
Params["fnval"] = 4048;
|
||||
Params["fourk"] = 1;
|
||||
Params["avid"] = 1755630705;
|
||||
Params["cid"] = 1574294582;
|
||||
|
||||
auto [img_key, sub_key] = Wbi::Get_wbi_key();
|
||||
const auto mixin_key = Wbi::Get_mixin_key(img_key, sub_key);
|
||||
const auto w_rid = Wbi::Calc_sign(Params, mixin_key);
|
||||
std::println("{}", Wbi::Json_to_url_encode_str(Params) + "&w_rid=" + w_rid);
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
avid=1755630705&cid=1574294582&fnval=4048&fnver=0&fourk=1&qn=32&wts=1717922933&w_rid=43571b838a1611fa121189083cfc1784
|
||||
```
|
||||
Reference in New Issue
Block a user