1135 lines
369 KiB
HTML
1135 lines
369 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<meta name="generator" content="VuePress 2.0.0-rc.24" />
|
||
<style>
|
||
:root {
|
||
--vp-c-bg: #fff;
|
||
}
|
||
|
||
[data-theme='dark'] {
|
||
--vp-c-bg: #1b1b1f;
|
||
}
|
||
|
||
html,
|
||
body {
|
||
background-color: var(--vp-c-bg);
|
||
}
|
||
</style>
|
||
<script>
|
||
const useChoice = localStorage.getItem('vuepress-color-scheme')
|
||
const systemStatus =
|
||
'matchMedia' in window
|
||
? window.matchMedia('(prefers-color-scheme: dark)').matches
|
||
: false
|
||
|
||
if (useChoice === 'light') {
|
||
document.documentElement.dataset.theme = 'light'
|
||
} else if (useChoice === 'dark' || systemStatus) {
|
||
document.documentElement.dataset.theme = 'dark'
|
||
}
|
||
</script>
|
||
<link rel="icon" href="/bilibili-API-collect/logo2.jpg"><title>WBI 签名 | BAC Document</title><meta name="description" content="社区开源的第三方哔哩哔哩 API 文档">
|
||
<link rel="preload" href="/bilibili-API-collect/assets/style-D1PJH1oj.css" as="style"><link rel="stylesheet" href="/bilibili-API-collect/assets/style-D1PJH1oj.css">
|
||
<link rel="modulepreload" href="/bilibili-API-collect/assets/app-Dgsdh8A6.js"><link rel="modulepreload" href="/bilibili-API-collect/assets/wbi.html-D21GJ5Gx.js">
|
||
<link rel="prefetch" href="/bilibili-API-collect/assets/CONTRIBUTING.html-Dg5RrJ0s.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-CyFjrwOB.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-DfGFo93u.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/splash.html-DTxmsPVe.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/ver.html-BK7Hl968.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-CRFYL4xy.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-67H6b90D.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-CkX_wc45.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/activity_list.html-Bekn3Lxe.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-DMnsBsuq.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-CBuhzqhd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/recommend_author.html-DBwItBdc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-C0ql065z.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/articles.html-zLkcz3pu.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/card.html-wL4C5GKc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/category.html-Xldy-aPs.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-CB0fSHFP.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/view.html-COrufaKB.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-BeujPZDG.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-DvFa4PRS.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/music_list.html-DeijlME4.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/musicstream_url.html-qq6CNfyp.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/rank.html-DT2C28KO.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/status_number.html-DEiPXucy.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/follow.html-DOVJW4CZ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-BLypTc8g.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/season_index.html-BSNCSXU1.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/timeline.html-CzpzQzIG.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/videostream_url.html-DlvjAVi_.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/banlist.html-Bx6m-UTQ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-BMdR7u31.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/video_room.html-CJ-aNxn7.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-BHbw7wWp.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/videostream_url.html-DnLcd0On.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/ip.html-BZmNmhHk.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-D_ydhzqh.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-D36gw51A.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-BN64GETH.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/opus.html-CoQ5EdO3.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/railgun.html-2O05GCD4.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/season.html-B_fCwBA8.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/statistics_data.html-BWH8OqIZ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/upload.html-DvDEkxhj.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/videos.html-4_uXrA4K.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/msg.html-C4G_rrXA.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-DeaDnvTK.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/buzzword.html-3axAz5ab.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/config.html-P2TT80Ma.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/danmaku_proto.html-B5M4AXvu.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/danmaku_view_proto.html-DtK2aZTc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/danmaku_xml.html-bHEnwOx6.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/history.html-D731H-Qd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/snapshot.html-sItLSrou.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/thumbup.html-oIOmP01b.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/webmask.html-BwxLSheT.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-D9uytAI1.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/all.html-MgLtiraJ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/atlist.html-CG0zNeT5.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/banner.html-W9RH5Lg_.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/basicInfo.html-DamYRO2m.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/card_info.html-BWktH6O6.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/content.html-DefzfqTR.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/detail.html-DH1NRSL5.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/dynamic_enum.html-DL_Gf64x.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/get_dynamic_detail.html-Bbk5LVZ-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/nav.html-D91zXMZR.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/publish.html-DaacAe0m.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/space.html-BjwA2AkB.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/topic.html-CxxVTskb.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/Bcoin.html-BhhfS1Rx.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/WeChat_Alipay.html-D7UPw-Mv.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/charge_list.html-DOFwkRFh.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/charge_msg.html-Bd63UhW6.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/monthly.html-D8O3h0v-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-DvqnymQp.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-Dk7ayv8u.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-DkRNgDlt.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-BSjizl7z.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-BfbnP9bx.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/color.html-D1CBKZrT.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/lottery.html-DbmXyYLK.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/skin.html-B7_-FfE5.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/history.html-U2B19yU-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/toview.html-m3XzHepP.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/danmaku.html-cYqsa6rm.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/emoticons.html-XPYXDzf0.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/follow_up_live.html-B7NT2XJb.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/gift.html-CPTDEb2_.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/guard.html-CgEHD9Az.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-bgddEvuk.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_area.html-UOPRZqNz.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_bill.html-Bxf6rN7p.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_data.html-DPx4fcGp.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_replay.html-iMUKGSwe.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_stream.html-CTvbm8Zd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/live_vote.html-niGIJdSc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/manage.html-DmvWf2hl.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/message_stream.html-DYabMnOf.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/recommend.html-0Yo2xP9c.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/redpocket.html-Bc9pXjpT.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/report.html-BHBFFQZc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/silent_user_manage.html-8B8EvR5w.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/user.html-FhJX8EJT.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/cookie_refresh.html-C-y7uaCA.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/exit.html-wyBJUhyQ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/login_info.html-DcTURbz0.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/login_notice.html-BXRbf4ou.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/member_center.html-UE6PIsuf.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/Activity.html-Bxk-gk5Y.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/ClockIn.html-CenNAwzg.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/Comic.html-CLerib4W.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/Download.html-Br9YEqP_.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/Season.html-Bv-xbTdd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/User.html-BxuEgE-I.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index_file.html-KxhduYzw.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/light_card.html-BX3csIVY.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/point_shop.html-BUYGiY4x.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/msg.html-DgLc4Fa5.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/private_msg.html-CTuY6IIe.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/private_msg_content.html-DnEBdBrk.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/settings.html-BbVpohbZ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/b23tv.html-Dxsq1OVj.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/buvid3_4.html-DBUwha3H.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/bvid_desc.html-C81lzKez.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/device_identity.html-B5I04eFh.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/errcode.html-BlmDP2Xd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/mathjax.html-B4Rx2kT_.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/picture.html-CKV2obIX.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/time_stamp.html-Cf7HhcO3.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-UGem3f8j.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/fetch.html-BtDU5o5f.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-C9gLOntC.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-DLzbyzsd.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-BtDZhXMA.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/list.html-Db8OOHOo.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-5vHX0xv-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/detail.html-VOBIbF4h.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/features.html-DiZBiXUW.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/rich_text_nodes.html-BvGiNCao.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/space.html-BdhGUVoS.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/hot.html-C_FX8JaJ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/search_request.html-xQgx95ji.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/search_response.html-BFpK_6jG.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/suggest.html-DlPRFJxV.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/teenager_mode.html-D3G18A_n.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/batch.html-cGq5Qeh2.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/check_nickname.html-BRdxxp6m.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/contract.html-YS65q_jn.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-CktfHCh6.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/medals.html-BRvf8EJa.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/official_role.html-CBvofUdP.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/register.html-BOasFjaK.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/relation.html-b3hEZ13C.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/space.html-BfZb_dIi.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/status_number.html-BT56l5dB.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-DLBmRfG7.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/appeal.html-CcLQmg66.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/attribute_data.html-C_YkRlS-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/collection.html-B-uxvybk.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-L873uB9d.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/interact_video.html-DoiQ0Pcr.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/online.html-DJ5lT1x9.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/pbp.html-BBYSf0a-.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/player.html-ZpJBp7gv.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/recommend.html-D0A21iEw.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/report.html-DuHXegGH.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/snapshot.html-hqn3Xd78.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/status_number.html-iguXtKgQ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/summary.html-DYcY1pBr.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/tags.html-Jjo00nOo.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/video_zone.html-B-nRnqQj.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/video_zone_v2.html-Cqbk0tky.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/videostream_url.html-JIL5pwcj.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/dynamic.html-BfZKb2_b.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/popular.html-xzW9jflm.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/precious_videos.html-DUvixdN1.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/ranking.html-Cx0F7V2z.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-1E0fVjfS.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/center.html-FZSMvI39.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/clockin.html-CE6-I-0u.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-D7kTJjVD.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/info.html-Bj2GpsEI.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/404_manga.html-CkQTSSKc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/banner.html-CWlCIz3C.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/header.html-CSeKquiq.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/zone_upload.html-CcYIfnj4.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/action.html-BIakPva5.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/base_info.html-DevYYkKc.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/judgement_info.html-BuyAWrJX.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/QR.html-BHJa37nz.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/SMS.html-In_XL6PP.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/password.html-CmP0Tl9k.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/index.html-B3pWXgRb.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/APP.html-CuPBHwrB.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/APPKey.html-CPC2-tlJ.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/bili_ticket.html-BusUE46s.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/v_voucher.html-BbbVVnZu.js" as="script"><link rel="prefetch" href="/bilibili-API-collect/assets/404.html-DrI-cPdQ.js" as="script">
|
||
</head>
|
||
<body>
|
||
<div id="app"><!--[--><div class="vp-theme-container external-link-icon" vp-container><!--[--><header class="vp-navbar" vp-navbar><div class="vp-toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a class="route-link" href="/bilibili-API-collect/"><img class="vp-site-logo" src="/bilibili-API-collect/logo2.jpg" alt="BAC Document"><span class="vp-site-name vp-hide-mobile" aria-hidden="true">BAC Document</span></a></span><div class="vp-navbar-items-wrapper" style=""><!--[--><!--]--><nav class="vp-navbar-items vp-hide-mobile" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/" aria-label="首页"><!--[--><!--[--><!--]--><!--]-->首页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/#🍴目录" aria-label="目录"><!--[--><!--[--><!--]--><!--]-->目录<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/CONTRIBUTING.html" aria-label="贡献指南"><!--[--><!--[--><!--]--><!--]-->贡献指南<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper"><button class="vp-navbar-dropdown-title" type="button" aria-label="相关社群"><span class="title">相关社群</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="相关社群"><span class="title">相关社群</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown" style="display:none;"><!--[--><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ympvb3LAPT-Ulu3ezhGqbkJ8zXMKImOX&authKey=z1KdkOdKO3wytN43m9K6On9nBtnDL4pAoD6VQHCipFBb9TasNDKuDHCmOE6TF3uc&noverify=0&group_code=191187164" aria-label="QQ交流群(综合技术交流)" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->QQ交流群(综合技术交流)<!--[--><!--[--><!--]--><!--]--></a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://t.me/bilibili_API_collect_community" aria-label="Telegram交流群(Github Bot推送)" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->Telegram交流群(Github Bot推送)<!--[--><!--[--><!--]--><!--]--></a></li><!--]--></ul></div></div><div class="vp-navbar-item"><a class="auto-link external-link" href="https://github.com/SocialSisterYi/bilibili-API-collect" aria-label="GitHub" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->GitHub<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button type="button" class="vp-toggle-color-mode-button" title="toggle color mode"><svg class="light-icon" viewbox="0 0 32 32" style=""><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg class="dark-icon" viewbox="0 0 32 32" style="display:none;"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><form class="search-box" role="search"><input type="search" placeholder="搜索" autocomplete="off" spellcheck="false" value><!----></form></div></header><!--]--><div class="vp-sidebar-mask"></div><!--[--><aside class="vp-sidebar" vp-sidebar><nav class="vp-navbar-items" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/" aria-label="首页"><!--[--><!--[--><!--]--><!--]-->首页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/#🍴目录" aria-label="目录"><!--[--><!--[--><!--]--><!--]-->目录<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/bilibili-API-collect/CONTRIBUTING.html" aria-label="贡献指南"><!--[--><!--[--><!--]--><!--]-->贡献指南<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper"><button class="vp-navbar-dropdown-title" type="button" aria-label="相关社群"><span class="title">相关社群</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="相关社群"><span class="title">相关社群</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown" style="display:none;"><!--[--><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ympvb3LAPT-Ulu3ezhGqbkJ8zXMKImOX&authKey=z1KdkOdKO3wytN43m9K6On9nBtnDL4pAoD6VQHCipFBb9TasNDKuDHCmOE6TF3uc&noverify=0&group_code=191187164" aria-label="QQ交流群(综合技术交流)" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->QQ交流群(综合技术交流)<!--[--><!--[--><!--]--><!--]--></a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://t.me/bilibili_API_collect_community" aria-label="Telegram交流群(Github Bot推送)" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->Telegram交流群(Github Bot推送)<!--[--><!--[--><!--]--><!--]--></a></li><!--]--></ul></div></div><div class="vp-navbar-item"><a class="auto-link external-link" href="https://github.com/SocialSisterYi/bilibili-API-collect" aria-label="GitHub" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><!--]--><!--]-->GitHub<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="vp-sidebar-items"><!--[--><li><p tabindex="0" class="vp-sidebar-item vp-sidebar-heading">WBI 签名 <!----></p><!----></li><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="vp-page"><!--[--><!--]--><div vp-content><!--[--><!--]--><div id="content"><h1 id="wbi-签名" tabindex="-1"><a class="header-anchor" href="#wbi-签名"><span>WBI 签名</span></a></h1><p>自 2023 年 3 月起,Bilibili Web 端部分接口开始采用 WBI 签名鉴权,表现在 REST API 请求时在 Query param 中添加了 <code>w_rid</code> 和 <code>wts</code> 字段。WBI 签名鉴权独立于 <a class="route-link" href="/bilibili-API-collect/docs/misc/sign/APP.html">APP 鉴权</a> 与其他 Cookie 鉴权,目前被认为是一种 Web 端风控手段。</p><p>经持续观察,大部分查询性接口都已经或准备采用 WBI 签名鉴权,请求 WBI 签名鉴权接口时,若签名参数 <code>w_rid</code> 与时间戳 <code>wts</code> 缺失、错误,会返回 <a class="route-link" href="/bilibili-API-collect/docs/misc/sign/v_voucher.html"><code>v_voucher</code></a>,如:</p><div class="language-json line-numbers-mode" data-highlighter="shiki" data-ext="json" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-json"><span class="line"><span style="color:#D4D4D4;">{</span><span style="color:#9CDCFE;">"code"</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"message"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"0"</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"ttl"</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"data"</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">"v_voucher"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"voucher_******"</span><span style="color:#D4D4D4;">}}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p>感谢 <a href="https://github.com/SocialSisterYi/bilibili-API-collect/issues/631" target="_blank" rel="noopener noreferrer">#631</a> 的研究与逆向工程。</p><p>细节更新:<a href="https://github.com/SocialSisterYi/bilibili-API-collect/issues/885" target="_blank" rel="noopener noreferrer">#885</a>。</p><p>最新进展: <a href="https://github.com/SocialSisterYi/bilibili-API-collect/issues/919" target="_blank" rel="noopener noreferrer">#919</a></p><h2 id="wbi-签名算法" tabindex="-1"><a class="header-anchor" href="#wbi-签名算法"><span>WBI 签名算法</span></a></h2><ol><li><p>获取实时口令 <code>img_key</code>、<code>sub_key</code></p><p>从 <a class="route-link" href="/bilibili-API-collect/docs/login/login_info.html#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF">nav 接口</a> 中获取 <code>img_url</code>、<code>sub_url</code> 两个字段的参数。 或从 <a class="route-link" href="/bilibili-API-collect/docs/misc/sign/bili_ticket.html#%E6%8E%A5%E5%8F%A3">bili_ticket 接口</a> 中获取 <code>img</code> <code>sub</code> 两个字段的参数。</p><p><strong>注:<code>img_url</code>、<code>sub_url</code> 两个字段的值看似为存于 BFS 中的 png 图片 url,实则只是经过伪装的实时 Token,故无需且不能试图访问这两个 url</strong></p><div class="language-json line-numbers-mode" data-highlighter="shiki" data-ext="json" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-json"><span class="line"><span style="color:#D4D4D4;">{</span><span style="color:#9CDCFE;">"code"</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">-101</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"message"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"账号未登录"</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"ttl"</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"data"</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">"isLogin"</span><span style="color:#D4D4D4;">:</span><span style="color:#569CD6;">false</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"wbi_img"</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">"img_url"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png"</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">"sub_url"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"https://i0.hdslb.com/bfs/wbi/4932caff0ff746eab6f01bf08b70ac45.png"</span><span style="color:#D4D4D4;">}}}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p>截取其文件名,分别记为 <code>img_key</code>、<code>sub_key</code>,如上述例子中的 <code>7cd084941338484aae1ad9425b84077c</code> 和 <code>4932caff0ff746eab6f01bf08b70ac45</code>。</p><p><code>img_key</code>、<code>sub_key</code> 全站统一使用,观测知应为<strong>每日更替</strong>,使用时建议做好<strong>缓存和刷新</strong>处理。</p><p>特别地,发现部分接口将 <code>img_key</code>、<code>sub_key</code> 硬编码进 JavaScript 文件内,如搜索接口 <code>https://s1.hdslb.com/bfs/static/laputa-search/client/assets/index.1ea39bea.js</code>,暂不清楚原因及影响。 同时, 部分页面会在 SSR 的 <code>__INITIAL_STATE__</code> 包含 <code>wbiImgKey</code> 与 <code>wbiSubKey</code>, 具体可用性与区别尚不明确</p></li><li><p>打乱重排实时口令获得 <code>mixin_key</code></p><p>把上一步获取到的 <code>sub_key</code> 拼接在 <code>img_key</code> 后面(下例记为 <code>raw_wbi_key</code>),遍历重排映射表 <code>MIXIN_KEY_ENC_TAB</code>,取出 <code>raw_wbi_key</code> 中对应位置的字符拼接得到新的字符串,截取前 32 位,即为 <code>mixin_key</code>。</p><p>重排映射表 <code>MIXIN_KEY_ENC_TAB</code> 长为 64,内容如下:</p><div class="language-rust line-numbers-mode" data-highlighter="shiki" data-ext="rust" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-rust"><span class="line"><span style="color:#569CD6;">const</span><span style="color:#D4D4D4;"> MIXIN_KEY_ENC_TAB: [</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">; </span><span style="color:#B5CEA8;">64</span><span style="color:#D4D4D4;">] = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">]</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>重排操作如下例:</p><div class="language-rust line-numbers-mode" data-highlighter="shiki" data-ext="rust" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-rust"><span class="line"><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> gen_mixin_key</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">raw_wbi_key</span><span style="color:#D4D4D4;">: </span><span style="color:#569CD6;">impl</span><span style="color:#4EC9B0;"> AsRef</span><span style="color:#D4D4D4;"><[</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">]>) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#D4D4D4;"> MIXIN_KEY_ENC_TAB: [</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">; </span><span style="color:#B5CEA8;">64</span><span style="color:#D4D4D4;">] = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ];</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> raw_wbi_key</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">raw_wbi_key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">as_ref</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#569CD6;"> mut</span><span style="color:#9CDCFE;"> mixin_key</span><span style="color:#D4D4D4;"> = {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> binding</span><span style="color:#D4D4D4;"> = MIXIN_KEY_ENC_TAB</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">iter</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 此步操作即遍历 MIXIN_KEY_ENC_TAB,取出 raw_wbi_key 中对应位置的字符</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;">(|</span><span style="color:#9CDCFE;">n</span><span style="color:#D4D4D4;">| </span><span style="color:#9CDCFE;">raw_wbi_key</span><span style="color:#D4D4D4;">[*</span><span style="color:#9CDCFE;">n</span><span style="color:#569CD6;"> as</span><span style="color:#4EC9B0;"> usize</span><span style="color:#D4D4D4;">])</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 并收集进数组内</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">collect</span><span style="color:#D4D4D4;">::<</span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">>>();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> unsafe</span><span style="color:#D4D4D4;"> { </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from_utf8_unchecked</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">binding</span><span style="color:#D4D4D4;">) }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> _</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">mixin_key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">split_off</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">); </span><span style="color:#6A9955;">// 截取前 32 位字符</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> mixin_key</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如 <code>img_key</code> -> <code>7cd084941338484aae1ad9425b84077c</code>、<code>sub_key</code> -> <code>4932caff0ff746eab6f01bf08b70ac45</code> 经过上述操作后得到 <code>mixin_key</code> -> <code>ea1db124af3c7062474693fa704f4ff8</code>。</p></li><li><p>计算签名(即 <code>w_rid</code>)</p><p>若下方内容为欲签名的<strong>原始</strong>请求参数(以 JavaScript Object 为例)</p><div class="language-javascript line-numbers-mode" data-highlighter="shiki" data-ext="javascript" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-javascript"><span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> foo</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'114'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> bar</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'514'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> zab</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1919810</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>wts</code> 字段的值应为当前以秒为单位的 Unix 时间戳,如 <code>1702204169</code></p><p>复制一份参数列表,添加 <code>wts</code> 参数,即:</p><div class="language-javascript line-numbers-mode" data-highlighter="shiki" data-ext="javascript" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-javascript"><span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> foo</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'114'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> bar</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'514'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> zab</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1919810</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> wts</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1702204169</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>随后按键名升序排序后百分号编码 URL Query,拼接前面得到的 <code>mixin_key</code>,如 <code>bar=514&foo=114&wts=1702204169&zab=1919810ea1db124af3c7062474693fa704f4ff8</code>,计算其 MD5 即为 <code>w_rid</code>。</p><p>需要注意的是:如果参数值含中文或特殊字符等,编码字符字母应当<strong>大写</strong> (部分库会错误编码为小写字母),空格应当编码为 <code>%20</code>(部分库按 <code>application/x-www-form-urlencoded</code> 约定编码为 <code>+</code>), 具体正确行为可参考 <a href="https://tc39.es/ecma262/multipage/global-object.html#sec-encodeuricomponent-uricomponent" target="_blank" rel="noopener noreferrer">encodeURIComponent 函数</a></p><p>例如:</p><div class="language-javascript line-numbers-mode" data-highlighter="shiki" data-ext="javascript" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-javascript"><span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> foo</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'one one four'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> bar</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'五一四'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C8C8C8;"> baz</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1919810</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>应该被编码为 <code>bar=%E4%BA%94%E4%B8%80%E5%9B%9B&baz=1919810&foo=one%20one%20four</code>。</p></li><li><p>向原始请求参数中添加 <code>w_rid</code>、<code>wts</code> 字段</p><p>将上一步得到的 <code>w_rid</code> 以及前面的 <code>wts</code> 追加到<strong>原始</strong>请求参数编码得到的 URL Query 后即可,目前看来无需对原始请求参数排序。</p><p>如前例最终得到 <code>bar=514&foo=114&zab=1919810&w_rid=8f6f2b5b3d485fe1886cec6a0be8c5d4&wts=1702204169</code>。</p></li></ol><h2 id="demo" tabindex="-1"><a class="header-anchor" href="#demo"><span>Demo</span></a></h2><p>含 <a href="#python">Python</a>、<a href="#javascript">JavaScript</a>、<a href="#golang">Golang</a>、<a href="#csharp">C#</a>、<a href="#java">Java</a>、<a href="#kotlin">Kotlin</a>、<a href="#swift">Swift</a>、<a href="#cplusplus">C++</a>、<a href="#rust">Rust</a>、<a href="#haskell">Haskell</a> 语言编写的 Demo</p><h3 id="python" tabindex="-1"><a class="header-anchor" href="#python"><span>Python</span></a></h3><p>需要<code>requests</code>依赖</p><div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-python"><span class="line"><span style="color:#C586C0;">from</span><span style="color:#D4D4D4;"> functools </span><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> reduce</span></span>
|
||
<span class="line"><span style="color:#C586C0;">from</span><span style="color:#D4D4D4;"> hashlib </span><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> md5</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> urllib.parse</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> time</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> requests</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">mixinKeyEncTab = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">def</span><span style="color:#DCDCAA;"> getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">orig</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">):</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> '对 imgKey 和 subKey 进行字符顺序打乱编码'</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> reduce(</span><span style="color:#569CD6;">lambda</span><span style="color:#9CDCFE;"> s</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">: s + orig[i], mixinKeyEncTab, </span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">)[:</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">def</span><span style="color:#DCDCAA;"> encWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">dict</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">img_key</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">sub_key</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">):</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> '为请求参数进行 wbi 签名'</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> mixin_key = getMixinKey(img_key + sub_key)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> curr_time = </span><span style="color:#DCDCAA;">round</span><span style="color:#D4D4D4;">(time.time())</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params[</span><span style="color:#CE9178;">'wts'</span><span style="color:#D4D4D4;">] = curr_time </span><span style="color:#6A9955;"># 添加 wts 字段</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params = </span><span style="color:#4EC9B0;">dict</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">sorted</span><span style="color:#D4D4D4;">(params.items())) </span><span style="color:#6A9955;"># 按照 key 重排参数</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> # 过滤 value 中的 "!'()*" 字符</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params = {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> k : </span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">.join(</span><span style="color:#DCDCAA;">filter</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">lambda</span><span style="color:#9CDCFE;"> chr</span><span style="color:#D4D4D4;">: </span><span style="color:#DCDCAA;">chr</span><span style="color:#C586C0;"> not</span><span style="color:#C586C0;"> in</span><span style="color:#CE9178;"> "!'()*"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">(v)))</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> k, v </span></span>
|
||
<span class="line"><span style="color:#C586C0;"> in</span><span style="color:#D4D4D4;"> params.items()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> query = urllib.parse.urlencode(params) </span><span style="color:#6A9955;"># 序列化参数</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> wbi_sign = md5((query + mixin_key).encode()).hexdigest() </span><span style="color:#6A9955;"># 计算 w_rid</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params[</span><span style="color:#CE9178;">'w_rid'</span><span style="color:#D4D4D4;">] = wbi_sign</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> params</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">def</span><span style="color:#DCDCAA;"> getWbiKeys</span><span style="color:#D4D4D4;">() -> tuple[</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">]:</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> '获取最新的 img_key 和 sub_key'</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> headers = {</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'User-Agent'</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'Referer'</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'https://www.bilibili.com/'</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> resp = requests.get(</span><span style="color:#CE9178;">'https://api.bilibili.com/x/web-interface/nav'</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">headers</span><span style="color:#D4D4D4;">=headers)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> resp.raise_for_status()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> json_content = resp.json()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> img_url: </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;"> = json_content[</span><span style="color:#CE9178;">'data'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'wbi_img'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'img_url'</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> sub_url: </span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;"> = json_content[</span><span style="color:#CE9178;">'data'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'wbi_img'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'sub_url'</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> img_key = img_url.rsplit(</span><span style="color:#CE9178;">'/'</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">].split(</span><span style="color:#CE9178;">'.'</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> sub_key = sub_url.rsplit(</span><span style="color:#CE9178;">'/'</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">].split(</span><span style="color:#CE9178;">'.'</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> img_key, sub_key</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">img_key, sub_key = getWbiKeys()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">signed_params = encWbi(</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;">={</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'foo'</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'114'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'bar'</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">'514'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'baz'</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1919810</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> },</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> img_key</span><span style="color:#D4D4D4;">=img_key,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> sub_key</span><span style="color:#D4D4D4;">=sub_key</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">query = urllib.parse.urlencode(signed_params)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">print</span><span style="color:#D4D4D4;">(signed_params)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">print</span><span style="color:#D4D4D4;">(query)</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>输出内容分别是进行 Wbi 签名的后参数的 key-Value 以及 url query 形式</p><div class="language- line-numbers-mode" data-highlighter="shiki" data-ext="" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-"><span class="line"><span>{'bar': '514', 'baz': '1919810', 'foo': '114', 'wts': '1702204169', 'w_rid': 'd3cbd2a2316089117134038bf4caf442'}</span></span>
|
||
<span class="line"><span>bar=514&baz=1919810&foo=114&wts=1702204169&w_rid=d3cbd2a2316089117134038bf4caf442</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="javascript" tabindex="-1"><a class="header-anchor" href="#javascript"><span>JavaScript</span></a></h3><p>需要 <code>fetch</code>(浏览器、NodeJS等环境自带)、<code>md5</code> 依赖</p><!----><p>输出内容为进行 Wbi 签名的后参数的 url query 形式</p><div class="language- line-numbers-mode" data-highlighter="shiki" data-ext="" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-"><span class="line"><span>bar=514&baz=1919810&foo=114&wts=1684805578&w_rid=bb97e15f28edf445a0e4420d36f0157e</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="golang" tabindex="-1"><a class="header-anchor" href="#golang"><span>Golang</span></a></h3><p>无第三方库</p><div class="language-go line-numbers-mode" data-highlighter="shiki" data-ext="go" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-go"><span class="line"><span style="color:#569CD6;">package</span><span style="color:#4EC9B0;"> main</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> (</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "bytes"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "crypto/md5"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "encoding/hex"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "encoding/json"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "fmt"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "io"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "net/http"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "net/url"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "strconv"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "strings"</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "time"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> main</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> u</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Parse</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> panic</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> fmt</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Printf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"orig: </span><span style="color:#9CDCFE;">%s</span><span style="color:#D7BA7D;">\n</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">String</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">Sign</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> panic</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> fmt</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Printf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"signed: </span><span style="color:#9CDCFE;">%s</span><span style="color:#D7BA7D;">\n</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">String</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 获取 wbi 时未修改 header</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 但实际使用签名后的 url 时发现风控较为严重</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// Sign 为链接签名</span></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> Sign</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;"> *</span><span style="color:#4EC9B0;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">URL</span><span style="color:#D4D4D4;">) </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Sign</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// Update 无视过期时间更新</span></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> Update</span><span style="color:#D4D4D4;">() </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Update</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> Get</span><span style="color:#D4D4D4;">() (</span><span style="color:#9CDCFE;">wk</span><span style="color:#4EC9B0;"> WbiKeys</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#4EC9B0;"> error</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">update</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">false</span><span style="color:#D4D4D4;">); </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#4EC9B0;"> WbiKeys</span><span style="color:#D4D4D4;">{}, </span><span style="color:#9CDCFE;">err</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">nil</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">var</span><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#4EC9B0;"> WbiKeys</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">type</span><span style="color:#4EC9B0;"> WbiKeys</span><span style="color:#569CD6;"> struct</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Img</span><span style="color:#4EC9B0;"> string</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Sub</span><span style="color:#4EC9B0;"> string</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Mixin</span><span style="color:#4EC9B0;"> string</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> lastUpdateTime</span><span style="color:#4EC9B0;"> time</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Time</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// Sign 为链接签名</span></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">wk </span><span style="color:#D4D4D4;">*</span><span style="color:#4EC9B0;">WbiKeys</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">Sign</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;"> *</span><span style="color:#4EC9B0;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">URL</span><span style="color:#D4D4D4;">) (</span><span style="color:#9CDCFE;">err</span><span style="color:#4EC9B0;"> error</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">update</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">false</span><span style="color:#D4D4D4;">); </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> err</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> values</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">u</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Query</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> values</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">removeUnwantedChars</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">values</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'!'</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'\''</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'('</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">')'</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'*'</span><span style="color:#D4D4D4;">) </span><span style="color:#6A9955;">// 必要性存疑?</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> values</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Set</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">strconv</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">FormatInt</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">time</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Now</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">Unix</span><span style="color:#D4D4D4;">(), </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // [url.Values.Encode] 内会对参数排序,</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 且遍历 map 时本身就是无序的</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> hash</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">md5</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Sum</span><span style="color:#D4D4D4;">([]</span><span style="color:#4EC9B0;">byte</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">values</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Encode</span><span style="color:#D4D4D4;">() + </span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Mixin</span><span style="color:#D4D4D4;">)) </span><span style="color:#6A9955;">// Calculate w_rid</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> values</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Set</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"w_rid"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">hex</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">EncodeToString</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">hash</span><span style="color:#D4D4D4;">[:]))</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> u</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">RawQuery</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">values</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Encode</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> nil</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// Update 无视过期时间更新</span></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">wk </span><span style="color:#D4D4D4;">*</span><span style="color:#4EC9B0;">WbiKeys</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">Update</span><span style="color:#D4D4D4;">() (</span><span style="color:#9CDCFE;">err</span><span style="color:#4EC9B0;"> error</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> wk</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">update</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">true</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// update 按需更新</span></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">wk </span><span style="color:#D4D4D4;">*</span><span style="color:#4EC9B0;">WbiKeys</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">update</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">purge</span><span style="color:#4EC9B0;"> bool</span><span style="color:#D4D4D4;">) </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> !</span><span style="color:#9CDCFE;">purge</span><span style="color:#D4D4D4;"> && </span><span style="color:#9CDCFE;">time</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Since</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">lastUpdateTime</span><span style="color:#D4D4D4;">) < </span><span style="color:#9CDCFE;">time</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Hour</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> nil</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 测试下来不用修改 header 也能过</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> resp</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">http</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Get</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://api.bilibili.com/x/web-interface/nav"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> err</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> defer</span><span style="color:#9CDCFE;"> resp</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Body</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Close</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> body</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">io</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ReadAll</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">resp</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Body</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> err</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> nav</span><span style="color:#D4D4D4;"> := </span><span style="color:#4EC9B0;">Nav</span><span style="color:#D4D4D4;">{}</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">json</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Unmarshal</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">body</span><span style="color:#D4D4D4;">, &</span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> err</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Code</span><span style="color:#D4D4D4;"> != </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;"> && </span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Code</span><span style="color:#D4D4D4;"> != -</span><span style="color:#B5CEA8;">101</span><span style="color:#D4D4D4;"> { </span><span style="color:#6A9955;">// -101 未登录时也会返回两个 key</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> fmt</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Errorf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"unexpected code: </span><span style="color:#9CDCFE;">%d</span><span style="color:#CE9178;">, message: </span><span style="color:#9CDCFE;">%s</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Code</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Message</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> img</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Data</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">WbiImg</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">ImgUrl</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> sub</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">nav</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Data</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">WbiImg</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">SubUrl</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> img</span><span style="color:#D4D4D4;"> == </span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;"> || </span><span style="color:#9CDCFE;">sub</span><span style="color:#D4D4D4;"> == </span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> fmt</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Errorf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"empty image or sub url: </span><span style="color:#9CDCFE;">%s</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">body</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> imgParts</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">strings</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">img</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> subParts</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">strings</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">sub</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 7cd084941338484aae1ad9425b84077c.png</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> imgPng</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">imgParts</span><span style="color:#D4D4D4;">[</span><span style="color:#DCDCAA;">len</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">imgParts</span><span style="color:#D4D4D4;">)-</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> subPng</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">subParts</span><span style="color:#D4D4D4;">[</span><span style="color:#DCDCAA;">len</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">subParts</span><span style="color:#D4D4D4;">)-</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 7cd084941338484aae1ad9425b84077c</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Img</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">strings</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">TrimSuffix</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">imgPng</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">".png"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Sub</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">strings</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">TrimSuffix</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">subPng</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">".png"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">mixin</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbiKeys</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">lastUpdateTime</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">time</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Now</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> nil</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">wk </span><span style="color:#D4D4D4;">*</span><span style="color:#4EC9B0;">WbiKeys</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">mixin</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#9CDCFE;"> mixin</span><span style="color:#D4D4D4;"> [</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">]</span><span style="color:#4EC9B0;">byte</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbi</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Img</span><span style="color:#D4D4D4;"> + </span><span style="color:#9CDCFE;">wk</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Sub</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#9CDCFE;"> i</span><span style="color:#D4D4D4;"> := </span><span style="color:#C586C0;">range</span><span style="color:#9CDCFE;"> mixin</span><span style="color:#D4D4D4;"> { </span><span style="color:#6A9955;">// for i := 0; i < len(mixin); i++ {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> mixin</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">] = </span><span style="color:#9CDCFE;">wbi</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">mixinKeyEncTab</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">]]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wk</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Mixin</span><span style="color:#D4D4D4;"> = </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">mixin</span><span style="color:#D4D4D4;">[:])</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">var</span><span style="color:#9CDCFE;"> mixinKeyEncTab</span><span style="color:#D4D4D4;"> = [...]</span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">61</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> removeUnwantedChars</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">v</span><span style="color:#4EC9B0;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Values</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">chars</span><span style="color:#D4D4D4;"> ...</span><span style="color:#4EC9B0;">byte</span><span style="color:#D4D4D4;">) </span><span style="color:#4EC9B0;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Values</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> b</span><span style="color:#D4D4D4;"> := []</span><span style="color:#4EC9B0;">byte</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">v</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Encode</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#9CDCFE;"> _</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;"> := </span><span style="color:#C586C0;">range</span><span style="color:#9CDCFE;"> chars</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> b</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">bytes</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ReplaceAll</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">, []</span><span style="color:#4EC9B0;">byte</span><span style="color:#D4D4D4;">{</span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;">}, </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> s</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := </span><span style="color:#9CDCFE;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ParseQuery</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#9CDCFE;"> err</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> panic</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> s</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">type</span><span style="color:#4EC9B0;"> Nav</span><span style="color:#569CD6;"> struct</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Code</span><span style="color:#4EC9B0;"> int</span><span style="color:#CE9178;"> `json:"code"`</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Message</span><span style="color:#4EC9B0;"> string</span><span style="color:#CE9178;"> `json:"message"`</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Ttl</span><span style="color:#4EC9B0;"> int</span><span style="color:#CE9178;"> `json:"ttl"`</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Data</span><span style="color:#569CD6;"> struct</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> WbiImg</span><span style="color:#569CD6;"> struct</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> ImgUrl</span><span style="color:#4EC9B0;"> string</span><span style="color:#CE9178;"> `json:"img_url"`</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> SubUrl</span><span style="color:#4EC9B0;"> string</span><span style="color:#CE9178;"> `json:"sub_url"`</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#CE9178;">`json:"wbi_img"`</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // ......</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#CE9178;">`json:"data"`</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="csharp" tabindex="-1"><a class="header-anchor" href="#csharp"><span>CSharp</span></a></h3><p>无需依赖外部库</p><div class="language-cs line-numbers-mode" data-highlighter="shiki" data-ext="cs" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-cs"><span class="line"><span style="color:#C586C0;">using</span><span style="color:#4EC9B0;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Security</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Cryptography</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#C586C0;">using</span><span style="color:#4EC9B0;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Text</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#C586C0;">using</span><span style="color:#4EC9B0;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Text</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Json</span><span style="color:#D4D4D4;">.</span><span style="color:#4EC9B0;">Nodes</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">class</span><span style="color:#4EC9B0;"> Program</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> HttpClient</span><span style="color:#9CDCFE;"> _httpClient</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> readonly</span><span style="color:#569CD6;"> int</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">MixinKeyEncTab</span><span style="color:#D4D4D4;"> =</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> //对 imgKey 和 subKey 进行字符顺序打乱编码</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> string</span><span style="color:#DCDCAA;"> GetMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">string</span><span style="color:#9CDCFE;"> orig</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> MixinKeyEncTab</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Aggregate</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;">, (</span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">) => </span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;"> + </span><span style="color:#9CDCFE;">orig</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">])[..</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> Dictionary</span><span style="color:#D4D4D4;"><</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">> </span><span style="color:#DCDCAA;">EncWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">Dictionary</span><span style="color:#D4D4D4;"><</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">> </span><span style="color:#9CDCFE;">parameters</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#9CDCFE;"> imgKey</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> subKey</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> mixinKey</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">GetMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">imgKey</span><span style="color:#D4D4D4;"> + </span><span style="color:#9CDCFE;">subKey</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> currTime</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">DateTimeOffset</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Now</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ToUnixTimeSeconds</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">ToString</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> //添加 wts 字段</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">] = </span><span style="color:#9CDCFE;">currTime</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 按照 key 重排参数</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">parameters</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">OrderBy</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;"> => </span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Key</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">ToDictionary</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;"> => </span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;"> => </span><span style="color:#9CDCFE;">p</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Value</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> //过滤 value 中的 "!'()*" 字符</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">parameters</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ToDictionary</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> kvp</span><span style="color:#D4D4D4;"> => </span><span style="color:#9CDCFE;">kvp</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Key</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> kvp</span><span style="color:#D4D4D4;"> => </span><span style="color:#569CD6;">new</span><span style="color:#569CD6;"> string</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">kvp</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Value</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Where</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">chr</span><span style="color:#D4D4D4;"> => !</span><span style="color:#CE9178;">"!'()*"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Contains</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">chr</span><span style="color:#D4D4D4;">)).</span><span style="color:#DCDCAA;">ToArray</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 序列化参数</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> query</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> FormUrlEncodedContent</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">parameters</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">ReadAsStringAsync</span><span style="color:#D4D4D4;">().</span><span style="color:#9CDCFE;">Result</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> //计算 w_rid</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> using</span><span style="color:#4EC9B0;"> MD5</span><span style="color:#9CDCFE;"> md5</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">MD5</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Create</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> byte</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">hashBytes</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">md5</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ComputeHash</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">Encoding</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF8</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">GetBytes</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">query</span><span style="color:#D4D4D4;"> + </span><span style="color:#9CDCFE;">mixinKey</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> wbiSign</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">BitConverter</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ToString</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">hashBytes</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">Replace</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"-"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">ToLower</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"w_rid"</span><span style="color:#D4D4D4;">] = </span><span style="color:#9CDCFE;">wbiSign</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 获取最新的 img_key 和 sub_key</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> async</span><span style="color:#4EC9B0;"> Task</span><span style="color:#D4D4D4;"><(</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">)> </span><span style="color:#DCDCAA;">GetWbiKeys</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#9CDCFE;"> httpClient</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> HttpClient</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> httpClient</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">DefaultRequestHeaders</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Add</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"User-Agent"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> httpClient</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">DefaultRequestHeaders</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Referrer</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> Uri</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://www.bilibili.com/"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> HttpResponseMessage</span><span style="color:#9CDCFE;"> responseMessage</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">await</span><span style="color:#9CDCFE;"> httpClient</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">SendAsync</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> HttpRequestMessage</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Method</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">HttpMethod</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Get</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> RequestUri</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> Uri</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://api.bilibili.com/x/web-interface/nav"</span><span style="color:#D4D4D4;">),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> });</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> JsonNode</span><span style="color:#9CDCFE;"> response</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">JsonNode</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Parse</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">await</span><span style="color:#9CDCFE;"> responseMessage</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">Content</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">ReadAsStringAsync</span><span style="color:#D4D4D4;">())!;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> imgUrl</span><span style="color:#D4D4D4;"> = (</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">)</span><span style="color:#9CDCFE;">response</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">"img_url"</span><span style="color:#D4D4D4;">]!;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> imgUrl</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">imgUrl</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">)[^</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">].</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"."</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> subUrl</span><span style="color:#D4D4D4;"> = (</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">)</span><span style="color:#9CDCFE;">response</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">"sub_url"</span><span style="color:#D4D4D4;">]!;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> subUrl</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">subUrl</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">)[^</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">].</span><span style="color:#DCDCAA;">Split</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"."</span><span style="color:#D4D4D4;">)[</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">imgUrl</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">subUrl</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> async</span><span style="color:#4EC9B0;"> Task</span><span style="color:#DCDCAA;"> Main</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">imgKey</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">subKey</span><span style="color:#D4D4D4;">) = </span><span style="color:#569CD6;">await</span><span style="color:#DCDCAA;"> GetWbiKeys</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Dictionary</span><span style="color:#D4D4D4;"><</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">> </span><span style="color:#9CDCFE;">signedParams</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">EncWbi</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> parameters</span><span style="color:#D4D4D4;">: </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> Dictionary</span><span style="color:#D4D4D4;"><</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">></span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">"foo"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"114"</span><span style="color:#D4D4D4;"> },</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">"bar"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"514"</span><span style="color:#D4D4D4;"> },</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">"baz"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"1919810"</span><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> },</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> imgKey</span><span style="color:#D4D4D4;">: </span><span style="color:#9CDCFE;">imgKey</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> subKey</span><span style="color:#D4D4D4;">: </span><span style="color:#9CDCFE;">subKey</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> string</span><span style="color:#9CDCFE;"> query</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">await</span><span style="color:#569CD6;"> new</span><span style="color:#4EC9B0;"> FormUrlEncodedContent</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">signedParams</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">ReadAsStringAsync</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Console</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">WriteLine</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">query</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>输出内容为进行 Wbi 签名的后参数的 url query 形式</p><div class="language- line-numbers-mode" data-highlighter="shiki" data-ext="" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-"><span class="line"><span>bar=514&baz=1919810&foo=114&wts=1687541921&w_rid=26e82b1b9b3a11dbb1807a9228a40d3b</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="java" tabindex="-1"><a class="header-anchor" href="#java"><span>Java</span></a></h3><div class="language-java line-numbers-mode" data-highlighter="shiki" data-ext="java" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-java"><span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.net.URLEncoder;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.nio.charset.StandardCharsets;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.security.MessageDigest;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.security.NoSuchAlgorithmException;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.util.*;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.util.stream.Collectors;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">public</span><span style="color:#569CD6;"> class</span><span style="color:#4EC9B0;"> WbiTest</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> final</span><span style="color:#4EC9B0;"> int</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">mixinKeyEncTab</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#4EC9B0;"> int</span><span style="color:#D4D4D4;">[]{</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> static</span><span style="color:#569CD6;"> final</span><span style="color:#4EC9B0;"> char</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">hexDigits</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">"0123456789abcdef"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toCharArray</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> md5</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> input</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> try</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> MessageDigest</span><span style="color:#9CDCFE;"> md</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">MessageDigest</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getInstance</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"MD5"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> byte</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">messageDigest</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">md</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">digest</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">input</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getBytes</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">StandardCharsets</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF_8</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> char</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">result</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#4EC9B0;"> char</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">messageDigest</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">length</span><span style="color:#D4D4D4;"> * </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">int</span><span style="color:#9CDCFE;"> i</span><span style="color:#D4D4D4;"> = </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">; i < </span><span style="color:#9CDCFE;">messageDigest</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">length</span><span style="color:#D4D4D4;">; i++) {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> result[i * </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">] = hexDigits[(messageDigest[i] >> </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">) & </span><span style="color:#B5CEA8;">0xF</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> result[i * </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;"> + </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">] = hexDigits[messageDigest[i] & </span><span style="color:#B5CEA8;">0xF</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#C586C0;"> new</span><span style="color:#DCDCAA;"> String</span><span style="color:#D4D4D4;">(result);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#C586C0;">catch</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">NoSuchAlgorithmException</span><span style="color:#9CDCFE;"> e</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> null</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> imgKey</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> subKey</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> s</span><span style="color:#D4D4D4;"> = imgKey + subKey;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> StringBuilder</span><span style="color:#9CDCFE;"> key</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> StringBuilder</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">int</span><span style="color:#9CDCFE;"> i</span><span style="color:#D4D4D4;"> = </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">; i < </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">; i++)</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">charAt</span><span style="color:#D4D4D4;">(mixinKeyEncTab[i]));</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toString</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> encodeURIComponent</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">Object</span><span style="color:#9CDCFE;"> o</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> URLEncoder</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">encode</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">o</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toString</span><span style="color:#D4D4D4;">(), </span><span style="color:#9CDCFE;">StandardCharsets</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF_8</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">replace</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"+"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"%20"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> void</span><span style="color:#DCDCAA;"> main</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">args</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> imgKey</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">"653657f524a547ac981ded72ea172057"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> subKey</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">"6e4909c702f846728e64f6007736a338"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> mixinKey</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">getMixinKey</span><span style="color:#D4D4D4;">(imgKey, subKey);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">println</span><span style="color:#D4D4D4;">(mixinKey); </span><span style="color:#6A9955;">// 72136226c6a73669787ee4fd02a74c27</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 用TreeMap自动排序</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> TreeMap</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">Object</span><span style="color:#D4D4D4;">> </span><span style="color:#9CDCFE;">map</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#4EC9B0;"> TreeMap</span><span style="color:#D4D4D4;"><>();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> map</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">put</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"foo"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"one one four"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> map</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">put</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"bar"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"五一四"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> map</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">put</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"baz"</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1919810</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> map</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">put</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">System</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">currentTimeMillis</span><span style="color:#D4D4D4;">() / </span><span style="color:#B5CEA8;">1000</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> param</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">map</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">entrySet</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">stream</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;">(it </span><span style="color:#569CD6;">-></span><span style="color:#9CDCFE;"> String</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">format</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"%s=%s"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">it</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getKey</span><span style="color:#D4D4D4;">(), </span><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">it</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getValue</span><span style="color:#D4D4D4;">())))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">collect</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">Collectors</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">joining</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> s</span><span style="color:#D4D4D4;"> = param + mixinKey;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> wbiSign</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">md5</span><span style="color:#D4D4D4;">(s);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">println</span><span style="color:#D4D4D4;">(wbiSign);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> finalParam</span><span style="color:#D4D4D4;"> = param + </span><span style="color:#CE9178;">"&w_rid="</span><span style="color:#D4D4D4;"> + wbiSign;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">println</span><span style="color:#D4D4D4;">(finalParam);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="kotlin" tabindex="-1"><a class="header-anchor" href="#kotlin"><span>Kotlin</span></a></h3><p>说明: 为了便于使用和缓存, 重新编写为实体类形式, 并拆分了多个文件. 使用官方的JSON序列化. (可以根据需要换成其他的)</p><p>WbiParams.kt</p><div class="language-kotlin line-numbers-mode" data-highlighter="shiki" data-ext="kotlin" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-kotlin"><span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> kotlinx.serialization.Serializable</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> kotlinx.serialization.json.JsonElement</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> kotlinx.serialization.json.JsonObject</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> kotlinx.serialization.json.jsonPrimitive</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">private</span><span style="color:#569CD6;"> fun</span><span style="color:#DCDCAA;"> JsonElement</span><span style="color:#D4D4D4;">?.</span><span style="color:#DCDCAA;">get</span><span style="color:#D4D4D4;">(): </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> check</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">this</span><span style="color:#D4D4D4;"> != </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;">) { </span><span style="color:#CE9178;">"No contents found"</span><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> this</span><span style="color:#D4D4D4;">.jsonPrimitive.content.</span><span style="color:#DCDCAA;">split</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'/'</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">last</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">removeSuffix</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">".png"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">private</span><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> mixinKeyEncTab = </span><span style="color:#DCDCAA;">intArrayOf</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;">@Serializable</span></span>
|
||
<span class="line"><span style="color:#569CD6;">data</span><span style="color:#569CD6;"> class</span><span style="color:#4EC9B0;"> WbiParams</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> imgKey: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> subKey: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 此处整合了切分参数(直接传入{img_url:string, sub_url:string}即可), 不需要可以删掉</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> constructor</span><span style="color:#D4D4D4;">(wbiImg: </span><span style="color:#4EC9B0;">JsonObject</span><span style="color:#D4D4D4;">) : </span><span style="color:#4EC9B0;">this</span><span style="color:#D4D4D4;">(wbiImg[</span><span style="color:#CE9178;">"img_url"</span><span style="color:#D4D4D4;">].</span><span style="color:#DCDCAA;">get</span><span style="color:#D4D4D4;">(), wbiImg[</span><span style="color:#CE9178;">"sub_url"</span><span style="color:#D4D4D4;">].</span><span style="color:#DCDCAA;">get</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> mixinKey: </span><span style="color:#4EC9B0;">String</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> get</span><span style="color:#D4D4D4;">() = (imgKey + subKey).</span><span style="color:#DCDCAA;">let</span><span style="color:#D4D4D4;"> { s </span><span style="color:#569CD6;">-></span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> buildString</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> repeat</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(s[mixinKeyEncTab[it]])</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 创建对象(GET获取或者读缓存, 比如Redis)之后, 直接调用此函数处理</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> fun</span><span style="color:#DCDCAA;"> enc</span><span style="color:#D4D4D4;">(params: </span><span style="color:#4EC9B0;">Map</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">Any</span><span style="color:#D4D4D4;">?>): </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> sorted = params.</span><span style="color:#DCDCAA;">filterValues</span><span style="color:#D4D4D4;"> { it != </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;"> }.</span><span style="color:#DCDCAA;">toSortedMap</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#DCDCAA;"> buildString</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(sorted.</span><span style="color:#DCDCAA;">toQueryString</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> wts = System.</span><span style="color:#DCDCAA;">currentTimeMillis</span><span style="color:#D4D4D4;">() / </span><span style="color:#B5CEA8;">1000</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> sorted[</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">] = wts</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&wts="</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(wts)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&w_rid="</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">((sorted.</span><span style="color:#DCDCAA;">toQueryString</span><span style="color:#D4D4D4;">() + mixinKey).</span><span style="color:#DCDCAA;">toMD5</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Extensions.kt</p><div class="language-kotlin line-numbers-mode" data-highlighter="shiki" data-ext="kotlin" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-kotlin"><span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.security.MessageDigest</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">private</span><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> hexDigits = </span><span style="color:#CE9178;">"0123456789abcdef"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toCharArray</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fun</span><span style="color:#4EC9B0;"> ByteArray</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toHexString</span><span style="color:#D4D4D4;">() = </span><span style="color:#DCDCAA;">buildString</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">this</span><span style="color:#D4D4D4;">.size shl </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> this@toHexString</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">forEach</span><span style="color:#D4D4D4;"> { byte </span><span style="color:#569CD6;">-></span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(hexDigits[byte.</span><span style="color:#DCDCAA;">toInt</span><span style="color:#D4D4D4;">() ushr </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;"> and </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">])</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> append</span><span style="color:#D4D4D4;">(hexDigits[byte.</span><span style="color:#DCDCAA;">toInt</span><span style="color:#D4D4D4;">() and </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">])</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fun</span><span style="color:#4EC9B0;"> String</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toMD5</span><span style="color:#D4D4D4;">(): </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> md = MessageDigest.</span><span style="color:#DCDCAA;">getInstance</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"MD5"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> val</span><span style="color:#D4D4D4;"> digest = md.</span><span style="color:#DCDCAA;">digest</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">this</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toByteArray</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> digest.</span><span style="color:#DCDCAA;">toHexString</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fun</span><span style="color:#DCDCAA;"> Map</span><span style="color:#D4D4D4;"><String, Any?>.</span><span style="color:#DCDCAA;">toQueryString</span><span style="color:#D4D4D4;">() = </span><span style="color:#569CD6;">this</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">filterValues</span><span style="color:#D4D4D4;"> { it != </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;"> }.entries.</span><span style="color:#DCDCAA;">joinToString</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">) { (k, v) </span><span style="color:#569CD6;">-></span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "</span><span style="color:#569CD6;">${</span><span style="color:#D4D4D4;">k.</span><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;">()</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">=</span><span style="color:#569CD6;">${</span><span style="color:#D4D4D4;">v!!.</span><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;">()</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>获取和使用案例略</p><h3 id="php" tabindex="-1"><a class="header-anchor" href="#php"><span>PHP</span></a></h3><p>来自<a href="https://github.com/SocialSisterYi/bilibili-API-collect/issues/813" target="_blank" rel="noopener noreferrer">SocialSisterYi/bilibili-API-collect#813</a></p><div class="language-php line-numbers-mode" data-highlighter="shiki" data-ext="php" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-php"><span class="line"><span style="color:#D4D4D4;"><?php</span></span>
|
||
<span class="line"><span style="color:#6A9955;">/**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * B站 Wbi 测试</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@author</span><span style="color:#6A9955;"> Prk</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">class</span><span style="color:#4EC9B0;"> Bilibili</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#9CDCFE;"> $mixinKeyEncTab</span><span style="color:#D4D4D4;"> = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> __construct</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> reQuery</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">array</span><span style="color:#9CDCFE;"> $query</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $wbi_keys</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">$this</span><span style="color:#D4D4D4;">-></span><span style="color:#DCDCAA;">getWbiKeys</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#569CD6;"> $this</span><span style="color:#D4D4D4;">-></span><span style="color:#DCDCAA;">encWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$query</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$wbi_keys</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">'img_key'</span><span style="color:#D4D4D4;">], </span><span style="color:#9CDCFE;">$wbi_keys</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">'sub_key'</span><span style="color:#D4D4D4;">]);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$orig</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $t</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> foreach</span><span style="color:#D4D4D4;"> (</span><span style="color:#569CD6;">$this</span><span style="color:#D4D4D4;">-></span><span style="color:#9CDCFE;">mixinKeyEncTab</span><span style="color:#D4D4D4;"> as </span><span style="color:#9CDCFE;">$n</span><span style="color:#D4D4D4;">) </span><span style="color:#9CDCFE;">$t</span><span style="color:#D4D4D4;"> .=</span><span style="color:#9CDCFE;"> $orig</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">$n</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#DCDCAA;"> substr</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$t</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> encWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$params</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$img_key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$sub_key</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $mixin_key</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">$this</span><span style="color:#D4D4D4;">-></span><span style="color:#DCDCAA;">getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$img_key</span><span style="color:#D4D4D4;"> .</span><span style="color:#9CDCFE;"> $sub_key</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $curr_time</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">time</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $chr_filter</span><span style="color:#D4D4D4;"> = </span><span style="color:#D16969;">"/[!'()*]/"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $query</span><span style="color:#D4D4D4;"> = [];</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">'wts'</span><span style="color:#D4D4D4;">] = </span><span style="color:#9CDCFE;">$curr_time</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> ksort</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$params</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> foreach</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">$params</span><span style="color:#D4D4D4;"> as </span><span style="color:#9CDCFE;">$key</span><span style="color:#D4D4D4;"> => </span><span style="color:#9CDCFE;">$value</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $value</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">preg_replace</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$chr_filter</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$value</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $query</span><span style="color:#D4D4D4;">[] = </span><span style="color:#DCDCAA;">urlencode</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$key</span><span style="color:#D4D4D4;">) </span><span style="color:#D4D4D4;">.</span><span style="color:#CE9178;"> '='</span><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;"> urlencode</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$value</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $query</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">implode</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'&'</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$query</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $wbi_sign</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">md5</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$query</span><span style="color:#D4D4D4;"> .</span><span style="color:#9CDCFE;"> $mixin_key</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> $query</span><span style="color:#D4D4D4;"> .</span><span style="color:#CE9178;"> '&w_rid='</span><span style="color:#D4D4D4;"> .</span><span style="color:#9CDCFE;"> $wbi_sign</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> getWbiKeys</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $resp</span><span style="color:#D4D4D4;"> = @</span><span style="color:#DCDCAA;">json_decode</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> $this</span><span style="color:#D4D4D4;">-></span><span style="color:#DCDCAA;">curl_get</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'https://api.bilibili.com/x/web-interface/nav'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> null</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'https://www.bilibili.com/'</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ), </span><span style="color:#569CD6;">true</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> (!</span><span style="color:#9CDCFE;">$resp</span><span style="color:#D4D4D4;">) </span><span style="color:#C586C0;">throw</span><span style="color:#569CD6;"> new</span><span style="color:#4EC9B0;"> Exception</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'请求失败'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $img_url</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">$resp</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">'data'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'wbi_img'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'img_url'</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $sub_url</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">$resp</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">'data'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'wbi_img'</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">'sub_url'</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> [</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'img_key'</span><span style="color:#D4D4D4;"> => </span><span style="color:#DCDCAA;">substr</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">basename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$img_url</span><span style="color:#D4D4D4;">), </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">strpos</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">basename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$img_url</span><span style="color:#D4D4D4;">), </span><span style="color:#CE9178;">'.'</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'sub_key'</span><span style="color:#D4D4D4;"> => </span><span style="color:#DCDCAA;">substr</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">basename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$sub_url</span><span style="color:#D4D4D4;">), </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">strpos</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">basename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$sub_url</span><span style="color:#D4D4D4;">), </span><span style="color:#CE9178;">'.'</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ];</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> private</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> curl_get</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$url</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$cookies</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$referer</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">'https://www.bilibili.com/'</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$ua</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$proxy</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">null</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">$header</span><span style="color:#D4D4D4;"> = []) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $ch</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">curl_init</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $header</span><span style="color:#D4D4D4;">[] = </span><span style="color:#CE9178;">"Accept: */*"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $header</span><span style="color:#D4D4D4;">[] = </span><span style="color:#CE9178;">"Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $header</span><span style="color:#D4D4D4;">[] = </span><span style="color:#CE9178;">"Connection: close"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $header</span><span style="color:#D4D4D4;">[]=</span><span style="color:#CE9178;">"Referer:https://www.bilibili.com/"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $header</span><span style="color:#D4D4D4;">[] = </span><span style="color:#CE9178;">"Cache-Control: max-age=0"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> curl_setopt_array</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$ch</span><span style="color:#D4D4D4;">, [</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_HTTPGET => </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_CUSTOMREQUEST => </span><span style="color:#CE9178;">'GET'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_RETURNTRANSFER => </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_HTTPHEADER => </span><span style="color:#9CDCFE;">$header</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_ENCODING => </span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_URL => </span><span style="color:#9CDCFE;">$url</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_USERAGENT => </span><span style="color:#CE9178;">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.39'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_TIMEOUT => </span><span style="color:#B5CEA8;">15</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">$cookies</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">curl_setopt</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $ch</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_COOKIE,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $cookies</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">$referer</span><span style="color:#D4D4D4;">) </span><span style="color:#DCDCAA;">curl_setopt_array</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$ch</span><span style="color:#D4D4D4;">, [</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_AUTOREFERER => </span><span style="color:#9CDCFE;">$referer</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_REFERER => </span><span style="color:#9CDCFE;">$referer</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> $content</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">curl_exec</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$ch</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> curl_close</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">$ch</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> $content</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#9CDCFE;">$c</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#4EC9B0;"> Bilibili</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">echo</span><span style="color:#9CDCFE;"> $c</span><span style="color:#D4D4D4;">-></span><span style="color:#DCDCAA;">reQuery</span><span style="color:#D4D4D4;">([</span><span style="color:#CE9178;">'foo'</span><span style="color:#D4D4D4;"> => </span><span style="color:#CE9178;">'114'</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'bar'</span><span style="color:#D4D4D4;"> => </span><span style="color:#CE9178;">'514'</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'baz'</span><span style="color:#D4D4D4;"> => </span><span style="color:#B5CEA8;">1919810</span><span style="color:#D4D4D4;">]);</span></span>
|
||
<span class="line"><span style="color:#6A9955;">// bar=514&baz=1919810&foo=114&wts=1700384803&w_rid=4614cb98d60a43e50c3a3033fe3d116b</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="rust" tabindex="-1"><a class="header-anchor" href="#rust"><span>Rust</span></a></h3><p>需要 serde、serde_json、reqwest、tokio 以及 md5</p><div class="language-rust line-numbers-mode" data-highlighter="shiki" data-ext="rust" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-rust"><span class="line"><span style="color:#569CD6;">use</span><span style="color:#4EC9B0;"> reqwest</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">header</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">USER_AGENT</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">use</span><span style="color:#4EC9B0;"> serde</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">Deserialize</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">use</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">time</span><span style="color:#D4D4D4;">::{</span><span style="color:#4EC9B0;">SystemTime</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">UNIX_EPOCH</span><span style="color:#D4D4D4;">};</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">const</span><span style="color:#D4D4D4;"> MIXIN_KEY_ENC_TAB: [</span><span style="color:#4EC9B0;">usize</span><span style="color:#D4D4D4;">; </span><span style="color:#B5CEA8;">64</span><span style="color:#D4D4D4;">] = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">#[derive(</span><span style="color:#4EC9B0;">Deserialize</span><span style="color:#D4D4D4;">)]</span></span>
|
||
<span class="line"><span style="color:#569CD6;">struct</span><span style="color:#4EC9B0;"> WbiImg</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> img_url</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> sub_url</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">#[derive(</span><span style="color:#4EC9B0;">Deserialize</span><span style="color:#D4D4D4;">)]</span></span>
|
||
<span class="line"><span style="color:#569CD6;">struct</span><span style="color:#4EC9B0;"> Data</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> wbi_img</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">WbiImg</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">#[derive(</span><span style="color:#4EC9B0;">Deserialize</span><span style="color:#D4D4D4;">)]</span></span>
|
||
<span class="line"><span style="color:#569CD6;">struct</span><span style="color:#4EC9B0;"> ResWbi</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> data</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Data</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// 对 imgKey 和 subKey 进行字符顺序打乱编码</span></span>
|
||
<span class="line"><span style="color:#569CD6;">fn</span><span style="color:#DCDCAA;"> get_mixin_key</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">orig</span><span style="color:#D4D4D4;">: &[</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">]) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> MIXIN_KEY_ENC_TAB</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">iter</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">take</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;">(|&</span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">| </span><span style="color:#9CDCFE;">orig</span><span style="color:#D4D4D4;">[</span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;">] </span><span style="color:#569CD6;">as</span><span style="color:#4EC9B0;"> char</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">collect</span><span style="color:#D4D4D4;">::<</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">>()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fn</span><span style="color:#DCDCAA;"> get_url_encoded</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">: &</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> s</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">chars</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">filter_map</span><span style="color:#D4D4D4;">(|</span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;">| </span><span style="color:#C586C0;">match</span><span style="color:#9CDCFE;"> c</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">is_ascii_alphanumeric</span><span style="color:#D4D4D4;">() || </span><span style="color:#CE9178;">"-_.~"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">contains</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> true</span><span style="color:#D4D4D4;"> => </span><span style="color:#4EC9B0;">Some</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">()),</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> false</span><span style="color:#D4D4D4;"> => {</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 过滤 value 中的 "!'()*" 字符</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#CE9178;"> "!'()*"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">contains</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">c</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#4EC9B0;"> None</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> encoded</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">c</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">encode_utf8</span><span style="color:#D4D4D4;">(&</span><span style="color:#569CD6;">mut</span><span style="color:#D4D4D4;"> [</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">; </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">])</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">bytes</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">fold</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">(), |</span><span style="color:#9CDCFE;">acc</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">| </span><span style="color:#9CDCFE;">acc</span><span style="color:#D4D4D4;"> + &</span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"%{:02X}"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Some</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">encoded</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> })</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">collect</span><span style="color:#D4D4D4;">::<</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">>()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// 为请求参数进行 wbi 签名</span></span>
|
||
<span class="line"><span style="color:#569CD6;">fn</span><span style="color:#DCDCAA;"> encode_wbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;"><(&</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">)>, (</span><span style="color:#9CDCFE;">img_key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">sub_key</span><span style="color:#D4D4D4;">): (</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">)) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> cur_time</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">match</span><span style="color:#4EC9B0;"> SystemTime</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">now</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">duration_since</span><span style="color:#D4D4D4;">(UNIX_EPOCH) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Ok</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">t</span><span style="color:#D4D4D4;">) => </span><span style="color:#9CDCFE;">t</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">as_secs</span><span style="color:#D4D4D4;">(),</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Err</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;">) => </span><span style="color:#DCDCAA;">panic!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"SystemTime before UNIX EPOCH!"</span><span style="color:#D4D4D4;">),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> _encode_wbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">, (</span><span style="color:#9CDCFE;">img_key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">sub_key</span><span style="color:#D4D4D4;">), </span><span style="color:#9CDCFE;">cur_time</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fn</span><span style="color:#DCDCAA;"> _encode_wbi</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> mut</span><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;"><(&</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">)>,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">img_key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">sub_key</span><span style="color:#D4D4D4;">): (</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">),</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> timestamp</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">u64</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> mixin_key</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">get_mixin_key</span><span style="color:#D4D4D4;">((</span><span style="color:#9CDCFE;">img_key</span><span style="color:#D4D4D4;"> + &</span><span style="color:#9CDCFE;">sub_key</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">as_bytes</span><span style="color:#D4D4D4;">());</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 添加当前时间戳</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">push</span><span style="color:#D4D4D4;">((</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">timestamp</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">()));</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 重新排序</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">sort_by</span><span style="color:#D4D4D4;">(|</span><span style="color:#9CDCFE;">a</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">| </span><span style="color:#9CDCFE;">a</span><span style="color:#D4D4D4;">.</span><span style="color:#B5CEA8;">0.</span><span style="color:#DCDCAA;">cmp</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">b</span><span style="color:#D4D4D4;">.</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 拼接参数</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> query</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">params</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">iter</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;">(|(</span><span style="color:#9CDCFE;">k</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">v</span><span style="color:#D4D4D4;">)| </span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"{}={}"</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">get_url_encoded</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">k</span><span style="color:#D4D4D4;">), </span><span style="color:#DCDCAA;">get_url_encoded</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">v</span><span style="color:#D4D4D4;">)))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">collect</span><span style="color:#D4D4D4;">::<</span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;"><</span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;">>>()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">join</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 计算签名</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> web_sign</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"{:?}"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">md5</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">compute</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">query</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">clone</span><span style="color:#D4D4D4;">() + &</span><span style="color:#9CDCFE;">mixin_key</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // 返回最终的 query</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> query</span><span style="color:#D4D4D4;"> + &</span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&w_rid={}"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">web_sign</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">async</span><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> get_wbi_keys</span><span style="color:#D4D4D4;">() -> </span><span style="color:#4EC9B0;">Result</span><span style="color:#D4D4D4;"><(</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">), </span><span style="color:#9CDCFE;">reqwest</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">Error</span><span style="color:#D4D4D4;">> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> client</span><span style="color:#D4D4D4;"> = </span><span style="color:#4EC9B0;">reqwest</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">Client</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">new</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#4EC9B0;"> ResWbi</span><span style="color:#D4D4D4;"> { </span><span style="color:#9CDCFE;">data</span><span style="color:#D4D4D4;">:</span><span style="color:#4EC9B0;">Data</span><span style="color:#D4D4D4;">{</span><span style="color:#9CDCFE;">wbi_img</span><span style="color:#D4D4D4;">} } = </span><span style="color:#9CDCFE;">client</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">get</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://api.bilibili.com/x/web-interface/nav"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">header</span><span style="color:#D4D4D4;">(USER_AGENT,</span><span style="color:#CE9178;">"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">header</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"Referer"</span><span style="color:#D4D4D4;">,</span><span style="color:#CE9178;">"https://www.bilibili.com/"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // SESSDATA=xxxxx</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">header</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"Cookie"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"SESSDATA=xxxxx"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">send</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#C586C0;">await</span><span style="color:#D4D4D4;">?</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">json</span><span style="color:#D4D4D4;">::<</span><span style="color:#4EC9B0;">ResWbi</span><span style="color:#D4D4D4;">>()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#C586C0;">await</span><span style="color:#D4D4D4;">?;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Ok</span><span style="color:#D4D4D4;">((</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> take_filename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">wbi_img</span><span style="color:#D4D4D4;">.img_url).</span><span style="color:#DCDCAA;">unwrap</span><span style="color:#D4D4D4;">(),</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> take_filename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">wbi_img</span><span style="color:#D4D4D4;">.sub_url).</span><span style="color:#DCDCAA;">unwrap</span><span style="color:#D4D4D4;">(),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">fn</span><span style="color:#DCDCAA;"> take_filename</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">url</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">) -> </span><span style="color:#4EC9B0;">Option</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">rsplit_once</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'/'</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">and_then</span><span style="color:#D4D4D4;">(|(</span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">)| </span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">rsplit_once</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'.'</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;">(|(</span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;">)| </span><span style="color:#9CDCFE;">s</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">#[tokio::main]</span></span>
|
||
<span class="line"><span style="color:#569CD6;">async</span><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> main</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> keys</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">get_wbi_keys</span><span style="color:#D4D4D4;">().</span><span style="color:#C586C0;">await</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">unwrap</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">vec!</span><span style="color:#D4D4D4;">[</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"foo"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"114"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"bar"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"514"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"baz"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"1919810"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ];</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> query</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">encode_wbi</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">keys</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> println!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"{}"</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">query</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// 取自文档描述的测试用例</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">#[cfg(test)]</span></span>
|
||
<span class="line"><span style="color:#569CD6;">mod</span><span style="color:#D4D4D4;"> tests {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> use</span><span style="color:#569CD6;"> super</span><span style="color:#D4D4D4;">::*;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> #[test]</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> test_get_filename</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> assert_eq!</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> take_filename</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ),</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Some</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"7cd084941338484aae1ad9425b84077c"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">())</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> #[test]</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> test_get_mixin_key</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> concat_key</span><span style="color:#D4D4D4;"> =</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "7cd084941338484aae1ad9425b84077c"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">() + </span><span style="color:#CE9178;">"4932caff0ff746eab6f01bf08b70ac45"</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> assert_eq!</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> get_mixin_key</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">concat_key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">as_bytes</span><span style="color:#D4D4D4;">()),</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "ea1db124af3c7062474693fa704f4ff8"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> #[test]</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> fn</span><span style="color:#DCDCAA;"> test_encode_wbi</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">vec!</span><span style="color:#D4D4D4;">[</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"foo"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"114"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"bar"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"514"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">"zab"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">from</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"1919810"</span><span style="color:#D4D4D4;">)),</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ];</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> assert_eq!</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> _encode_wbi</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> params</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "7cd084941338484aae1ad9425b84077c"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">(),</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "4932caff0ff746eab6f01bf08b70ac45"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ),</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 1702204169</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ),</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "bar=514&foo=114&wts=1702204169&zab=1919810&w_rid=8f6f2b5b3d485fe1886cec6a0be8c5d4"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> )</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="swift" tabindex="-1"><a class="header-anchor" href="#swift"><span>Swift</span></a></h3><p>需要 <a href="https://github.com/Alamofire/Alamofire" target="_blank" rel="noopener noreferrer">Alamofire</a> 和 <a href="https://github.com/SwiftyJSON/SwiftyJSON" target="_blank" rel="noopener noreferrer">SwiftyJSON</a> 库</p><div class="language-swift line-numbers-mode" data-highlighter="shiki" data-ext="swift" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-swift"><span class="line"><span style="color:#C586C0;">import</span><span style="color:#4EC9B0;"> Alamofire</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#4EC9B0;"> CommonCrypto</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#4EC9B0;"> Foundation</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#4EC9B0;"> SwiftyJSON</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">func</span><span style="color:#DCDCAA;"> biliWbiSign</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">param</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">completion</span><span style="color:#D4D4D4;">: </span><span style="color:#569CD6;">@escaping</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">?) -> </span><span style="color:#4EC9B0;">Void</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> func</span><span style="color:#DCDCAA;"> getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">orig</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#4EC9B0;"> String</span><span style="color:#D4D4D4;">(mixinKeyEncTab.</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;"> { orig[orig.</span><span style="color:#DCDCAA;">index</span><span style="color:#D4D4D4;">(orig.</span><span style="color:#9CDCFE;">startIndex</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">offsetBy</span><span style="color:#D4D4D4;">: </span><span style="color:#569CD6;">$0</span><span style="color:#D4D4D4;">)] }.</span><span style="color:#DCDCAA;">prefix</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> func</span><span style="color:#DCDCAA;"> encWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">params</span><span style="color:#D4D4D4;">: [</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Any</span><span style="color:#D4D4D4;">], </span><span style="color:#DCDCAA;">imgKey</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">subKey</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">) -> [</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Any</span><span style="color:#D4D4D4;">] {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#D4D4D4;"> params = params</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> mixinKey = </span><span style="color:#DCDCAA;">getMixinKey</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">orig</span><span style="color:#D4D4D4;">: imgKey + subKey)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> currTime = </span><span style="color:#4EC9B0;">Int</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">Date</span><span style="color:#D4D4D4;">().</span><span style="color:#9CDCFE;">timeIntervalSince1970</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params[</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">] = currTime</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> query = params.</span><span style="color:#DCDCAA;">sorted</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> $0</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">key</span><span style="color:#D4D4D4;"> < </span><span style="color:#569CD6;">$1</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">key</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }.</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;"> { (key, value) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#C586C0;"> in</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> stringValue: </span><span style="color:#4EC9B0;">String</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> doubleValue = value as? </span><span style="color:#4EC9B0;">Double</span><span style="color:#D4D4D4;">, doubleValue.</span><span style="color:#DCDCAA;">truncatingRemainder</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">dividingBy</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">) == </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> stringValue = </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">Int</span><span style="color:#D4D4D4;">(doubleValue))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#C586C0;">else</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> stringValue = </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">describing</span><span style="color:#D4D4D4;">: value)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> filteredValue = stringValue.</span><span style="color:#DCDCAA;">filter</span><span style="color:#D4D4D4;"> { !</span><span style="color:#CE9178;">"!'()*"</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">contains</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">$0</span><span style="color:#D4D4D4;">) }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#CE9178;"> "</span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">key</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">=</span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">filteredValue</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }.</span><span style="color:#DCDCAA;">joined</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separator</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> wbiSign = </span><span style="color:#DCDCAA;">calculateMD5</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">string</span><span style="color:#D4D4D4;">: query + mixinKey)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params[</span><span style="color:#CE9178;">"w_rid"</span><span style="color:#D4D4D4;">] = wbiSign</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> params</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> func</span><span style="color:#DCDCAA;"> getWbiKeys</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">completion</span><span style="color:#D4D4D4;">: </span><span style="color:#569CD6;">@escaping</span><span style="color:#D4D4D4;"> (Result<(imgKey: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, subKey: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">), </span><span style="color:#4EC9B0;">Error</span><span style="color:#D4D4D4;">>) -> </span><span style="color:#4EC9B0;">Void</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> headers: HTTPHeaders = [</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "User-Agent"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "Referer"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"https://www.bilibili.com/"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> AF.</span><span style="color:#DCDCAA;">request</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"https://api.bilibili.com/x/web-interface/nav"</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">headers</span><span style="color:#D4D4D4;">: headers).</span><span style="color:#DCDCAA;">responseJSON</span><span style="color:#D4D4D4;"> { response </span><span style="color:#C586C0;">in</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> switch</span><span style="color:#D4D4D4;"> response.result {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> case</span><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">success</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">let</span><span style="color:#D4D4D4;"> value):</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> json = </span><span style="color:#DCDCAA;">JSON</span><span style="color:#D4D4D4;">(value)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> imgURL = json[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"img_url"</span><span style="color:#D4D4D4;">].</span><span style="color:#9CDCFE;">string</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">""</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> subURL = json[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"sub_url"</span><span style="color:#D4D4D4;">].</span><span style="color:#9CDCFE;">string</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">""</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> imgKey = imgURL.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">last</span><span style="color:#D4D4D4;">?.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"."</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">first</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">""</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> subKey = subURL.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"/"</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">last</span><span style="color:#D4D4D4;">?.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"."</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">first</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">""</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> completion</span><span style="color:#D4D4D4;">(.</span><span style="color:#DCDCAA;">success</span><span style="color:#D4D4D4;">((imgKey, subKey)))</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> case</span><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">failure</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">let</span><span style="color:#D4D4D4;"> error):</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> completion</span><span style="color:#D4D4D4;">(.</span><span style="color:#DCDCAA;">failure</span><span style="color:#D4D4D4;">(error))</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> func</span><span style="color:#DCDCAA;"> calculateMD5</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">string</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">) -> </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> data = </span><span style="color:#DCDCAA;">Data</span><span style="color:#D4D4D4;">(string.</span><span style="color:#9CDCFE;">utf8</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#D4D4D4;"> digest = [</span><span style="color:#4EC9B0;">UInt8</span><span style="color:#D4D4D4;">](</span><span style="color:#DCDCAA;">repeating</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">count</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">Int</span><span style="color:#D4D4D4;">(CC_MD5_DIGEST_LENGTH))</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> _</span><span style="color:#D4D4D4;"> = data.</span><span style="color:#DCDCAA;">withUnsafeBytes</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> CC_MD5</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">$0</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">baseAddress</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">CC_LONG</span><span style="color:#D4D4D4;">(data.</span><span style="color:#9CDCFE;">count</span><span style="color:#D4D4D4;">), &digest)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> digest.</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;"> { </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">format</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"%02hhx"</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">$0</span><span style="color:#D4D4D4;">) }.</span><span style="color:#DCDCAA;">joined</span><span style="color:#D4D4D4;">()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> mixinKeyEncTab = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> getWbiKeys</span><span style="color:#D4D4D4;"> { result </span><span style="color:#C586C0;">in</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> switch</span><span style="color:#D4D4D4;"> result {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> case</span><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">success</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">let</span><span style="color:#D4D4D4;"> keys):</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> spdParam = param.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> var</span><span style="color:#D4D4D4;"> spdDicParam = [</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">: </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">]()</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> pair </span><span style="color:#C586C0;">in</span><span style="color:#D4D4D4;"> spdParam {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> components = pair.</span><span style="color:#DCDCAA;">components</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separatedBy</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"="</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> components.</span><span style="color:#9CDCFE;">count</span><span style="color:#D4D4D4;"> == </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> spdDicParam[components[</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">]] = components[</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> signedParams = </span><span style="color:#DCDCAA;">encWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">params</span><span style="color:#D4D4D4;">: spdDicParam, </span><span style="color:#DCDCAA;">imgKey</span><span style="color:#D4D4D4;">: keys.</span><span style="color:#9CDCFE;">imgKey</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">subKey</span><span style="color:#D4D4D4;">: keys.</span><span style="color:#9CDCFE;">subKey</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> query = signedParams.</span><span style="color:#DCDCAA;">map</span><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">"</span><span style="color:#569CD6;">\($0</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">key</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">=</span><span style="color:#569CD6;">\($0</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">value</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;"> }.</span><span style="color:#DCDCAA;">joined</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">separator</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> completion</span><span style="color:#D4D4D4;">(query)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> case</span><span style="color:#D4D4D4;"> .</span><span style="color:#DCDCAA;">failure</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">let</span><span style="color:#D4D4D4;"> error):</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> print</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"Error getting keys: </span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">error</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> completion</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">// 使用示例</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">biliWbiSign</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">param</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"bar=514&foo=114&zab=1919810"</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> signedQuery </span><span style="color:#C586C0;">in</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> signedQuery = signedQuery {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> print</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"签名后的参数: </span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">signedQuery</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#C586C0;">else</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> print</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"签名失败"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">RunLoop.</span><span style="color:#9CDCFE;">main</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">run</span><span style="color:#D4D4D4;">()</span><span style="color:#6A9955;">//程序类型为命令行程序时需要添加这行代码</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-text line-numbers-mode" data-highlighter="shiki" data-ext="text" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-text"><span class="line"><span>签名后的参数: bar=514&wts=1741082093&foo=114&zab=1919810&w_rid=04775bb3debbb45bab86a93a1c08d12a</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="cplusplus" tabindex="-1"><a class="header-anchor" href="#cplusplus"><span>CPlusPlus</span></a></h3><p>需要 c++ 23 标准库,<a href="https://github.com/libcpr/cpr" target="_blank" rel="noopener noreferrer">cpr</a>、<a href="https://github.com/weidai11/cryptopp" target="_blank" rel="noopener noreferrer">cryptopp</a>、<a href="https://github.com/nlohmann/json" target="_blank" rel="noopener noreferrer">nlohmann/json</a> 等依赖</p><div class="language-c++ line-numbers-mode" data-highlighter="shiki" data-ext="c++" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-c++"><span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <array></span><span style="color:#6A9955;"> // std::array</span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <locale></span><span style="color:#6A9955;"> // std::locale</span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <print></span><span style="color:#6A9955;"> // std::println</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">/// thrid party libraries</span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <cpr/cpr.h></span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <cryptopp/md5.h></span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <cryptopp/hex.h></span></span>
|
||
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> <nlohmann/json.hpp></span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">/*</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * 注意,假定不会发生错误!</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;">class</span><span style="color:#4EC9B0;"> Wbi</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> constexpr</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::array<</span><span style="color:#569CD6;">uint8_t</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">64</span><span style="color:#D4D4D4;">> MIXIN_KEY_ENC_TAB_ = {</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /* 获取 md5 hex(lower) */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#DCDCAA;"> Get_md5_hex</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Input_str</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> CryptoPP</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">Weak1</span><span style="color:#D4D4D4;">::MD5 hash;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string md5_hex;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> CryptoPP</span><span style="color:#D4D4D4;">::StringSource </span><span style="color:#DCDCAA;">ss</span><span style="color:#D4D4D4;">(Input_str, </span><span style="color:#569CD6;">true</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> new</span><span style="color:#4EC9B0;"> CryptoPP</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">HashFilter</span><span style="color:#D4D4D4;">(hash,</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> new</span><span style="color:#4EC9B0;"> CryptoPP</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">HexEncoder</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> new</span><span style="color:#4EC9B0;"> CryptoPP</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">StringSink</span><span style="color:#D4D4D4;">(md5_hex)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> )</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> )</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> );</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">ranges</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">for_each</span><span style="color:#D4D4D4;">(md5_hex, [](</span><span style="color:#569CD6;">char</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">x</span><span style="color:#D4D4D4;">) { x = </span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">tolower</span><span style="color:#D4D4D4;">(x); });</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> md5_hex;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">public:</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> /* 将 json 转换为 url 编码字符串 */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#DCDCAA;"> Json_to_url_encode_str</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">const</span><span style="color:#4EC9B0;"> nlohmann</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">json</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Json</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string encode_str;</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> (</span><span style="color:#569CD6;">const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> &[key, value]: </span><span style="color:#9CDCFE;">Json</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">items</span><span style="color:#D4D4D4;">()) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> encode_str</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(key).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"="</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">cpr</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">util</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">urlEncode</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">value</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">is_string</span><span style="color:#D4D4D4;">() ? </span><span style="color:#9CDCFE;">value</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">get</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::string>() : </span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">(value))).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"&"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> // remove the last '&'</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> encode_str</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">resize</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">encode_str</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">size</span><span style="color:#D4D4D4;">() - </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">'</span><span style="color:#D7BA7D;">\0</span><span style="color:#CE9178;">'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> encode_str;</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /* 获取 wbi key */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">pair</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">> </span><span style="color:#DCDCAA;">Get_wbi_key</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> url = </span><span style="color:#4EC9B0;">cpr</span><span style="color:#D4D4D4;">::Url {</span><span style="color:#CE9178;">"https://api.bilibili.com/x/web-interface/nav"</span><span style="color:#D4D4D4;">};</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> cookie = </span><span style="color:#4EC9B0;">cpr</span><span style="color:#D4D4D4;">::Cookies {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span><span style="color:#CE9178;">"SESSDATA"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"xxxxxxxxxxxx"</span><span style="color:#D4D4D4;">},</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> header = </span><span style="color:#4EC9B0;">cpr</span><span style="color:#D4D4D4;">::Header {</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span><span style="color:#CE9178;">"User-Agent"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"</span><span style="color:#D4D4D4;">},</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> {</span><span style="color:#CE9178;">"Referer"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"https://www.bilibili.com/"</span><span style="color:#D4D4D4;">},</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> };</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> response = </span><span style="color:#4EC9B0;">cpr</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">Get</span><span style="color:#D4D4D4;">(url, cookie, header);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> nlohmann</span><span style="color:#D4D4D4;">::json json = </span><span style="color:#4EC9B0;">nlohmann</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">json</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">parse</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">response</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">text</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string img_url = </span><span style="color:#9CDCFE;">json</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"img_url"</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string sub_url = </span><span style="color:#9CDCFE;">json</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"data"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"wbi_img"</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">"sub_url"</span><span style="color:#D4D4D4;">];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string img_key = </span><span style="color:#9CDCFE;">img_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">substr</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">img_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wbi/"</span><span style="color:#D4D4D4;">) + </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">img_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">".png"</span><span style="color:#D4D4D4;">) - </span><span style="color:#9CDCFE;">img_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wbi/"</span><span style="color:#D4D4D4;">) - </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string sub_key = </span><span style="color:#9CDCFE;">sub_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">substr</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">sub_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wbi/"</span><span style="color:#D4D4D4;">) + </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">sub_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">".png"</span><span style="color:#D4D4D4;">) - </span><span style="color:#9CDCFE;">sub_url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">find</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"wbi/"</span><span style="color:#D4D4D4;">) - </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> {img_key, sub_key};</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /* 获取 mixin key */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#DCDCAA;"> Get_mixin_key</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Img_key</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Sub_key</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string raw_wbi_key_str = Img_key + Sub_key;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string result;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">ranges</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">for_each</span><span style="color:#D4D4D4;">(MIXIN_KEY_ENC_TAB_, [&</span><span style="color:#9CDCFE;">result</span><span style="color:#D4D4D4;">, &</span><span style="color:#9CDCFE;">raw_wbi_key_str</span><span style="color:#D4D4D4;">](</span><span style="color:#569CD6;">const</span><span style="color:#569CD6;"> uint8_t</span><span style="color:#9CDCFE;"> x</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> result</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">push_back</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">raw_wbi_key_str</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">at</span><span style="color:#D4D4D4;">(x));</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> });</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> result</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">substr</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /* 计算签名(w_rid) */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#DCDCAA;"> Calc_sign</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">nlohmann</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">json</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Params</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">string</span><span style="color:#569CD6;"> &</span><span style="color:#9CDCFE;">Mixin_key</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;">] = </span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">chrono</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">duration_cast</span><span style="color:#D4D4D4;"><</span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">chrono</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">seconds</span><span style="color:#D4D4D4;">>(</span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">chrono</span><span style="color:#D4D4D4;">::</span><span style="color:#4EC9B0;">system_clock</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">now</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">time_since_epoch</span><span style="color:#D4D4D4;">()).</span><span style="color:#DCDCAA;">count</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::string encode_str = </span><span style="color:#DCDCAA;">Json_to_url_encode_str</span><span style="color:#D4D4D4;">(Params).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(Mixin_key);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#DCDCAA;"> Get_md5_hex</span><span style="color:#D4D4D4;">(encode_str);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">};</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">int</span><span style="color:#DCDCAA;"> main</span><span style="color:#D4D4D4;">() {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> nlohmann</span><span style="color:#D4D4D4;">::json Params;</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // qn=32&fnver=0&fnval=4048&fourk=1&avid=1755630705&cid=1574294582</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"qn"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"fnver"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"fnval"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">4048</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"fourk"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"avid"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">1755630705</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">"cid"</span><span style="color:#D4D4D4;">] = </span><span style="color:#B5CEA8;">1574294582</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> [img_key, sub_key] = </span><span style="color:#4EC9B0;">Wbi</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">Get_wbi_key</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> mixin_key = </span><span style="color:#4EC9B0;">Wbi</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">Get_mixin_key</span><span style="color:#D4D4D4;">(img_key, sub_key);</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#569CD6;"> auto</span><span style="color:#D4D4D4;"> w_rid = </span><span style="color:#4EC9B0;">Wbi</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">Calc_sign</span><span style="color:#D4D4D4;">(Params, mixin_key);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> std</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">println</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"{}"</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">Wbi</span><span style="color:#D4D4D4;">::</span><span style="color:#DCDCAA;">Json_to_url_encode_str</span><span style="color:#D4D4D4;">(Params) + </span><span style="color:#CE9178;">"&w_rid="</span><span style="color:#D4D4D4;"> + w_rid);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-text line-numbers-mode" data-highlighter="shiki" data-ext="text" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-text"><span class="line"><span>avid=1755630705&cid=1574294582&fnval=4048&fnver=0&fourk=1&qn=32&wts=1717922933&w_rid=43571b838a1611fa121189083cfc1784</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="haskell" tabindex="-1"><a class="header-anchor" href="#haskell"><span>Haskell</span></a></h3><p>无第三方依赖: <code>base</code>, <code>Cabal-syntax</code>, <code>bytestring</code>, <code>containers</code><br> 注: 此处使用自写的 URI 编码模块, 实际可用别的第三方库替代</p><p><code>Main.hs</code>:</p><div class="language-hs line-numbers-mode" data-highlighter="shiki" data-ext="hs" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-hs"><span class="line"><span style="color:#569CD6;">module</span><span style="color:#4EC9B0;"> Main</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">wbi</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">main</span><span style="color:#D4D4D4;">) </span><span style="color:#569CD6;">where</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Data.ByteString.Char8</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">pack</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#569CD6;"> qualified</span><span style="color:#4EC9B0;"> Data.Map.Strict</span><span style="color:#569CD6;"> as</span><span style="color:#4EC9B0;"> Map</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Distribution.Utils.MD5</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">md5</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">showMD5</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> URIEncoder</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Data.Time.Clock.System</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">getSystemTime</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">systemSeconds</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">mixinKeyEncTab</span><span style="color:#D4D4D4;"> :: [</span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">mixinKeyEncTab = [</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 46</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">47</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">53</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">8</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">23</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">32</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">15</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">50</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">58</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">3</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">45</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">35</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">27</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">43</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">5</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">49</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 33</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">9</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">42</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">19</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">29</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">28</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">14</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">39</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">38</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">41</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">13</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">37</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">48</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">7</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">24</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">55</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">40</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 61</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">26</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">17</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">60</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">51</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">30</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">22</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">25</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">54</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">21</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">56</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">59</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">63</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">57</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">62</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">11</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#B5CEA8;"> 36</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">20</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">34</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">44</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">52</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">getMixinKey</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">getMixinKey imgKey subKey =</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> s = imgKey ++ subKey</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> in</span><span style="color:#D4D4D4;"> map (\i -> s !! (mixinKeyEncTab !! i)) [</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">..</span><span style="color:#B5CEA8;">31</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">join</span><span style="color:#D4D4D4;"> :: [</span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;">] -> </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">join arr ins = concatMap (++ ins) (init arr) ++ last arr</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">wbi</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">Integer</span><span style="color:#D4D4D4;"> -> </span><span style="color:#4EC9B0;">Map.</span><span style="color:#569CD6;">Map</span><span style="color:#569CD6;"> String</span><span style="color:#569CD6;"> String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">wbi imgKey subKey wts params =</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> orig = join (map (\(k, v) -> encodeURIComponent k ++ </span><span style="color:#CE9178;">"="</span><span style="color:#D4D4D4;"> ++ encodeURIComponent v) (</span><span style="color:#4EC9B0;">Map.</span><span style="color:#D4D4D4;">toList $ </span><span style="color:#4EC9B0;">Map.</span><span style="color:#D4D4D4;">insert </span><span style="color:#CE9178;">"wts"</span><span style="color:#D4D4D4;"> (show wts) params)) </span><span style="color:#CE9178;">"&"</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> in</span><span style="color:#D4D4D4;"> orig ++ </span><span style="color:#CE9178;">"&w_rid="</span><span style="color:#D4D4D4;"> ++ showMD5 (md5 $ pack $ orig ++ getMixinKey imgKey subKey)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">main</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">IO</span><span style="color:#D4D4D4;"> ()</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">main = </span><span style="color:#C586C0;">do</span><span style="color:#6A9955;"> -- hard encode for test</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> params1 = </span><span style="color:#4EC9B0;">Map.</span><span style="color:#D4D4D4;">fromList [(</span><span style="color:#CE9178;">"aid"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"2"</span><span style="color:#D4D4D4;">)]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params2 = </span><span style="color:#4EC9B0;">Map.</span><span style="color:#D4D4D4;">fromList [(</span><span style="color:#CE9178;">"foo"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"114"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ,(</span><span style="color:#CE9178;">"bar"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"514"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ,(</span><span style="color:#CE9178;">"hello"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"世 界"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> imgKey = </span><span style="color:#CE9178;">"7cd084941338484aae1ad9425b84077c"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> subKey = </span><span style="color:#CE9178;">"4932caff0ff746eab6f01bf08b70ac45"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> wts1 <- getSystemTime </span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> putStrLn $ wbi imgKey subKey (toInteger $ systemSeconds wts1) params1</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> wts2 <- getSystemTime </span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> putStrLn $ wbi imgKey subKey (toInteger $ systemSeconds wts2) params2</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>URIEncoder.hs</code>:</p><div class="language-hs line-numbers-mode" data-highlighter="shiki" data-ext="hs" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-hs"><span class="line"><span style="color:#569CD6;">module</span><span style="color:#4EC9B0;"> URIEncoder</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;">) </span><span style="color:#569CD6;">where</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Data.Char</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">ord</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">chr</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">intToDigit</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Data.Bits</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">shiftL</span><span style="color:#D4D4D4;">, </span><span style="color:#DCDCAA;">shiftR</span><span style="color:#D4D4D4;">, (</span><span style="color:#DCDCAA;">.&.</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#4EC9B0;"> Data.List</span><span style="color:#D4D4D4;"> (</span><span style="color:#DCDCAA;">isInfixOf</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">-- ES 19.2.6.4 encodeURIComponent ( uriComponent )</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">encodeURIComponent</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">encodeURIComponent input = </span><span style="color:#C586C0;">case</span><span style="color:#D4D4D4;"> encode input </span><span style="color:#CE9178;">""</span><span style="color:#C586C0;"> of</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> Right result -> result</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> Left err -> error err</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">-- ES 19.2.6.5 Encode ( string, extraUnescaped )</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;">encode</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">Either</span><span style="color:#569CD6;"> String</span><span style="color:#569CD6;"> String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">encode string extraUnescaped = loop </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;"> string</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> where</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> alwaysUnescaped = [</span><span style="color:#CE9178;">'A'</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">'Z'</span><span style="color:#D4D4D4;">] ++ [</span><span style="color:#CE9178;">'a'</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">'z'</span><span style="color:#D4D4D4;">] ++ [</span><span style="color:#CE9178;">'0'</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">'9'</span><span style="color:#D4D4D4;">] ++ </span><span style="color:#CE9178;">"-.!~*'()"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> unescapedSet = alwaysUnescaped ++ extraUnescaped</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> </span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> loop k str</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | k >= length str = Right </span><span style="color:#569CD6;">[]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | otherwise = </span><span style="color:#C586C0;">case</span><span style="color:#D4D4D4;"> codePointAt str k </span><span style="color:#C586C0;">of</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (Nothing, _) -> Left </span><span style="color:#CE9178;">"Unpaired surrogate"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> (Just (cp, _), newK) -></span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> [str !! k] `isInfixOf` unescapedSet</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> then</span><span style="color:#D4D4D4;"> (str !! k :) <$> loop (k + </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">) str</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> else</span><span style="color:#C586C0;"> do</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> bytes <- utf8Encode cp</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> escaped = concatMap percentEncode bytes</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> rest <- loop newK str</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> Right (escaped ++ rest)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">codePointAt</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;"> -> (</span><span style="color:#569CD6;">Maybe</span><span style="color:#D4D4D4;"> (</span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;">), </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">codePointAt s k</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | k >= length s = (Nothing, k)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | otherwise =</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> c1 = ord (s !! k)</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> in</span><span style="color:#C586C0;"> if</span><span style="color:#B5CEA8;"> 0xD800</span><span style="color:#D4D4D4;"> <= c1 && c1 <= </span><span style="color:#B5CEA8;">0xDBFF</span><span style="color:#D4D4D4;"> && k+</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;"> < length s</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> then</span><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> c2 = ord (s !! (k+</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">))</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> in</span><span style="color:#C586C0;"> if</span><span style="color:#B5CEA8;"> 0xDC00</span><span style="color:#D4D4D4;"> <= c2 && c2 <= </span><span style="color:#B5CEA8;">0xDFFF</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> then</span><span style="color:#D4D4D4;"> ( Just (</span><span style="color:#B5CEA8;">0x10000</span><span style="color:#D4D4D4;"> + ((c1 - </span><span style="color:#B5CEA8;">0xD800</span><span style="color:#D4D4D4;">) `shiftL` </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">) + (c2 - </span><span style="color:#B5CEA8;">0xDC00</span><span style="color:#D4D4D4;">), </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , k + </span><span style="color:#B5CEA8;">2</span><span style="color:#D4D4D4;"> )</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> else</span><span style="color:#D4D4D4;"> (Just (c1, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">), k + </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> else</span><span style="color:#D4D4D4;"> (Just (c1, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">), k + </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">utf8Encode</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">Either</span><span style="color:#569CD6;"> String</span><span style="color:#D4D4D4;"> [</span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;">]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">utf8Encode cp</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | cp < </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;"> = Left </span><span style="color:#CE9178;">"Invalid code point"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | cp <= </span><span style="color:#B5CEA8;">0x007F</span><span style="color:#D4D4D4;"> = Right [cp]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | cp <= </span><span style="color:#B5CEA8;">0x07FF</span><span style="color:#D4D4D4;"> = Right</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> [ </span><span style="color:#B5CEA8;">0xC0</span><span style="color:#D4D4D4;"> + (cp `shiftR` </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + (cp .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">) ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | cp <= </span><span style="color:#B5CEA8;">0xFFFF</span><span style="color:#D4D4D4;"> = Right</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> [ </span><span style="color:#B5CEA8;">0xE0</span><span style="color:#D4D4D4;"> + (cp `shiftR` </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + ((cp `shiftR` </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">) .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + (cp .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">) ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | cp <= </span><span style="color:#B5CEA8;">0x10FFFF</span><span style="color:#D4D4D4;"> = Right</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> [ </span><span style="color:#B5CEA8;">0xF0</span><span style="color:#D4D4D4;"> + (cp `shiftR` </span><span style="color:#B5CEA8;">18</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + ((cp `shiftR` </span><span style="color:#B5CEA8;">12</span><span style="color:#D4D4D4;">) .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + ((cp `shiftR` </span><span style="color:#B5CEA8;">6</span><span style="color:#D4D4D4;">) .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> , </span><span style="color:#B5CEA8;">0x80</span><span style="color:#D4D4D4;"> + (cp .&. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">) ]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | otherwise = Left </span><span style="color:#CE9178;">"Code point out of range"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#DCDCAA;">percentEncode</span><span style="color:#D4D4D4;"> :: </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;"> -> </span><span style="color:#569CD6;">String</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">percentEncode byte = </span><span style="color:#CE9178;">'%'</span><span style="color:#D4D4D4;"> : toHex byte</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> where</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> toHex n = [hexDigit (n `div` </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">), hexDigit (n `mod` </span><span style="color:#B5CEA8;">16</span><span style="color:#D4D4D4;">)]</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> hexDigit x</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | x < </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;"> = intToDigit x</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> | otherwise = chr (x - </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;"> + ord </span><span style="color:#CE9178;">'A'</span><span style="color:#D4D4D4;">)</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>输出:</p><div class="language-text line-numbers-mode" data-highlighter="shiki" data-ext="text" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-text"><span class="line"><span>aid=2&wts=1744823207&w_rid=a3cd246bd42c066932752b24694eaf0d</span></span>
|
||
<span class="line"><span>bar=514&foo=114&hello=%E4%B8%96%20%E7%95%8C&wts=1744823207&w_rid=93acf59d85f74453e40cea00056c3daf</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div></div><!--[--><!--]--></div><footer class="vp-page-meta"><div class="vp-meta-item edit-link"><a class="auto-link external-link label" href="https://github.com/SocialSisterYi/bilibili-API-collect/edit/master/docs/misc/sign/wbi.md" aria-label="在 GitHub 上编辑此页" rel="noopener noreferrer" target="_blank"><!--[--><!--[--><svg class="edit-icon" viewbox="0 0 1024 1024"><g fill="currentColor"><path d="M430.818 653.65a60.46 60.46 0 0 1-50.96-93.281l71.69-114.012 7.773-10.365L816.038 80.138A60.46 60.46 0 0 1 859.225 62a60.46 60.46 0 0 1 43.186 18.138l43.186 43.186a60.46 60.46 0 0 1 0 86.373L588.879 565.55l-8.637 8.637-117.466 68.234a60.46 60.46 0 0 1-31.958 11.229z"></path><path d="M728.802 962H252.891A190.883 190.883 0 0 1 62.008 771.98V296.934a190.883 190.883 0 0 1 190.883-192.61h267.754a60.46 60.46 0 0 1 0 120.92H252.891a69.962 69.962 0 0 0-69.098 69.099V771.98a69.962 69.962 0 0 0 69.098 69.098h475.911A69.962 69.962 0 0 0 797.9 771.98V503.363a60.46 60.46 0 1 1 120.922 0V771.98A190.883 190.883 0 0 1 728.802 962z"></path></g></svg><!--]--><!--]-->在 GitHub 上编辑此页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-meta-item git-info"><div class="vp-meta-item last-updated"><span class="meta-item-label">最近更新: </span><time class="meta-item-info" datetime="2025-09-16T14:59:14.000Z" data-allow-mismatch>2025/9/16 14:59</time></div><div class="vp-meta-item contributors"><span class="meta-item-label">Contributors: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: 1440239038@qq.com">SocialSisterYi</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: me@isoasflus.com">THMonster</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: jannchie@gmail.com">Jianqi Pan</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: ywmoyue@163.com">ywmoyue</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 62145553+vapehacker@users.noreply.github.com">vapehacker</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: takanashirikkax@gmail.com">7rikka</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 73207840+lanyeeee@users.noreply.github.com">lanyeeee</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 63290381+xiaoyv404@users.noreply.github.com">xiaoyv404</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: emkqson@outlook.com">PACI</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 69347367+188102836@users.noreply.github.com">188102836</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: sjx233@qq.com">ud2</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: catlair@qq.com">LaMerChiang</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: fwqaaq@gmail.com">fwqaaq</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 45706356+WindowsMEMZ@users.noreply.github.com">WindowsMEMZ</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 70561268+cxw620@users.noreply.github.com">cxw620</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: ivan@hanloth.com">Ivan Hanloth</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 51024916+YuHuanTin@users.noreply.github.com">YuHuanTin</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 69023595+stmtc233@users.noreply.github.com">stmtc233</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 62951481+xrz-cloud@users.noreply.github.com">xrz-cloud</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: amtoaer@outlook.com">ᴀᴍᴛᴏᴀᴇʀ</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 102411014+SessionHu@users.noreply.github.com">SessionHu</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 93977077+MukjepScarlet@users.noreply.github.com">MukjepScarlet</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 982809597@qq.com">Miuzarte</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: quanminjun37@gmail.com">Seamain</span><!--[-->, <!--]--><!--]--><!--[--><span class="contributor" title="email: 11794321+xjbeta@users.noreply.github.com">xjbeta</span><!----><!--]--><!--]--></span></div></div></footer><!----><!--[--><!--[--><footer style="text-align:center;"> Copyright © 2020-2025 <a href="https://github.com/SocialSisterYi/">SocialSisterYi</a> | <a href="https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/LICENSE">CC-BY-NC-4.0 Licensed</a></footer><!--]--><!--]--></main><!--]--></div><!--[--><!----><!--]--><!--]--></div>
|
||
<script type="module" src="/bilibili-API-collect/assets/app-Dgsdh8A6.js" defer></script>
|
||
</body>
|
||
</html>
|