返回提交历史
Modified
docs/misc/sign/wbi.md
+59
-44
XFEstudio/bilibili-API-collect
fix: 优化Kotlin样例 (#1096)
优化点: - 用实体类保存数据, 缓存/加签更方便 - 之前的貌似有bug (可能是参数顺序导致的? 待确认), 现在这个版本实测无误
1ab70f7
代码差异
1 个文件
+59
-44
@@ -731,24 +731,19 @@ public class WbiTest {
731
731
732
732
### Kotlin
733
733
734
```kotlin
735
import java.net.URLEncoder
736
import java.nio.charset.StandardCharsets
737
import java.security.MessageDigest
734
说明: 为了便于使用和缓存, 重新编写为实体类形式, 并拆分了多个文件. 使用官方的JSON序列化. (可以根据需要换成其他的)
738
735
739
private val hexDigits = "0123456789abcdef".toCharArray()
740
741
fun ByteArray.toHexString() = buildString(this.size shl 1) {
742
this@toHexString.forEach { byte ->
743
append(hexDigits[byte.toInt() ushr 4 and 15])
744
append(hexDigits[byte.toInt() and 15])
745
}
746
}
736
WbiParams.kt
747
737
748
fun String.toMD5(): String {
749
val md = MessageDigest.getInstance("MD5")
750
val digest = md.digest(this.toByteArray())
751
return digest.toHexString()
738
```kotlin
739
import kotlinx.serialization.Serializable
740
import kotlinx.serialization.json.JsonElement
741
import kotlinx.serialization.json.JsonObject
742
import kotlinx.serialization.json.jsonPrimitive
743
744
private fun JsonElement?.get(): String {
745
check(this != null) { "No contents found" }
746
return this.jsonPrimitive.content.split('/').last().removeSuffix(".png")
752
747
}
753
748
754
749
private val mixinKeyEncTab = intArrayOf(
@@ -758,46 +753,66 @@ private val mixinKeyEncTab = intArrayOf(
758
753
36, 20, 34, 44, 52
759
754
)
760
755
761
fun getMixinKey(imgKey: String, subKey: String): String {
762
val s = imgKey + subKey
763
return buildString {
764
repeat(32) {
765
append(s[mixinKeyEncTab[it]])
756
@Serializable
757
data class WbiParams(
758
val imgKey: String,
759
val subKey: String,
760
) {
761
// 此处整合了切分参数(直接传入{img_url:string, sub_url:string}即可), 不需要可以删掉
762
constructor(wbiImg: JsonObject) : this(wbiImg["img_url"].get(), wbiImg["sub_url"].get())
763
764
private val mixinKey: String
765
get() = (imgKey + subKey).let { s ->
766
buildString {
767
repeat(32) {
768
append(s[mixinKeyEncTab[it]])
769
}
770
}
771
}
772
773
// 创建对象(GET获取或者读缓存, 比如Redis)之后, 直接调用此函数处理
774
fun enc(params: Map<String, Any?>): String {
775
val sorted = params.filterValues { it != null }.toSortedMap()
776
return buildString {
777
append(sorted.toQueryString())
778
val wts = System.currentTimeMillis() / 1000
779
sorted["wts"] = wts
780
append("&wts=")
781
append(wts)
782
append("&w_rid=")
783
append((sorted.toQueryString() + mixinKey).toMD5())
766
784
}
767
785
}
768
786
}
787
```
769
788
770
fun Any.encodeURIComponent() =
771
URLEncoder.encode(this.toString(), StandardCharsets.UTF_8).replace("+", "%20")
789
Extensions.kt
772
790
773
fun encWbi(params: Map<String, Any>, imgKey: String, subKey: String): String {
774
val mixinKey = getMixinKey(imgKey, subKey)
775
val s = params.toSortedMap().let {
776
it["wts"] to System.currentTimeMillis() / 1000
777
it.entries.joinToString("&") { (k, v) ->
778
"${k.encodeURIComponent()}=${v.encodeURIComponent()}"
779
}
791
```kotlin
792
import java.security.MessageDigest
793
794
private val hexDigits = "0123456789abcdef".toCharArray()
795
796
fun ByteArray.toHexString() = buildString(this.size shl 1) {
797
this@toHexString.forEach { byte ->
798
append(hexDigits[byte.toInt() ushr 4 and 15])
799
append(hexDigits[byte.toInt() and 15])
780
800
}
781
return "$s&w_rid=${(s + mixinKey).toMD5()}"
782
801
}
783
802
784
fun main() {
785
val imgKey = "653657f524a547ac981ded72ea172057"
786
val subKey = "6e4909c702f846728e64f6007736a338"
787
val mixinKey = getMixinKey(imgKey, subKey)
788
println(mixinKey) // 72136226c6a73669787ee4fd02a74c27
789
790
// 需要加签的参数
791
val param = mapOf(
792
"foo" to "one+one four",
793
"bar" to "五一四",
794
"baz" to 1919810,
795
)
803
fun String.toMD5(): String {
804
val md = MessageDigest.getInstance("MD5")
805
val digest = md.digest(this.toByteArray())
806
return digest.toHexString()
807
}
796
808
797
println(encWbi(param, imgKey, subKey))
809
fun Map<String, Any?>.toQueryString() = this.filterValues { it != null }.entries.joinToString("&") { (k, v) ->
810
"${k.encodeURIComponent()}=${v!!.encodeURIComponent()}"
798
811
}
799
812
```
800
813
814
获取和使用案例略
815
801
816
### PHP
802
817
803
818
来自[SocialSisterYi/bilibili-API-collect#813](https://github.com/SocialSisterYi/bilibili-API-collect/issues/813)