Files
bilibili-API-collect/assets/wbi.html-D21GJ5Gx.js
github-actions 1424f73d2e generated
2026-01-22 17:37:01 +00:00

1243 lines
397 KiB
JavaScript
Raw Permalink 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.

import{_ as t,c as y,b as s,a as o,e as a,d as n,w as p,r as D,o as i}from"./app-Dgsdh8A6.js";const C={};function d(u,l){const e=D("RouteLink"),c=D("CodeGroupItem"),r=D("CodeGroup");return i(),y("div",null,[l[32]||(l[32]=s("h1",{id:"wbi-签名",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#wbi-签名"},[s("span",null,"WBI 签名")])],-1)),s("p",null,[l[1]||(l[1]=n("自 2023 年 3 月起Bilibili Web 端部分接口开始采用 WBI 签名鉴权,表现在 REST API 请求时在 Query param 中添加了 ")),l[2]||(l[2]=s("code",null,"w_rid",-1)),l[3]||(l[3]=n(" 和 ")),l[4]||(l[4]=s("code",null,"wts",-1)),l[5]||(l[5]=n(" 字段。WBI 签名鉴权独立于 ")),a(e,{to:"/docs/misc/sign/APP.html"},{default:p(()=>l[0]||(l[0]=[n("APP 鉴权")])),_:1,__:[0]}),l[6]||(l[6]=n(" 与其他 Cookie 鉴权,目前被认为是一种 Web 端风控手段。"))]),s("p",null,[l[8]||(l[8]=n("经持续观察,大部分查询性接口都已经或准备采用 WBI 签名鉴权,请求 WBI 签名鉴权接口时,若签名参数 ")),l[9]||(l[9]=s("code",null,"w_rid",-1)),l[10]||(l[10]=n(" 与时间戳 ")),l[11]||(l[11]=s("code",null,"wts",-1)),l[12]||(l[12]=n(" 缺失、错误,会返回 ")),a(e,{to:"/docs/misc/sign/v_voucher.html"},{default:p(()=>l[7]||(l[7]=[s("code",null,"v_voucher",-1)])),_:1,__:[7]}),l[13]||(l[13]=n(",如:"))]),l[33]||(l[33]=o('<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>',5)),s("ol",null,[s("li",null,[l[27]||(l[27]=s("p",null,[n("获取实时口令 "),s("code",null,"img_key"),n("、"),s("code",null,"sub_key")],-1)),s("p",null,[l[16]||(l[16]=n("从 ")),a(e,{to:"/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"},{default:p(()=>l[14]||(l[14]=[n("nav 接口")])),_:1,__:[14]}),l[17]||(l[17]=n(" 中获取 ")),l[18]||(l[18]=s("code",null,"img_url",-1)),l[19]||(l[19]=n("、")),l[20]||(l[20]=s("code",null,"sub_url",-1)),l[21]||(l[21]=n(" 两个字段的参数。 或从 ")),a(e,{to:"/docs/misc/sign/bili_ticket.html#%E6%8E%A5%E5%8F%A3"},{default:p(()=>l[15]||(l[15]=[n("bili_ticket 接口")])),_:1,__:[15]}),l[22]||(l[22]=n(" 中获取 ")),l[23]||(l[23]=s("code",null,"img",-1)),l[24]||(l[24]=n()),l[25]||(l[25]=s("code",null,"sub",-1)),l[26]||(l[26]=n(" 两个字段的参数。"))]),l[28]||(l[28]=o('<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>',5))]),l[29]||(l[29]=o(`<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>`,3))]),l[34]||(l[34]=o(`<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>`,9)),a(r,null,{default:p(()=>[a(c,{title:"JavaScript"},{default:p(()=>l[30]||(l[30]=[s("div",{class:"language-javascript line-numbers-mode","data-highlighter":"shiki","data-ext":"javascript",style:{"background-color":"#1E1E1E",color:"#D4D4D4"}},[s("pre",{class:"shiki dark-plus vp-code"},[s("code",{class:"language-javascript"},[s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}},"import"),s("span",{style:{color:"#9CDCFE"}}," md5"),s("span",{style:{color:"#C586C0"}}," from"),s("span",{style:{color:"#CE9178"}}," 'md5'")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," mixinKeyEncTab"),s("span",{style:{color:"#D4D4D4"}}," = [")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 46"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"47"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"18"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"2"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"53"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"8"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"23"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"32"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"15"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"50"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"10"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"31"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"58"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"45"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"35"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"27"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"43"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"5"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"49"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 33"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"42"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"19"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"29"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"28"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"14"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"39"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"12"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"38"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"41"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"13"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"37"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"48"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"16"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"24"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"55"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"40"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 61"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"26"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"17"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"60"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"51"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"30"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"22"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"25"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"54"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"21"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"56"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"59"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"6"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"63"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"57"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"62"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"11"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 36"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"20"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"34"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"44"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"52")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"]")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 对 imgKey 和 subKey 进行字符顺序打乱编码")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#DCDCAA"}}," getMixinKey"),s("span",{style:{color:"#D4D4D4"}}," = ("),s("span",{style:{color:"#9CDCFE"}},"orig"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>"),s("span",{style:{color:"#9CDCFE"}}," mixinKeyEncTab"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"map"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"n"),s("span",{style:{color:"#569CD6"}}," =>"),s("span",{style:{color:"#9CDCFE"}}," orig"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"n"),s("span",{style:{color:"#D4D4D4"}},"])."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"''"),s("span",{style:{color:"#D4D4D4"}},")."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"32"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 为请求参数进行 wbi 签名")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," encWbi"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"sub_key"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," mixin_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"getMixinKey"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"sub_key"),s("span",{style:{color:"#D4D4D4"}},"),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," curr_time"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Math"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"round"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"Date"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"now"),s("span",{style:{color:"#D4D4D4"}},"() / "),s("span",{style:{color:"#B5CEA8"}},"1000"),s("span",{style:{color:"#D4D4D4"}},"),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," chr_filter"),s("span",{style:{color:"#D4D4D4"}}," ="),s("span",{style:{color:"#D16969"}}," /"),s("span",{style:{color:"#CE9178"}},"["),s("span",{style:{color:"#D16969"}},"!'()*"),s("span",{style:{color:"#CE9178"}},"]"),s("span",{style:{color:"#D16969"}},"/"),s("span",{style:{color:"#569CD6"}},"g")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Object"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"assign"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},", { "),s("span",{style:{color:"#9CDCFE"}},"wts:"),s("span",{style:{color:"#9CDCFE"}}," curr_time"),s("span",{style:{color:"#D4D4D4"}}," }) "),s("span",{style:{color:"#6A9955"}},"// 添加 wts 字段")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}}," // 按照 key 重排参数")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," query"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Object")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"keys"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"sort"),s("span",{style:{color:"#D4D4D4"}},"()")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"map"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#569CD6"}}," =>"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},` // 过滤 value 中的 "!'()*" 字符`)]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," value"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},"]."),s("span",{style:{color:"#DCDCAA"}},"toString"),s("span",{style:{color:"#D4D4D4"}},"()."),s("span",{style:{color:"#DCDCAA"}},"replace"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"chr_filter"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"''"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#CE9178"}}," `"),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#DCDCAA"}},"encodeURIComponent"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},")"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"="),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#DCDCAA"}},"encodeURIComponent"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"value"),s("span",{style:{color:"#D4D4D4"}},")"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"`")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," })")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'&'"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," wbi_sign"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"md5"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"query"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"mixin_key"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#6A9955"}},"// 计算 w_rid")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#9CDCFE"}}," query"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#CE9178"}},"'&w_rid='"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"wbi_sign")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 获取最新的 img_key 和 sub_key")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"async"),s("span",{style:{color:"#569CD6"}}," function"),s("span",{style:{color:"#DCDCAA"}}," getWbiKeys"),s("span",{style:{color:"#D4D4D4"}},"() {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," res"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#DCDCAA"}}," fetch"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'https://api.bilibili.com/x/web-interface/nav'"),s("span",{style:{color:"#D4D4D4"}},", {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," headers:"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}}," // SESSDATA 字段")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Cookie:"),s("span",{style:{color:"#CE9178"}}," 'SESSDATA=xxxxxx'"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#CE9178"}}," 'User-Agent'"),s("span",{style:{color:"#9CDCFE"}},":"),s("span",{style:{color:"#CE9178"}}," 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Referer:"),s("span",{style:{color:"#CE9178"}}," 'https://www.bilibili.com/'"),s("span",{style:{color:"#6A9955"}},"//对于直接浏览器调用可能不适用")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," })")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#D4D4D4"}}," { "),s("span",{style:{color:"#9CDCFE"}},"data"),s("span",{style:{color:"#D4D4D4"}},": { "),s("span",{style:{color:"#9CDCFE"}},"wbi_img"),s("span",{style:{color:"#D4D4D4"}},": { "),s("span",{style:{color:"#4FC1FF"}},"img_url"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#4FC1FF"}},"sub_url"),s("span",{style:{color:"#D4D4D4"}}," } } } = "),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#9CDCFE"}}," res"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"json"),s("span",{style:{color:"#D4D4D4"}},"()")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_key:"),s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"(")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'/'"),s("span",{style:{color:"#D4D4D4"}},") + "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'.'"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_key:"),s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"(")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'/'"),s("span",{style:{color:"#D4D4D4"}},") + "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'.'"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," )")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"async"),s("span",{style:{color:"#569CD6"}}," function"),s("span",{style:{color:"#DCDCAA"}}," main"),s("span",{style:{color:"#D4D4D4"}},"() {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," web_keys"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#DCDCAA"}}," getWbiKeys"),s("span",{style:{color:"#D4D4D4"}},"()")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," params"),s("span",{style:{color:"#D4D4D4"}}," = { "),s("span",{style:{color:"#9CDCFE"}},"foo:"),s("span",{style:{color:"#CE9178"}}," '114'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"bar:"),s("span",{style:{color:"#CE9178"}}," '514'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"baz:"),s("span",{style:{color:"#B5CEA8"}}," 1919810"),s("span",{style:{color:"#D4D4D4"}}," },")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," img_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"web_keys"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," sub_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"web_keys"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"sub_key")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," query"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"encWbi"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"sub_key"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"query"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#DCDCAA"}},"main"),s("span",{style:{color:"#D4D4D4"}},"()")])])]),s("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"})])],-1)])),_:1,__:[30]}),a(c,{title:"TypeScript"},{default:p(()=>l[31]||(l[31]=[s("div",{class:"language-typescript line-numbers-mode","data-highlighter":"shiki","data-ext":"typescript",style:{"background-color":"#1E1E1E",color:"#D4D4D4"}},[s("pre",{class:"shiki dark-plus vp-code"},[s("code",{class:"language-typescript"},[s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}},"import"),s("span",{style:{color:"#9CDCFE"}}," md5"),s("span",{style:{color:"#C586C0"}}," from"),s("span",{style:{color:"#CE9178"}}," 'md5'")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," mixinKeyEncTab"),s("span",{style:{color:"#D4D4D4"}}," = [")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 46"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"47"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"18"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"2"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"53"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"8"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"23"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"32"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"15"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"50"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"10"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"31"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"58"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"45"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"35"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"27"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"43"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"5"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"49"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 33"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"42"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"19"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"29"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"28"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"14"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"39"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"12"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"38"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"41"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"13"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"37"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"48"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"16"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"24"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"55"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"40"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 61"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"26"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"17"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"60"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"51"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"30"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"22"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"25"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"54"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"21"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"56"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"59"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"6"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"63"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"57"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"62"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"11"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#B5CEA8"}}," 36"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"20"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"34"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"44"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"52")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"]")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 对 imgKey 和 subKey 进行字符顺序打乱编码")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#DCDCAA"}}," getMixinKey"),s("span",{style:{color:"#D4D4D4"}}," = ("),s("span",{style:{color:"#9CDCFE"}},"orig"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," mixinKeyEncTab")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"map"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"n"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>"),s("span",{style:{color:"#9CDCFE"}}," orig"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"n"),s("span",{style:{color:"#D4D4D4"}},"])")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},'""'),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"32"),s("span",{style:{color:"#D4D4D4"}},");")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 为请求参数进行 wbi 签名")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," encWbi"),s("span",{style:{color:"#D4D4D4"}},"(")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," params"),s("span",{style:{color:"#D4D4D4"}},": { ["),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},"]: "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}}," | "),s("span",{style:{color:"#4EC9B0"}},"number"),s("span",{style:{color:"#D4D4D4"}}," | "),s("span",{style:{color:"#4EC9B0"}},"object"),s("span",{style:{color:"#D4D4D4"}}," },")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_key"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_key"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},") {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," mixin_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"getMixinKey"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"sub_key"),s("span",{style:{color:"#D4D4D4"}},"),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," curr_time"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Math"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"round"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"Date"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"now"),s("span",{style:{color:"#D4D4D4"}},"() / "),s("span",{style:{color:"#B5CEA8"}},"1000"),s("span",{style:{color:"#D4D4D4"}},"),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," chr_filter"),s("span",{style:{color:"#D4D4D4"}}," ="),s("span",{style:{color:"#D16969"}}," /"),s("span",{style:{color:"#CE9178"}},"["),s("span",{style:{color:"#D16969"}},"!'()*"),s("span",{style:{color:"#CE9178"}},"]"),s("span",{style:{color:"#D16969"}},"/"),s("span",{style:{color:"#569CD6"}},"g"),s("span",{style:{color:"#D4D4D4"}},";")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Object"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"assign"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},", { "),s("span",{style:{color:"#9CDCFE"}},"wts:"),s("span",{style:{color:"#9CDCFE"}}," curr_time"),s("span",{style:{color:"#D4D4D4"}}," }); "),s("span",{style:{color:"#6A9955"}},"// 添加 wts 字段")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}}," // 按照 key 重排参数")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," query"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Object"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"keys"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"sort"),s("span",{style:{color:"#D4D4D4"}},"()")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"map"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},` // 过滤 value 中的 "!'()*" 字符`)]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," value"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},"]."),s("span",{style:{color:"#DCDCAA"}},"toString"),s("span",{style:{color:"#D4D4D4"}},"()."),s("span",{style:{color:"#DCDCAA"}},"replace"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"chr_filter"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},'""'),s("span",{style:{color:"#D4D4D4"}},");")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#CE9178"}}," `"),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#DCDCAA"}},"encodeURIComponent"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"key"),s("span",{style:{color:"#D4D4D4"}},")"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"="),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#DCDCAA"}},"encodeURIComponent"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"value"),s("span",{style:{color:"#D4D4D4"}},")"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"`"),s("span",{style:{color:"#D4D4D4"}},";")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," })")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},'"&"'),s("span",{style:{color:"#D4D4D4"}},");")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," wbi_sign"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"md5"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"query"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"mixin_key"),s("span",{style:{color:"#D4D4D4"}},"); "),s("span",{style:{color:"#6A9955"}},"// 计算 w_rid")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#9CDCFE"}}," query"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#CE9178"}},'"&w_rid="'),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#9CDCFE"}},"wbi_sign"),s("span",{style:{color:"#D4D4D4"}},";")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}},"// 获取最新的 img_key 和 sub_key")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"async"),s("span",{style:{color:"#569CD6"}}," function"),s("span",{style:{color:"#DCDCAA"}}," getWbiKeys"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"SESSDATA"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," res"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#DCDCAA"}}," fetch"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'https://api.bilibili.com/x/web-interface/nav'"),s("span",{style:{color:"#D4D4D4"}},", {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," headers:"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#6A9955"}}," // SESSDATA 字段")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Cookie:"),s("span",{style:{color:"#CE9178"}}," `SESSDATA="),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#4FC1FF"}},"SESSDATA"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"`"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#CE9178"}}," 'User-Agent'"),s("span",{style:{color:"#9CDCFE"}},":"),s("span",{style:{color:"#CE9178"}}," 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," Referer:"),s("span",{style:{color:"#CE9178"}}," 'https://www.bilibili.com/'"),s("span",{style:{color:"#6A9955"}},"//对于直接浏览器调用可能不适用")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," })")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," data"),s("span",{style:{color:"#D4D4D4"}},": {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," wbi_img"),s("span",{style:{color:"#D4D4D4"}},": { "),s("span",{style:{color:"#4FC1FF"}},"img_url"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#4FC1FF"}},"sub_url"),s("span",{style:{color:"#D4D4D4"}}," },")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," },")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," } = ("),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#9CDCFE"}}," res"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"json"),s("span",{style:{color:"#D4D4D4"}},"()) "),s("span",{style:{color:"#C586C0"}},"as"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," data"),s("span",{style:{color:"#D4D4D4"}},": {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," wbi_img"),s("span",{style:{color:"#D4D4D4"}},": { "),s("span",{style:{color:"#9CDCFE"}},"img_url"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},"; "),s("span",{style:{color:"#9CDCFE"}},"sub_url"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}}," };")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," };")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," };")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#D4D4D4"}}," {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_key:"),s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"(")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'/'"),s("span",{style:{color:"#D4D4D4"}},") + "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," img_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'.'"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ),")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_key:"),s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"slice"),s("span",{style:{color:"#D4D4D4"}},"(")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'/'"),s("span",{style:{color:"#D4D4D4"}},") + "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," sub_url"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"lastIndexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'.'"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," )")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"async"),s("span",{style:{color:"#569CD6"}}," function"),s("span",{style:{color:"#DCDCAA"}}," main"),s("span",{style:{color:"#D4D4D4"}},"() {")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," web_keys"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#C586C0"}},"await"),s("span",{style:{color:"#DCDCAA"}}," getWbiKeys"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},'"SESSDATA的值"'),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," params"),s("span",{style:{color:"#D4D4D4"}}," = { "),s("span",{style:{color:"#9CDCFE"}},"foo:"),s("span",{style:{color:"#CE9178"}}," '114'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"bar:"),s("span",{style:{color:"#CE9178"}}," '514'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"baz:"),s("span",{style:{color:"#B5CEA8"}}," 1919810"),s("span",{style:{color:"#D4D4D4"}}," },")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," img_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"web_keys"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}},",")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#4FC1FF"}}," sub_key"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"web_keys"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"sub_key")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," query"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#DCDCAA"}},"encWbi"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"params"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"img_key"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"sub_key"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"query"),s("span",{style:{color:"#D4D4D4"}},")")]),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(`
`),s("span",{class:"line"}),n(`
`),s("span",{class:"line"},[s("span",{style:{color:"#DCDCAA"}},"main"),s("span",{style:{color:"#D4D4D4"}},"()")])])]),s("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"})])],-1)])),_:1,__:[31]})]),_:1}),l[35]||(l[35]=o(`<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>`,41))])}const E=t(C,[["render",d]]),m=JSON.parse('{"path":"/docs/misc/sign/wbi.html","title":"WBI 签名","lang":"zh-CN","frontmatter":{},"git":{"updatedTime":1758034754000,"contributors":[{"name":"SocialSisterYi","username":"SocialSisterYi","email":"1440239038@qq.com","commits":3,"url":"https://github.com/SocialSisterYi"},{"name":"THMonster","username":"THMonster","email":"me@isoasflus.com","commits":1,"url":"https://github.com/THMonster"},{"name":"Jianqi Pan","username":"","email":"jannchie@gmail.com","commits":1},{"name":"ywmoyue","username":"ywmoyue","email":"ywmoyue@163.com","commits":1,"url":"https://github.com/ywmoyue"},{"name":"vapehacker","username":"vapehacker","email":"62145553+vapehacker@users.noreply.github.com","commits":1,"url":"https://github.com/vapehacker"},{"name":"7rikka","username":"7rikka","email":"takanashirikkax@gmail.com","commits":2,"url":"https://github.com/7rikka"},{"name":"lanyeeee","username":"lanyeeee","email":"73207840+lanyeeee@users.noreply.github.com","commits":1,"url":"https://github.com/lanyeeee"},{"name":"xiaoyv404","username":"xiaoyv404","email":"63290381+xiaoyv404@users.noreply.github.com","commits":1,"url":"https://github.com/xiaoyv404"},{"name":"PACI","username":"PACI","email":"emkqson@outlook.com","commits":1,"url":"https://github.com/PACI"},{"name":"188102836","username":"188102836","email":"69347367+188102836@users.noreply.github.com","commits":1,"url":"https://github.com/188102836"},{"name":"ud2","username":"ud2","email":"sjx233@qq.com","commits":2,"url":"https://github.com/ud2"},{"name":"LaMerChiang","username":"LaMerChiang","email":"catlair@qq.com","commits":1,"url":"https://github.com/LaMerChiang"},{"name":"fwqaaq","username":"fwqaaq","email":"fwqaaq@gmail.com","commits":1,"url":"https://github.com/fwqaaq"},{"name":"WindowsMEMZ","username":"WindowsMEMZ","email":"45706356+WindowsMEMZ@users.noreply.github.com","commits":1,"url":"https://github.com/WindowsMEMZ"},{"name":"cxw620","username":"cxw620","email":"70561268+cxw620@users.noreply.github.com","commits":1,"url":"https://github.com/cxw620"},{"name":"Ivan Hanloth","username":"","email":"ivan@hanloth.com","commits":1},{"name":"YuHuanTin","username":"YuHuanTin","email":"51024916+YuHuanTin@users.noreply.github.com","commits":1,"url":"https://github.com/YuHuanTin"},{"name":"stmtc233","username":"stmtc233","email":"69023595+stmtc233@users.noreply.github.com","commits":1,"url":"https://github.com/stmtc233"},{"name":"xrz-cloud","username":"xrz-cloud","email":"62951481+xrz-cloud@users.noreply.github.com","commits":1,"url":"https://github.com/xrz-cloud"},{"name":"ᴀᴍᴛᴏᴀᴇʀ","username":"","email":"amtoaer@outlook.com","commits":1},{"name":"SessionHu","username":"SessionHu","email":"102411014+SessionHu@users.noreply.github.com","commits":7,"url":"https://github.com/SessionHu"},{"name":"MukjepScarlet","username":"MukjepScarlet","email":"93977077+MukjepScarlet@users.noreply.github.com","commits":2,"url":"https://github.com/MukjepScarlet"},{"name":"Miuzarte","username":"Miuzarte","email":"982809597@qq.com","commits":1,"url":"https://github.com/Miuzarte"},{"name":"Seamain","username":"Seamain","email":"quanminjun37@gmail.com","commits":1,"url":"https://github.com/Seamain"},{"name":"xjbeta","username":"xjbeta","email":"11794321+xjbeta@users.noreply.github.com","commits":1,"url":"https://github.com/xjbeta"}],"changelog":[{"hash":"3299dde4c877c8c5cc16f7dba4fec857d67fceaa","time":1758034754000,"email":"11794321+xjbeta@users.noreply.github.com","author":"xjbeta","message":"fix(doc/misc/sign/wbi.md): swift demo (#1389)"},{"hash":"22c19c917ea5eb11aa2835780ffac101a90fbfaf","time":1745004257000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"feat(misc/sign/wbi.md): add details"},{"hash":"17b0e43ec2573a3b7f99d5c4c204a4f3b7f9641b","time":1744996652000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"feat: add details"},{"hash":"526b0374c0ba58c7a1266762f464f5a5579b02ce","time":1744823327000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"feat(misc/sign/wbi.md): update haskell demo data"},{"hash":"ad1d2dd96dc3285e0ed3941796fb2ed2ed237536","time":1744819234000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"feat(misc/sign/wbi.md): haskell demo"},{"hash":"4abf38f2aa66f38fc4041cb8eb9ad850679281a7","time":1744514563000,"email":"quanminjun37@gmail.com","author":"Seamain","message":"优化wbi.md里的Swift代码 (#1208)"},{"hash":"724e618babe94dcc1ddd557ae33fa3f9f176cf12","time":1743773185000,"email":"982809597@qq.com","author":"Miuzarte","message":"重构 wbi golang 实现"},{"hash":"1e24c6b1889160c4c35c01416aa4239501accf5f","time":1726759053000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"调整部分接口描述与错误修复 (#1088)","coAuthors":[{"name":"社会易姐QwQ","email":"45892418+SocialSisterYi@users.noreply.github.com"}]},{"hash":"1ab70f7914d82214aa1a1b8e732a4ac5c37322a4","time":1726676140000,"email":"93977077+MukjepScarlet@users.noreply.github.com","author":"木葉 Scarlet","message":"fix: 优化Kotlin样例 (#1096)"},{"hash":"60a0c5d1a2f44fe61335da04571305fa7727a968","time":1724238159000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"feat: 各种接口补充与错误修正 (#1066)"},{"hash":"cb4f767d4ee3f4f66b6caff04c9c40164ea4af54","time":1722218589000,"email":"93977077+MukjepScarlet@users.noreply.github.com","author":"木葉 Scarlet","message":"feat: 添加wbi加签的Kotlin实现, 优化Java实现 (#1068)"},{"hash":"18c1efbc102ae6b44c8f5314c90e5e64f0d926cd","time":1721909032000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"feat: bili_ticket 算法 Java 实现 及 信息补充 及 错误修正 (#1061)"},{"hash":"8f419c1c9cdb9b32d6441c735647332ccdb21dd4","time":1721469205000,"email":"amtoaer@outlook.com","author":"ᴀᴍᴛᴏᴀᴇʀ","message":"fix: 修复获取 wbi 签名的 rust 实现 (#1059)"},{"hash":"20940eefcd80ce9e414c8cc3f4d75be1e2db1148","time":1718245920000,"email":"62951481+xrz-cloud@users.noreply.github.com","author":"xrz","message":"feat. wbi签名算法添加typescript实现 (#1031)"},{"hash":"767cb93264eb5d741aff70d35ce12313e7218c15","time":1718245814000,"email":"69023595+stmtc233@users.noreply.github.com","author":"stmtc233","message":"Update wbi.md (#1034)"},{"hash":"e7ab2d770b423a891ed7e663d94bfe1f0f59501d","time":1718245563000,"email":"51024916+YuHuanTin@users.noreply.github.com","author":"YuHuanTin","message":"wbi、av2bv、bv2av 的 c++ 实现 (#1035)"},{"hash":"64e1bde5be5bba4e8c98da4945c08a48d375e437","time":1712071300000,"email":"ivan@hanloth.com","author":"Ivan Hanloth","message":"修复Demo访问/x/web-interface/nav被ban的问题 (#991)"},{"hash":"24397b6601e6249bab15b8f9c17481fbfb4e6d40","time":1702290813000,"email":"70561268+cxw620@users.noreply.github.com","author":"陈寒彤","message":"update wbi sign description (#892)"},{"hash":"27308c22c83e14bb67ac39425574dfbe32aa0b89","time":1702173833000,"email":"45706356+WindowsMEMZ@users.noreply.github.com","author":"Mark Chan","message":"为avid-bvid转换和Wbi签名添加Swift实现 (#890)"},{"hash":"56bfa77a70bab7c14cd829fd9726e560ed122e7f","time":1701615703000,"email":"fwqaaq@gmail.com","author":"fwqaaq","message":"Update wbi.md about rust and javascript code examples for wbi signature implementation (#884)"},{"hash":"86ba55259dfbed8e076a572a4ef416a5b29d4a96","time":1700385876000,"email":"catlair@qq.com","author":"LaMerChiang","message":"Update wbi.md (#866)"},{"hash":"542359a54f9abb4e4a6979088c9d9f75c84a98de","time":1691929891000,"email":"69347367+188102836@users.noreply.github.com","author":"188102836","message":"优化示例代码 (#777)","coAuthors":[{"name":"ud2","email":"sjx233@qq.com"},{"name":"ud2","email":"sjx233@qq.com"}]},{"hash":"56d0126d5d35ac3b02e96edeb751d5a656b8f27e","time":1691719236000,"email":"emkqson@outlook.com","author":"PACI","message":"update io and time (#769)"},{"hash":"d023b55918b3d171eca0e9092f7e55a20a10cf0b","time":1688290621000,"email":"63290381+xiaoyv404@users.noreply.github.com","author":"小宇","message":"Fix language list error (#731)"},{"hash":"fd313b8c1cd2dcbcaf22c5aa68930dbf9354b690","time":1688099263000,"email":"takanashirikkax@gmail.com","author":"7rikka","message":"添加Wbi签名的Java实现 (#726)"},{"hash":"63deb66605188519d6a22b8e9bc396aca72182ad","time":1687947513000,"email":"73207840+lanyeeee@users.noreply.github.com","author":"kurisu_u","message":"给Wbi签名算法的Demo添加C#实现 (#719)","coAuthors":[{"name":"社会易姐QwQ","email":"45892418+SocialSisterYi@users.noreply.github.com"}]},{"hash":"a8742859fc4a41d6a4fabccf56bb70063a15c942","time":1687946222000,"email":"takanashirikkax@gmail.com","author":"7rikka","message":"添加Wbi签名的Java实现 (#722)"},{"hash":"0abdd4b847c8a90e628d41c6fbc4f0a21227b1a5","time":1687499343000,"email":"62145553+vapehacker@users.noreply.github.com","author":"icyu","message":"修改wbi文档中的流程描述 (#718)"},{"hash":"3aaf9679c51eec05c28fe505cd26238e6c2ac303","time":1687307987000,"email":"ywmoyue@163.com","author":"ywmoyue","message":"补充wbi文档 (#706)"},{"hash":"fc0c6874d94f45d97b74c624fa61baeacdace2ca","time":1685870545000,"email":"jannchie@gmail.com","author":"Jianqi Pan","message":"✨ feat: add golang wbi demo (#696)"},{"hash":"7b5ac3f50375310176709dc531d61a1761b6f5d8","time":1685064391000,"email":"me@isoasflus.com","author":"THMonster","message":"修正wbi文档中的一些描述错误 (#684)"},{"hash":"05ac3d5e2a9e28be3bf129ae8c78ffdbebaa161c","time":1684805901000,"email":"1440239038@qq.com","author":"SocialSisterYi","message":"添加文档【Wbi 接口签名】,修改目录结构"}]},"filePathRelative":"docs/misc/sign/wbi.md"}');export{E as comp,m as data};