bilibili-API-collect/docs/misc/sign/wbi.html
github-actions 1424f73d2e generated
2026-01-22 17:37:01 +00:00

1135 lines
369 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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&amp;k=ympvb3LAPT-Ulu3ezhGqbkJ8zXMKImOX&amp;authKey=z1KdkOdKO3wytN43m9K6On9nBtnDL4pAoD6VQHCipFBb9TasNDKuDHCmOE6TF3uc&amp;noverify=0&amp;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&amp;k=ympvb3LAPT-Ulu3ezhGqbkJ8zXMKImOX&amp;authKey=z1KdkOdKO3wytN43m9K6On9nBtnDL4pAoD6VQHCipFBb9TasNDKuDHCmOE6TF3uc&amp;noverify=0&amp;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;">&quot;code&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;message&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">&quot;0&quot;</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;ttl&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;data&quot;</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">&quot;v_voucher&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">&quot;voucher_******&quot;</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;">&quot;code&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">-101</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;message&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">&quot;账号未登录&quot;</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;ttl&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;data&quot;</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">&quot;isLogin&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#569CD6;">false</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">:{</span><span style="color:#9CDCFE;">&quot;img_url&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">&quot;https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png&quot;</span><span style="color:#D4D4D4;">,</span><span style="color:#9CDCFE;">&quot;sub_url&quot;</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">&quot;https://i0.hdslb.com/bfs/wbi/4932caff0ff746eab6f01bf08b70ac45.png&quot;</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;">&lt;[</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">]&gt;) -&gt; </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;">::&lt;</span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;">&lt;</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">&gt;&gt;();</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> -&gt; <code>7cd084941338484aae1ad9425b84077c</code><code>sub_key</code> -&gt; <code>4932caff0ff746eab6f01bf08b70ac45</code> 经过上述操作后得到 <code>mixin_key</code> -&gt; <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;">&#39;114&#39;</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;">&#39;514&#39;</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;">&#39;114&#39;</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;">&#39;514&#39;</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&amp;foo=114&amp;wts=1702204169&amp;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;">&#39;one one four&#39;</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;">&#39;五一四&#39;</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&amp;baz=1919810&amp;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&amp;foo=114&amp;zab=1919810&amp;w_rid=8f6f2b5b3d485fe1886cec6a0be8c5d4&amp;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;"> &#39;对 imgKey 和 subKey 进行字符顺序打乱编码&#39;</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;">&#39;&#39;</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;"> &#39;为请求参数进行 wbi 签名&#39;</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;">&#39;wts&#39;</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 中的 &quot;!&#39;()*&quot; 字符</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;">&#39;&#39;</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;"> &quot;!&#39;()*&quot;</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;">&#39;w_rid&#39;</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;">() -&gt; 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;"> &#39;获取最新的 img_key 和 sub_key&#39;</span></span>
<span class="line"><span style="color:#D4D4D4;"> headers = {</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;User-Agent&#39;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;Referer&#39;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&#39;https://www.bilibili.com/&#39;</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;">&#39;https://api.bilibili.com/x/web-interface/nav&#39;</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;">&#39;data&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;wbi_img&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;img_url&#39;</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;">&#39;data&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;wbi_img&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;sub_url&#39;</span><span style="color:#D4D4D4;">]</span></span>
<span class="line"><span style="color:#D4D4D4;"> img_key = img_url.rsplit(</span><span style="color:#CE9178;">&#39;/&#39;</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;">&#39;.&#39;</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;">&#39;/&#39;</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;">&#39;.&#39;</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;"> &#39;foo&#39;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&#39;114&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;bar&#39;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&#39;514&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;baz&#39;</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>{&#39;bar&#39;: &#39;514&#39;, &#39;baz&#39;: &#39;1919810&#39;, &#39;foo&#39;: &#39;114&#39;, &#39;wts&#39;: &#39;1702204169&#39;, &#39;w_rid&#39;: &#39;d3cbd2a2316089117134038bf4caf442&#39;}</span></span>
<span class="line"><span>bar=514&amp;baz=1919810&amp;foo=114&amp;wts=1702204169&amp;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&amp;baz=1919810&amp;foo=114&amp;wts=1684805578&amp;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;"> &quot;bytes&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;crypto/md5&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;encoding/hex&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;encoding/json&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;fmt&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;io&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;net/http&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;net/url&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;strconv&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;strings&quot;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;time&quot;</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;">&quot;https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091&quot;</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;">&quot;orig: </span><span style="color:#9CDCFE;">%s</span><span style="color:#D7BA7D;">\n</span><span style="color:#CE9178;">&quot;</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;">&quot;signed: </span><span style="color:#9CDCFE;">%s</span><span style="color:#D7BA7D;">\n</span><span style="color:#CE9178;">&quot;</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;">&#39;!&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;\&#39;&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;(&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;)&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;*&#39;</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;">&quot;wts&quot;</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;">&quot;w_rid&quot;</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;"> &amp;&amp; </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;">) &lt; </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;">&quot;https://api.bilibili.com/x/web-interface/nav&quot;</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;">, &amp;</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;"> &amp;&amp; </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;">&quot;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;">&quot;</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;">&quot;&quot;</span><span style="color:#D4D4D4;"> || </span><span style="color:#9CDCFE;">sub</span><span style="color:#D4D4D4;"> == </span><span style="color:#CE9178;">&quot;&quot;</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;">&quot;empty image or sub url: </span><span style="color:#9CDCFE;">%s</span><span style="color:#CE9178;">&quot;</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;">&quot;/&quot;</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;">&quot;/&quot;</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;">&quot;.png&quot;</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;">&quot;.png&quot;</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 &lt; 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:&quot;code&quot;`</span></span>
<span class="line"><span style="color:#9CDCFE;"> Message</span><span style="color:#4EC9B0;"> string</span><span style="color:#CE9178;"> `json:&quot;message&quot;`</span></span>
<span class="line"><span style="color:#9CDCFE;"> Ttl</span><span style="color:#4EC9B0;"> int</span><span style="color:#CE9178;"> `json:&quot;ttl&quot;`</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:&quot;img_url&quot;`</span></span>
<span class="line"><span style="color:#9CDCFE;"> SubUrl</span><span style="color:#4EC9B0;"> string</span><span style="color:#CE9178;"> `json:&quot;sub_url&quot;`</span></span>
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#CE9178;">`json:&quot;wbi_img&quot;`</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:&quot;data&quot;`</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;">&quot;&quot;</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;">) =&gt; </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;">&lt;</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">&gt; </span><span style="color:#DCDCAA;">EncWbi</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">Dictionary</span><span style="color:#D4D4D4;">&lt;</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">&gt; </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;">&quot;wts&quot;</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;"> =&gt; </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;"> =&gt; </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;"> =&gt; </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 中的 &quot;!&#39;()*&quot; 字符</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;"> =&gt; </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;"> =&gt; </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;"> =&gt; !</span><span style="color:#CE9178;">&quot;!&#39;()*&quot;</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;">&quot;-&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;&quot;</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;">&quot;w_rid&quot;</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;">&lt;(</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">)&gt; </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;">&quot;User-Agent&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&quot;</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;">&quot;https://www.bilibili.com/&quot;</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;">&quot;https://api.bilibili.com/x/web-interface/nav&quot;</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;">&quot;data&quot;</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">&quot;img_url&quot;</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;">&quot;/&quot;</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;">&quot;.&quot;</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;">&quot;data&quot;</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">]![</span><span style="color:#CE9178;">&quot;sub_url&quot;</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;">&quot;/&quot;</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;">&quot;.&quot;</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;">&lt;</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">&gt; </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;">&lt;</span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">, </span><span style="color:#569CD6;">string</span><span style="color:#D4D4D4;">&gt;</span></span>
<span class="line"><span style="color:#D4D4D4;"> {</span></span>
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">&quot;foo&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;114&quot;</span><span style="color:#D4D4D4;"> },</span></span>
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">&quot;bar&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;514&quot;</span><span style="color:#D4D4D4;"> },</span></span>
<span class="line"><span style="color:#D4D4D4;"> { </span><span style="color:#CE9178;">&quot;baz&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;1919810&quot;</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&amp;baz=1919810&amp;foo=114&amp;wts=1687541921&amp;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;">&quot;0123456789abcdef&quot;</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;">&quot;MD5&quot;</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 &lt; </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] &gt;&gt; </span><span style="color:#B5CEA8;">4</span><span style="color:#D4D4D4;">) &amp; </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] &amp; </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 &lt; </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;">&quot;+&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;%20&quot;</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;">&quot;653657f524a547ac981ded72ea172057&quot;</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;">&quot;6e4909c702f846728e64f6007736a338&quot;</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;">&lt;</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">Object</span><span style="color:#D4D4D4;">&gt; </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;">&lt;&gt;();</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;">&quot;foo&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;one one four&quot;</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;">&quot;bar&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;五一四&quot;</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;">&quot;baz&quot;</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;">&quot;wts&quot;</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;">-&gt;</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;">&quot;%s=%s&quot;</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;">&quot;&amp;&quot;</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;">&quot;&amp;w_rid=&quot;</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;">&quot;No contents found&quot;</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;">&#39;/&#39;</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;">&quot;.png&quot;</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;">&quot;img_url&quot;</span><span style="color:#D4D4D4;">].</span><span style="color:#DCDCAA;">get</span><span style="color:#D4D4D4;">(), wbiImg[</span><span style="color:#CE9178;">&quot;sub_url&quot;</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;">-&gt;</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;">&lt;</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">Any</span><span style="color:#D4D4D4;">?&gt;): </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;">&quot;wts&quot;</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;">&quot;&amp;wts=&quot;</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;">&quot;&amp;w_rid=&quot;</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;">&quot;0123456789abcdef&quot;</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;">-&gt;</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;">&quot;MD5&quot;</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;">&lt;String, Any?&gt;.</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;">&quot;&amp;&quot;</span><span style="color:#D4D4D4;">) { (k, v) </span><span style="color:#569CD6;">-&gt;</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;</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;">&quot;</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;">&lt;?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;">-&gt;</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;">-&gt;</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;">&#39;img_key&#39;</span><span style="color:#D4D4D4;">], </span><span style="color:#9CDCFE;">$wbi_keys</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">&#39;sub_key&#39;</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;">&#39;&#39;</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;">-&gt;</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;">-&gt;</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;">&quot;/[!&#39;()*]/&quot;</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;">&#39;wts&#39;</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;"> =&gt; </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;">&#39;&#39;</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;"> &#39;=&#39;</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;">&#39;&amp;&#39;</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;"> &#39;&amp;w_rid=&#39;</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;">-&gt;</span><span style="color:#DCDCAA;">curl_get</span><span style="color:#D4D4D4;">(</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;https://api.bilibili.com/x/web-interface/nav&#39;</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;"> &#39;https://www.bilibili.com/&#39;</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;">&#39;请求失败&#39;</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;">&#39;data&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;wbi_img&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;img_url&#39;</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;">&#39;data&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;wbi_img&#39;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&#39;sub_url&#39;</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;"> &#39;img_key&#39;</span><span style="color:#D4D4D4;"> =&gt; </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;">&#39;.&#39;</span><span style="color:#D4D4D4;">)),</span></span>
<span class="line"><span style="color:#CE9178;"> &#39;sub_key&#39;</span><span style="color:#D4D4D4;"> =&gt; </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;">&#39;.&#39;</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;">&#39;https://www.bilibili.com/&#39;</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;">&quot;Accept: */*&quot;</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;">&quot;Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7&quot;</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;">&quot;Connection: close&quot;</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;">&quot;Referer:https://www.bilibili.com/&quot;</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;">&quot;Cache-Control: max-age=0&quot;</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 =&gt; </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_CUSTOMREQUEST =&gt; </span><span style="color:#CE9178;">&#39;GET&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_RETURNTRANSFER =&gt; </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_HTTPHEADER =&gt; </span><span style="color:#9CDCFE;">$header</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_ENCODING =&gt; </span><span style="color:#CE9178;">&#39;&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_URL =&gt; </span><span style="color:#9CDCFE;">$url</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_USERAGENT =&gt; </span><span style="color:#CE9178;">&#39;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&#39;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_TIMEOUT =&gt; </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 =&gt; </span><span style="color:#9CDCFE;">$referer</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#D4D4D4;"> CURLOPT_REFERER =&gt; </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;">-&gt;</span><span style="color:#DCDCAA;">reQuery</span><span style="color:#D4D4D4;">([</span><span style="color:#CE9178;">&#39;foo&#39;</span><span style="color:#D4D4D4;"> =&gt; </span><span style="color:#CE9178;">&#39;114&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;bar&#39;</span><span style="color:#D4D4D4;"> =&gt; </span><span style="color:#CE9178;">&#39;514&#39;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&#39;baz&#39;</span><span style="color:#D4D4D4;"> =&gt; </span><span style="color:#B5CEA8;">1919810</span><span style="color:#D4D4D4;">]);</span></span>
<span class="line"><span style="color:#6A9955;">// bar=514&amp;baz=1919810&amp;foo=114&amp;wts=1700384803&amp;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;">: &amp;[</span><span style="color:#4EC9B0;">u8</span><span style="color:#D4D4D4;">]) -&gt; </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;">(|&amp;</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;">::&lt;</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">&gt;()</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;">: &amp;</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">) -&gt; </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;">&quot;-_.~&quot;</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;"> =&gt; </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;"> =&gt; {</span></span>
<span class="line"><span style="color:#6A9955;"> // 过滤 value 中的 &quot;!&#39;()*&quot; 字符</span></span>
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#CE9178;"> &quot;!&#39;()*&quot;</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;">(&amp;</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;">&quot;&quot;</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;"> + &amp;</span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;%{:02X}&quot;</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;">::&lt;</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">&gt;()</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;">&lt;(&amp;</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">)&gt;, (</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;">)) -&gt; </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;">) =&gt; </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;">) =&gt; </span><span style="color:#DCDCAA;">panic!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;SystemTime before UNIX EPOCH!&quot;</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;">&lt;(&amp;</span><span style="color:#4EC9B0;">str</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">)&gt;,</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;">) -&gt; </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;"> + &amp;</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;">&quot;wts&quot;</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;">&quot;{}={}&quot;</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;">::&lt;</span><span style="color:#4EC9B0;">Vec</span><span style="color:#D4D4D4;">&lt;</span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;">&gt;&gt;()</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;">&quot;&amp;&quot;</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;">&quot;{:?}&quot;</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;">() + &amp;</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;"> + &amp;</span><span style="color:#DCDCAA;">format!</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;&amp;w_rid={}&quot;</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;">() -&gt; </span><span style="color:#4EC9B0;">Result</span><span style="color:#D4D4D4;">&lt;(</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;">&gt; {</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;">&quot;https://api.bilibili.com/x/web-interface/nav&quot;</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;">&quot;Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36&quot;</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;">&quot;Referer&quot;</span><span style="color:#D4D4D4;">,</span><span style="color:#CE9178;">&quot;https://www.bilibili.com/&quot;</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;">&quot;Cookie&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;SESSDATA=xxxxx&quot;</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;">::&lt;</span><span style="color:#4EC9B0;">ResWbi</span><span style="color:#D4D4D4;">&gt;()</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;">) -&gt; </span><span style="color:#4EC9B0;">Option</span><span style="color:#D4D4D4;">&lt;</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">&gt; {</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;">&#39;/&#39;</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;">&#39;.&#39;</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;">&quot;foo&quot;</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;">&quot;114&quot;</span><span style="color:#D4D4D4;">)),</span></span>
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">&quot;bar&quot;</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;">&quot;514&quot;</span><span style="color:#D4D4D4;">)),</span></span>
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">&quot;baz&quot;</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;">&quot;1919810&quot;</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;">&quot;{}&quot;</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;"> &quot;https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png&quot;</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;">&quot;7cd084941338484aae1ad9425b84077c&quot;</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;"> &quot;7cd084941338484aae1ad9425b84077c&quot;</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">to_string</span><span style="color:#D4D4D4;">() + </span><span style="color:#CE9178;">&quot;4932caff0ff746eab6f01bf08b70ac45&quot;</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;"> &quot;ea1db124af3c7062474693fa704f4ff8&quot;</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;">&quot;foo&quot;</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;">&quot;114&quot;</span><span style="color:#D4D4D4;">)),</span></span>
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">&quot;bar&quot;</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;">&quot;514&quot;</span><span style="color:#D4D4D4;">)),</span></span>
<span class="line"><span style="color:#D4D4D4;"> (</span><span style="color:#CE9178;">&quot;zab&quot;</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;">&quot;1919810&quot;</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;"> &quot;7cd084941338484aae1ad9425b84077c&quot;</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;"> &quot;4932caff0ff746eab6f01bf08b70ac45&quot;</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;"> &quot;bar=514&amp;foo=114&amp;wts=1702204169&amp;zab=1919810&amp;w_rid=8f6f2b5b3d485fe1886cec6a0be8c5d4&quot;</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;">?) -&gt; </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;">) -&gt; </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;">) -&gt; [</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;">&quot;wts&quot;</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;"> &lt; </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) -&gt; </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;">&quot;!&#39;()*&quot;</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;"> &quot;</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;">&quot;</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;">&quot;&amp;&quot;</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;">&quot;w_rid&quot;</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&lt;(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;">&gt;) -&gt; </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;"> &quot;User-Agent&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&quot;</span><span style="color:#D4D4D4;">,</span></span>
<span class="line"><span style="color:#CE9178;"> &quot;Referer&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;https://www.bilibili.com/&quot;</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;">&quot;https://api.bilibili.com/x/web-interface/nav&quot;</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;">&quot;data&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;img_url&quot;</span><span style="color:#D4D4D4;">].</span><span style="color:#9CDCFE;">string</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">&quot;&quot;</span></span>
<span class="line"><span style="color:#569CD6;"> let</span><span style="color:#D4D4D4;"> subURL = json[</span><span style="color:#CE9178;">&quot;data&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;sub_url&quot;</span><span style="color:#D4D4D4;">].</span><span style="color:#9CDCFE;">string</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">&quot;&quot;</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;">&quot;/&quot;</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;">&quot;.&quot;</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">first</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">&quot;&quot;</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;">&quot;/&quot;</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;">&quot;.&quot;</span><span style="color:#D4D4D4;">).</span><span style="color:#9CDCFE;">first</span><span style="color:#D4D4D4;"> ?? </span><span style="color:#CE9178;">&quot;&quot;</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;">) -&gt; </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;">), &amp;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;">&quot;%02hhx&quot;</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;">&quot;&amp;&quot;</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;">&quot;=&quot;</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;">&quot;</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;">&quot;</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;">&quot;&amp;&quot;</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;">&quot;Error getting keys: </span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">error</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">&quot;</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;">&quot;bar=514&amp;foo=114&amp;zab=1919810&quot;</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;">&quot;签名后的参数: </span><span style="color:#569CD6;">\(</span><span style="color:#D4D4D4;">signedQuery</span><span style="color:#569CD6;">)</span><span style="color:#CE9178;">&quot;</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;">&quot;签名失败&quot;</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&amp;wts=1741082093&amp;foo=114&amp;zab=1919810&amp;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;"> &lt;array&gt;</span><span style="color:#6A9955;"> // std::array</span></span>
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> &lt;locale&gt;</span><span style="color:#6A9955;"> // std::locale</span></span>
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> &lt;print&gt;</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;"> &lt;cpr/cpr.h&gt;</span></span>
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> &lt;cryptopp/md5.h&gt;</span></span>
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> &lt;cryptopp/hex.h&gt;</span></span>
<span class="line"><span style="color:#C586C0;">#include</span><span style="color:#CE9178;"> &lt;nlohmann/json.hpp&gt;</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&lt;</span><span style="color:#569CD6;">uint8_t</span><span style="color:#D4D4D4;">, </span><span style="color:#B5CEA8;">64</span><span style="color:#D4D4D4;">&gt; 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;"> &amp;</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;"> &amp;</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;"> &amp;</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;"> &amp;[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;">&quot;=&quot;</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;">&lt;</span><span style="color:#4EC9B0;">std</span><span style="color:#D4D4D4;">::string&gt;() : </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;">&quot;&amp;&quot;</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 &#39;&amp;&#39;</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;">&#39;</span><span style="color:#D7BA7D;">\0</span><span style="color:#CE9178;">&#39;</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;">&lt;</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;">&gt; </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;">&quot;https://api.bilibili.com/x/web-interface/nav&quot;</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;">&quot;SESSDATA&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;xxxxxxxxxxxx&quot;</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;">&quot;User-Agent&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3&quot;</span><span style="color:#D4D4D4;">},</span></span>
<span class="line"><span style="color:#D4D4D4;"> {</span><span style="color:#CE9178;">&quot;Referer&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;https://www.bilibili.com/&quot;</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;">&quot;data&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;img_url&quot;</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;">&quot;data&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;wbi_img&quot;</span><span style="color:#D4D4D4;">][</span><span style="color:#CE9178;">&quot;sub_url&quot;</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;">&quot;wbi/&quot;</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;">&quot;.png&quot;</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;">&quot;wbi/&quot;</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;">&quot;wbi/&quot;</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;">&quot;.png&quot;</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;">&quot;wbi/&quot;</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;"> &amp;</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;"> &amp;</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_, [&amp;</span><span style="color:#9CDCFE;">result</span><span style="color:#D4D4D4;">, &amp;</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;"> &amp;</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;"> &amp;</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;">&quot;wts&quot;</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;">&lt;</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;">&gt;(</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&amp;fnver=0&amp;fnval=4048&amp;fourk=1&amp;avid=1755630705&amp;cid=1574294582</span></span>
<span class="line"><span style="color:#9CDCFE;"> Params</span><span style="color:#D4D4D4;">[</span><span style="color:#CE9178;">&quot;qn&quot;</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;">&quot;fnver&quot;</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;">&quot;fnval&quot;</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;">&quot;fourk&quot;</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;">&quot;avid&quot;</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;">&quot;cid&quot;</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;">&quot;{}&quot;</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;">&quot;&amp;w_rid=&quot;</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&amp;cid=1574294582&amp;fnval=4048&amp;fnver=0&amp;fourk=1&amp;qn=32&amp;wts=1717922933&amp;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;"> -&gt; </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -&gt; </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 -&gt; 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;">] -&gt; </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -&gt; </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;"> -&gt; </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -&gt; </span><span style="color:#569CD6;">Integer</span><span style="color:#D4D4D4;"> -&gt; </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;"> -&gt; </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) -&gt; encodeURIComponent k ++ </span><span style="color:#CE9178;">&quot;=&quot;</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;">&quot;wts&quot;</span><span style="color:#D4D4D4;"> (show wts) params)) </span><span style="color:#CE9178;">&quot;&amp;&quot;</span></span>
<span class="line"><span style="color:#569CD6;"> in</span><span style="color:#D4D4D4;"> orig ++ </span><span style="color:#CE9178;">&quot;&amp;w_rid=&quot;</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;">&quot;aid&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;2&quot;</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;">&quot;foo&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;114&quot;</span><span style="color:#D4D4D4;">)</span></span>
<span class="line"><span style="color:#D4D4D4;"> ,(</span><span style="color:#CE9178;">&quot;bar&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;514&quot;</span><span style="color:#D4D4D4;">)</span></span>
<span class="line"><span style="color:#D4D4D4;"> ,(</span><span style="color:#CE9178;">&quot;hello&quot;</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">&quot;世 界&quot;</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;">&quot;7cd084941338484aae1ad9425b84077c&quot;</span></span>
<span class="line"><span style="color:#D4D4D4;"> subKey = </span><span style="color:#CE9178;">&quot;4932caff0ff746eab6f01bf08b70ac45&quot;</span></span>
<span class="line"><span style="color:#D4D4D4;"> wts1 &lt;- 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 &lt;- 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;">.&amp;.</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;"> -&gt; </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;">&quot;&quot;</span><span style="color:#C586C0;"> of</span></span>
<span class="line"><span style="color:#D4D4D4;"> Right result -&gt; result</span></span>
<span class="line"><span style="color:#D4D4D4;"> Left err -&gt; 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;"> -&gt; </span><span style="color:#569CD6;">String</span><span style="color:#D4D4D4;"> -&gt; </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;">&#39;A&#39;</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">&#39;Z&#39;</span><span style="color:#D4D4D4;">] ++ [</span><span style="color:#CE9178;">&#39;a&#39;</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">&#39;z&#39;</span><span style="color:#D4D4D4;">] ++ [</span><span style="color:#CE9178;">&#39;0&#39;</span><span style="color:#D4D4D4;">..</span><span style="color:#CE9178;">&#39;9&#39;</span><span style="color:#D4D4D4;">] ++ </span><span style="color:#CE9178;">&quot;-.!~*&#39;()&quot;</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 &gt;= 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, _) -&gt; Left </span><span style="color:#CE9178;">&quot;Unpaired surrogate&quot;</span></span>
<span class="line"><span style="color:#D4D4D4;"> (Just (cp, _), newK) -&gt;</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 :) &lt;$&gt; 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 &lt;- 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 &lt;- 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;"> -&gt; </span><span style="color:#569CD6;">Int</span><span style="color:#D4D4D4;"> -&gt; (</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 &gt;= 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;"> &lt;= c1 &amp;&amp; c1 &lt;= </span><span style="color:#B5CEA8;">0xDBFF</span><span style="color:#D4D4D4;"> &amp;&amp; k+</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;"> &lt; 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;"> &lt;= c2 &amp;&amp; c2 &lt;= </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;"> -&gt; </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 &lt; </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;"> = Left </span><span style="color:#CE9178;">&quot;Invalid code point&quot;</span></span>
<span class="line"><span style="color:#D4D4D4;"> | cp &lt;= </span><span style="color:#B5CEA8;">0x007F</span><span style="color:#D4D4D4;"> = Right [cp]</span></span>
<span class="line"><span style="color:#D4D4D4;"> | cp &lt;= </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 .&amp;. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">) ]</span></span>
<span class="line"><span style="color:#D4D4D4;"> | cp &lt;= </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;">) .&amp;. </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 .&amp;. </span><span style="color:#B5CEA8;">0x3F</span><span style="color:#D4D4D4;">) ]</span></span>
<span class="line"><span style="color:#D4D4D4;"> | cp &lt;= </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;">) .&amp;. </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;">) .&amp;. </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 .&amp;. </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;">&quot;Code point out of range&quot;</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;"> -&gt; </span><span style="color:#569CD6;">String</span></span>
<span class="line"><span style="color:#D4D4D4;">percentEncode byte = </span><span style="color:#CE9178;">&#39;%&#39;</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 &lt; </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;">&#39;A&#39;</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&amp;wts=1744823207&amp;w_rid=a3cd246bd42c066932752b24694eaf0d</span></span>
<span class="line"><span>bar=514&amp;foo=114&amp;hello=%E4%B8%96%20%E7%95%8C&amp;wts=1744823207&amp;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>