返回提交历史
Modified
docs/misc/sign/wbi.md
+80
-15
XFEstudio/bilibili-API-collect
fix: 修复获取 wbi 签名的 rust 实现 (#1059)
* fix: 修复获取 wbi 签名的 rust 实现 * chore: 在最上面的介绍里补上 Rust 的超链接
8f419c1
代码差异
1 个文件
+80
-15
@@ -120,7 +120,7 @@
120
120
121
121
## Demo
122
122
123
含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java)、[Swift](#Swift)、[C++](#CPlusPlus) 语言编写的 Demo 。
123
含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java)、[Swift](#Swift)、[C++](#CPlusPlus)、[Rust](#Rust) 语言编写的 Demo 。
124
124
125
125
### Python
126
126
@@ -867,6 +867,7 @@ struct ResWbi {
867
867
fn get_mixin_key(orig: &[u8]) -> String {
868
868
MIXIN_KEY_ENC_TAB
869
869
.iter()
870
.take(32)
870
871
.map(|&i| orig[i] as char)
871
872
.collect::<String>()
872
873
}
@@ -891,23 +892,34 @@ fn get_url_encoded(s: &str) -> String {
891
892
}
892
893
893
894
// 为请求参数进行 wbi 签名
894
fn encode_wbi(params: &mut Vec<(&str, String)>, (img_key, sub_key): (String, String)) -> String {
895
let mixin_key = get_mixin_key((img_key + &sub_key).as_bytes());
895
fn encode_wbi(params: Vec<(&str, String)>, (img_key, sub_key): (String, String)) -> String {
896
896
let cur_time = match SystemTime::now().duration_since(UNIX_EPOCH) {
897
897
Ok(t) => t.as_secs(),
898
898
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
899
899
};
900
_encode_wbi(params, (img_key, sub_key), cur_time)
901
}
902
903
fn _encode_wbi(
904
mut params: Vec<(&str, String)>,
905
(img_key, sub_key): (String, String),
906
timestamp: u64,
907
) -> String {
908
let mixin_key = get_mixin_key((img_key + &sub_key).as_bytes());
900
909
// 添加当前时间戳
901
params.push(("wts", cur_time.to_string()));
910
params.push(("wts", timestamp.to_string()));
902
911
// 重新排序
903
912
params.sort_by(|a, b| a.0.cmp(b.0));
904
let query = params.iter().fold(String::from(""), |acc, (k, v)| {
905
acc + format!("{}={}&", get_url_encoded(k), get_url_encoded(v)).as_str()
906
});
907
913
// 拼接参数
914
let query = params
915
.iter()
916
.map(|(k, v)| format!("{}={}", get_url_encoded(k), get_url_encoded(v)))
917
.collect::<Vec<_>>()
918
.join("&");
919
// 计算签名
908
920
let web_sign = format!("{:?}", md5::compute(query.clone() + &mixin_key));
909
910
query + &format!("w_rid={}", web_sign)
921
// 返回最终的 query
922
query + &format!("&w_rid={}", web_sign)
911
923
}
912
924
913
925
async fn get_wbi_keys() -> Result<(String, String), reqwest::Error> {
@@ -922,22 +934,75 @@ async fn get_wbi_keys() -> Result<(String, String), reqwest::Error> {
922
934
.await?
923
935
.json::<ResWbi>()
924
936
.await?;
937
Ok((
938
take_filename(wbi_img.img_url).unwrap(),
939
take_filename(wbi_img.sub_url).unwrap(),
940
))
941
}
925
942
926
Ok((wbi_img.img_url, wbi_img.sub_url))
943
fn take_filename(url: String) -> Option<String> {
944
url.rsplit_once('/')
945
.and_then(|(_, s)| s.rsplit_once('.'))
946
.map(|(s, _)| s.to_string())
927
947
}
928
948
929
949
#[tokio::main]
930
950
async fn main() {
931
let urls = get_wbi_keys().await.unwrap();
932
let mut params = vec![
951
let keys = get_wbi_keys().await.unwrap();
952
let params = vec![
933
953
("foo", String::from("114")),
934
954
("bar", String::from("514")),
935
955
("baz", String::from("1919810")),
936
956
];
957
let query = encode_wbi(params, keys);
958
println!("{}", query);
959
}
937
960
938
let query = encode_wbi(&mut params, urls);
961
// 取自文档描述的测试用例
962
#[cfg(test)]
963
mod tests {
964
use super::*;
965
966
#[test]
967
fn test_get_filename() {
968
assert_eq!(
969
take_filename(
970
"https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png".to_string()
971
),
972
Some("7cd084941338484aae1ad9425b84077c".to_string())
973
);
974
}
939
975
940
println!("{}", query);
976
#[test]
977
fn test_get_mixin_key() {
978
let concat_key =
979
"7cd084941338484aae1ad9425b84077c".to_string() + "4932caff0ff746eab6f01bf08b70ac45";
980
assert_eq!(
981
get_mixin_key(concat_key.as_bytes()),
982
"ea1db124af3c7062474693fa704f4ff8"
983
);
984
}
985
986
#[test]
987
fn test_encode_wbi() {
988
let params = vec![
989
("foo", String::from("114")),
990
("bar", String::from("514")),
991
("zab", String::from("1919810")),
992
];
993
assert_eq!(
994
_encode_wbi(
995
params,
996
(
997
"7cd084941338484aae1ad9425b84077c".to_string(),
998
"4932caff0ff746eab6f01bf08b70ac45".to_string()
999
),
1000
1702204169
1001
),
1002
"bar=514&foo=114&wts=1702204169&zab=1919810&w_rid=8f6f2b5b3d485fe1886cec6a0be8c5d4"
1003
.to_string()
1004
)
1005
}
941
1006
}
942
1007
```
943
1008