XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/bilibili-API-collect

feat: 添加wbi加签的Kotlin实现, 优化Java实现 (#1068)

cb4f767
木葉 Scarlet <93977077+MukjepScarlet@users.noreply.github.com>
提交于

代码差异

1 个文件 +120 -37
Modified docs/misc/sign/wbi.md +120 -37
@@ -120,7 +120,7 @@
120 120
121 121 ## Demo
122 122
123 含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java)、[Swift](#Swift)、[C++](#CPlusPlus)、[Rust](#Rust) 语言编写的 Demo 。
123 含 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp)、[Java](#Java)、[Kotlin](#Kotlin)、[Swift](#Swift)、[C++](#CPlusPlus)、[Rust](#Rust) 语言编写的 Demo 。
124 124
125 125 ### Python
126 126
@@ -658,14 +658,13 @@ bar=514&baz=1919810&foo=114&wts=1687541921&w_rid=26e82b1b9b3a11dbb1807a9228a40d3
658 658
659 659 ### Java
660 660
661 需要 `hutool` 依赖
662
663 661 ```java
664 package com.example.demo;
665
666 import cn.hutool.crypto.SecureUtil;
667
662 import java.net.URLEncoder;
663 import java.nio.charset.StandardCharsets;
664 import java.security.MessageDigest;
665 import java.security.NoSuchAlgorithmException;
668 666 import java.util.*;
667 import java.util.stream.Collectors;
669 668
670 669 public class WbiTest {
671 670 private static final int[] mixinKeyEncTab = new int[]{
@@ -675,42 +674,126 @@ public class WbiTest {
675 674 36, 20, 34, 44, 52
676 675 };
677 676
677 private static final char[] hexDigits = "0123456789abcdef".toCharArray();
678
679 public static String md5(String input) {
680 try {
681 MessageDigest md = MessageDigest.getInstance("MD5");
682 byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
683 char[] result = new char[messageDigest.length * 2];
684 for (int i = 0; i < messageDigest.length; i++) {
685 result[i * 2] = hexDigits[(messageDigest[i] >> 4) & 0xF];
686 result[i * 2 + 1] = hexDigits[messageDigest[i] & 0xF];
687 }
688 return new String(result);
689 } catch (NoSuchAlgorithmException e) {
690 return null;
691 }
692 }
693
678 694 public static String getMixinKey(String imgKey, String subKey) {
679 695 String s = imgKey + subKey;
680 696 StringBuilder key = new StringBuilder();
681 for (int i = 0; i < 32; i++) {
697 for (int i = 0; i < 32; i++)
682 698 key.append(s.charAt(mixinKeyEncTab[i]));
683 }
684 699 return key.toString();
685 700 }
686 701
687 public static void main(String[] args) {
688 String imgKey = "653657f524a547ac981ded72ea172057";
689 String subKey = "6e4909c702f846728e64f6007736a338";
690 String mixinKey = getMixinKey(imgKey, subKey);
691 System.out.println(mixinKey);
692 //72136226c6a73669787ee4fd02a74c27
693 //{
694 // foo: 'one one four',
695 // bar: '五一四',
696 // baz: 1919810
697 //}
698 LinkedHashMap<String, Object> map = new LinkedHashMap<>();
699 map.put("foo", "one one four");
700 map.put("bar", "五一四");
701 map.put("baz", 1919810);
702 map.put("wts", System.currentTimeMillis() / 1000);
703 StringJoiner param = new StringJoiner("&");
704 //排序 + 拼接字符串
705 map.entrySet().stream()
706 .sorted(Map.Entry.comparingByKey())
707 .forEach(entry -> param.add(entry.getKey() + "=" + URLUtil.encode(entry.getValue().toString())));
708 String s = param + mixinKey;
709 String wbiSign = SecureUtil.md5(s);
710 System.out.println(wbiSign);
711 String finalParam = param + "&w_rid=" + wbiSign;
712 System.out.println(finalParam);
713 }
702 public static String encodeURIComponent(Object o) {
703 return URLEncoder.encode(o.toString(), StandardCharsets.UTF_8).replace("+", "%20");
704 }
705
706 public static void main(String[] args) {
707 String imgKey = "653657f524a547ac981ded72ea172057";
708 String subKey = "6e4909c702f846728e64f6007736a338";
709 String mixinKey = getMixinKey(imgKey, subKey);
710 System.out.println(mixinKey); // 72136226c6a73669787ee4fd02a74c27
711
712 // 用TreeMap自动排序
713 TreeMap<String, Object> map = new TreeMap<>();
714 map.put("foo", "one one four");
715 map.put("bar", "五一四");
716 map.put("baz", 1919810);
717 map.put("wts", System.currentTimeMillis() / 1000);
718 String param = map.entrySet().stream()
719 .map(it -> String.format("%s=%s", it.getKey(), encodeURIComponent(it.getValue())))
720 .collect(Collectors.joining("&"));
721 String s = param + mixinKey;
722
723 String wbiSign = md5(s);
724 System.out.println(wbiSign);
725 String finalParam = param + "&w_rid=" + wbiSign;
726 System.out.println(finalParam);
727 }
728 }
729 ```
730
731 ### Kotlin
732
733 ```kotlin
734 import java.net.URLEncoder
735 import java.nio.charset.StandardCharsets
736 import java.security.MessageDigest
737
738 private val hexDigits = "0123456789abcdef".toCharArray()
739
740 fun ByteArray.toHexString() = buildString(this.size shl 1) {
741 this@toHexString.forEach { byte ->
742 append(hexDigits[byte.toInt() ushr 4 and 15])
743 append(hexDigits[byte.toInt() and 15])
744 }
745 }
746
747 fun String.toMD5(): String {
748 val md = MessageDigest.getInstance("MD5")
749 val digest = md.digest(this.toByteArray())
750 return digest.toHexString()
751 }
752
753 private val mixinKeyEncTab = intArrayOf(
754 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
755 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
756 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
757 36, 20, 34, 44, 52
758 )
759
760 fun getMixinKey(imgKey: String, subKey: String): String {
761 val s = imgKey + subKey
762 return buildString {
763 repeat(32) {
764 append(s[mixinKeyEncTab[it]])
765 }
766 }
767 }
768
769 fun Any.encodeURIComponent() =
770 URLEncoder.encode(this.toString(), StandardCharsets.UTF_8).replace("+", "%20")
771
772 fun encWbi(params: Map<String, Any>, imgKey: String, subKey: String): String {
773 val mixinKey = getMixinKey(imgKey, subKey)
774 val s = params.toSortedMap().let {
775 it["wts"] to System.currentTimeMillis() / 1000
776 it.entries.joinToString("&") { (k, v) ->
777 "${k.encodeURIComponent()}=${v.encodeURIComponent()}"
778 }
779 }
780 return "$s&w_rid=${(s + mixinKey).toMD5()}"
781 }
782
783 fun main() {
784 val imgKey = "653657f524a547ac981ded72ea172057"
785 val subKey = "6e4909c702f846728e64f6007736a338"
786 val mixinKey = getMixinKey(imgKey, subKey)
787 println(mixinKey) // 72136226c6a73669787ee4fd02a74c27
788
789 // 需要加签的参数
790 val param = mapOf(
791 "foo" to "one+one four",
792 "bar" to "五一四",
793 "baz" to 1919810,
794 )
795
796 println(encWbi(param, imgKey, subKey))
714 797 }
715 798 ```
716 799
@@ -1214,4 +1297,4 @@ int main() {
1214 1297
1215 1298 ```text
1216 1299 avid=1755630705&cid=1574294582&fnval=4048&fnver=0&fourk=1&qn=32&wts=1717922933&w_rid=43571b838a1611fa121189083cfc1784
1217 ```
1300 ```