🚀调整项目结构
This commit is contained in:
84
docs/other/API_sign.md
Normal file
84
docs/other/API_sign.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# API 签名与鉴权
|
||||
|
||||
部分客户端专用的 rest api 存在基于 sign 的鉴权,需要使用规定的`appkey`及其对应的`appsec`与原始请求参数进行签名计算
|
||||
|
||||
不同`appkey`对应不同的 app (如客户端、概念版、必剪、漫画、bililink等)
|
||||
|
||||
不同平台同 app 也会存在不同的 `appkey`(如安卓端、ios端、TV端等)
|
||||
|
||||
同平台同 app 下不同功能也会存在不同的 `appkey`(如登录专用、取流专用等)
|
||||
|
||||
**appkey与appsec一一对应**
|
||||
|
||||
- [API签名的计算方式](#API签名的计算方式)
|
||||
- [已知的APPKey](#已知的APPKey)
|
||||
|
||||
---
|
||||
|
||||
## API签名的计算方式
|
||||
|
||||
首先为参数中添加`appkey`字段,然后按照参数的 key 重新排序,再将重排序后的参数使用 url query 格式序列化拼接与该 appkey 相对应的 appsec (盐值) 进行**md5 hash计算**(32位小写),该 hash 便是 API 签名
|
||||
|
||||
为参数尾部增添`sign`字段,它的值为上一步计算所得的 hash,一并作为表单提交
|
||||
|
||||
**实例:**
|
||||
|
||||
使用 appkey = `1d8b6e7d45233436`, appsec = `560c52ccd288fed045859ed18bffd973` 对如下 `params` 参数进行签名
|
||||
|
||||
```python
|
||||
import hashlib
|
||||
import urllib.parse
|
||||
|
||||
def appsign(params, appkey, appsec):
|
||||
'为请求参数进行 api 签名'
|
||||
params.update({'appkey': appkey})
|
||||
params = dict(sorted(params.items())) # 重排序参数 key
|
||||
query = urllib.parse.urlencode(params) # 序列化参数
|
||||
sign = hashlib.md5((query+appsec).encode()).hexdigest() # 计算 api 签名
|
||||
params.update({'sign':sign})
|
||||
return params
|
||||
|
||||
appkey = '1d8b6e7d45233436'
|
||||
appsec = '560c52ccd288fed045859ed18bffd973'
|
||||
params = {
|
||||
'id':114514,
|
||||
'str':'1919810',
|
||||
'test':'いいよ,こいよ',
|
||||
}
|
||||
signed_params = appsign(params, appkey, appsec)
|
||||
query = urllib.parse.urlencode(signed_params)
|
||||
print(signed_params)
|
||||
print(query)
|
||||
```
|
||||
|
||||
输出以下内容,分别是进行 api 签名后参数的 dict 以及 url query 格式
|
||||
|
||||
```
|
||||
{'appkey': '1d8b6e7d45233436', 'id': 114514, 'str': '1919810', 'test': 'いいよ,こいよ', 'sign': '01479cf20504d865519ac50f33ba3a7d'}
|
||||
appkey=1d8b6e7d45233436&id=114514&str=1919810&test=%E3%81%84%E3%81%84%E3%82%88%EF%BC%8C%E3%81%93%E3%81%84%E3%82%88&sign=01479cf20504d865519ac50f33ba3a7d
|
||||
```
|
||||
|
||||
## 已知的APPKey
|
||||
|
||||
| appkey | appsec(sign盐值) | 平台 | 应用 | 备注 |
|
||||
|------------------|----------------------------------|-----|----------|------|
|
||||
| 07da50c9a0bf829f | 25bdede4e1581c836cab73a48790ca6e | 安卓 | 概念版 | |
|
||||
| 1d8b6e7d45233436 | 560c52ccd288fed045859ed18bffd973 | 安卓 | 客户端 | 一般用途 |
|
||||
| 178cf125136ca8ea | 34381a26236dd1171185c0beb042e1c6 | 安卓 | 概念版 | |
|
||||
| 27eb53fc9058f8c3 | c2ed53a74eeefe3cf99fbd01d8c9c375 | ios | 客户端 | 一般用途 |
|
||||
| 37207f2beaebf8d7 | e988e794d4d4b6dd43bc0e89d6e90c43 | 安卓 | biliLink | |
|
||||
| 4409e2ce8ffd12b8 | 59b43e04ad6965f34319062b478f83dd | TV | 客户端 | |
|
||||
| 57263273bc6b67f6 | a0488e488d1567960d3a765e8d129f90 | 安卓 | 客户端 | |
|
||||
| 8d23902c1688a798 | 710f0212e62bd499b8d3ac6e1db9302a | 安卓 | 车机版 | |
|
||||
| 5dce947fe22167f9 | | 安卓 | 必剪 | |
|
||||
| 7d336ec01856996b | a1ce6983bc89e20a36c37f40c4f1a0dd | 安卓 | 概念版 | |
|
||||
| 85eb6835b0a1034e | 2ad42749773c441109bdc0191257a664 | | | |
|
||||
| 8e16697a1b4f8121 | f5dd03b752426f2e623d7badb28d190a | 安卓 | 国际版 | |
|
||||
| aae92bc66f3edfab | af125a0d5279fd576c1b4418a3e8276d | PC | 投稿工具 | |
|
||||
| ae57252b0c09105d | c75875c596a69eb55bd119e74b07cfe3 | 安卓 | 国际版 | |
|
||||
| bb3101000e232e27 | 36efcfed79309338ced0380abd824ac1 | 安卓 | 国际版 | |
|
||||
| bca7e84c2d947ac6 | 60698ba2f68e01ce44738920a0ffe768 | 安卓 | 客户端 | 登录专用 |
|
||||
| cc578d267072c94d | ffb6bb4c4edae2566584dbcacfc6a6ad | 安卓 | 轻视频 | |
|
||||
| cc8617fd6961e070 | 3131924b941aac971e45189f265262be | 安卓 | 漫画 | |
|
||||
| iVGUTjsxvpLeuDCf | aHRmhWMLkdeMuILqORnYZocwMBpMEOdt | 安卓 | 客户端 | 取流专用 |
|
||||
| YvirImLGlLANCLvM | JNlZNgfNGKZEpaDTkCdPQVXntXhuiJEM | ios | 客户端 | 取流专用 |
|
||||
389
docs/other/bvid_desc.md
Normal file
389
docs/other/bvid_desc.md
Normal file
@@ -0,0 +1,389 @@
|
||||
# bvid说明
|
||||
|
||||
2020-03-23 B站推出了全新的稿件视频id`bvid`来接替之前的`avid`,其意义与之相同
|
||||
|
||||
详见:
|
||||
|
||||
1. [【升级公告】AV号全面升级至BV号(专栏)](https://www.bilibili.com/read/cv5167957)
|
||||
2. [【升级公告】AV号全面升级至BV号](https://www.bilibili.com/blackboard/activity-BV-PC.html)
|
||||
|
||||
---
|
||||
|
||||
- [概述](#概述)
|
||||
- [格式](#格式)
|
||||
- [实质](#实质)
|
||||
- [avid发号方式的变化](#avid发号方式的变化)
|
||||
|
||||
- [算法概述](#算法概述)
|
||||
- [av->bv算法](#av->bv算法)
|
||||
- [bv->av算法](#bv->av算法)
|
||||
|
||||
- [编程实现](#编程实现)
|
||||
|
||||
- [Python](#Python)
|
||||
|
||||
- [C](#C)
|
||||
|
||||
- [TypeScript](#TypeScript)
|
||||
|
||||
- [Java](#Java)
|
||||
|
||||
- [Kotlin](#Kotlin)
|
||||
|
||||
- [Golang](#Golang)
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
### 格式
|
||||
|
||||
“bvid”恒为长度为12的字符串,前两个字母为大写“BV”,后10个为base58计算结果
|
||||
|
||||
### 实质
|
||||
|
||||
“bvid"为“avid”的base58编码,可通过算法进行相互转化
|
||||
|
||||
### avid发号方式的变化
|
||||
|
||||
从2009-09-09 09:09:09 [av2](https://www.bilibili.com/video/av2)的发布到2020-03-28 19:45:02 [av99999999](https://www.bilibili.com/video/av99999999)的发布B站结束了以投稿时间为顺序的avid发放,改为随机发放avid
|
||||
|
||||
~~暗示B站东方要完?泪目~~
|
||||
|
||||
## 算法概述
|
||||
|
||||
算法以及程序主要参考[知乎@mcfx的回答](https://www.zhihu.com/question/381784377/answer/1099438784)
|
||||
|
||||
### av->bv算法
|
||||
|
||||
注:本算法及示例程序仅能编码及解码avid<` 29460791296 `,无法验证avid>=` 29460791296 `的正确性
|
||||
|
||||
1. a=(avid⊕177451812)+8728348608
|
||||
2. 以i为循环变量循环6次b[i]=(a/58^i)%58
|
||||
3. 将b[i]中各个数字转换为以下码表中的字符
|
||||
|
||||
码表:
|
||||
|
||||
> fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF
|
||||
|
||||
4. 初始化字符串b[i]=`BV1 4 1 7 `
|
||||
|
||||
5. 按照以下字符顺序编码表编码并填充至b[i]
|
||||
|
||||
字符顺序编码表:
|
||||
|
||||
> 0 -> 11
|
||||
>
|
||||
> 1 -> 10
|
||||
>
|
||||
> 2 -> 3
|
||||
>
|
||||
> 3 -> 8
|
||||
>
|
||||
> 4 -> 4
|
||||
>
|
||||
> 5 -> 6
|
||||
|
||||
|
||||
### bv->av算法
|
||||
|
||||
为以上算法的逆运算
|
||||
|
||||
## 编程实现
|
||||
|
||||
使用Python、C、TypeScript、Java、Kotlin以及Golang作为示例,欢迎社区提交更多例程
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF' # 码表
|
||||
tr = {} # 反查码表
|
||||
# 初始化反查码表
|
||||
for i in range(58):
|
||||
tr[table[i]] = i
|
||||
s = [11, 10, 3, 8, 4, 6] # 位置编码表
|
||||
XOR = 177451812 # 固定异或值
|
||||
ADD = 8728348608 # 固定加法值
|
||||
|
||||
def bv2av(x):
|
||||
r = 0
|
||||
for i in range(6):
|
||||
r += tr[x[s[i]]] * 58 ** i
|
||||
return (r - ADD) ^ XOR
|
||||
|
||||
def av2bv(x):
|
||||
x = (x ^ XOR) + ADD
|
||||
r = list('BV1 4 1 7 ')
|
||||
for i in range(6):
|
||||
r[s[i]] = table[x // 58 ** i % 58]
|
||||
return ''. join(r)
|
||||
|
||||
print(av2bv(170001))
|
||||
print(bv2av('BV17x411w7KC'))
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
BV17x411w7KC
|
||||
170001
|
||||
```
|
||||
|
||||
### C
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
const char table[] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"; // 码表
|
||||
char tr[124]; // 反查码表
|
||||
const unsigned long long XOR = 177451812; // 固定异或值
|
||||
const unsigned long long ADD = 8728348608; // 固定加法值
|
||||
const int s[] = {11, 10, 3, 8, 4, 6}; // 位置编码表
|
||||
|
||||
// 初始化反查码表
|
||||
void tr_init() {
|
||||
for (int i = 0; i < 58; i++)
|
||||
tr[table[i]] = i;
|
||||
}
|
||||
|
||||
unsigned long long bv2av(char bv[]) {
|
||||
unsigned long long r = 0;
|
||||
unsigned long long av;
|
||||
for (int i = 0; i < 6; i++)
|
||||
r += tr[bv[s[i]]] * (unsigned long long)pow(58, i);
|
||||
av = (r - ADD) ^ XOR;
|
||||
return av;
|
||||
}
|
||||
|
||||
char *av2bv(unsigned long long av) {
|
||||
char *result = (char*)malloc(13);
|
||||
strcpy(result,"BV1 4 1 7 ");
|
||||
av = (av ^ XOR) + ADD;
|
||||
for (int i = 0; i < 6; i++)
|
||||
result[s[i]] = table[(unsigned long long)(av / (unsigned long long)pow(58, i)) % 58];
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
tr_init();
|
||||
printf("%s\n", av2bv(170001));
|
||||
printf("%u\n", bv2av("BV17x411w7KC"));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
BV17x411w7KC
|
||||
170001
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
感谢[#417](https://github.com/SocialSisterYi/bilibili-API-collect/issues/417#issuecomment-1186475063)提供
|
||||
|
||||
```typescript
|
||||
export default class BvCode {
|
||||
private TABEL = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'; // 码表
|
||||
private TR: Record<string, number> = {}; // 反查码表
|
||||
private S = [11, 10, 3, 8, 4, 6]; // 位置编码表
|
||||
private XOR = 177451812; // 固定异或值
|
||||
private ADD = 8728348608; // 固定加法值
|
||||
constructor() {
|
||||
// 初始化反查码表
|
||||
const len = this.TABEL.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
this.TR[this.TABEL[i]] = i;
|
||||
}
|
||||
}
|
||||
av2bv(av: number): string {
|
||||
const x_ = (av ^ this.XOR) + this.ADD;
|
||||
const r = ['B', 'V', '1', , , '4', , '1', , '7'];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
r[this.S[i]] = this.TABEL[Math.floor(x_ / 58 ** i) % 58];
|
||||
}
|
||||
return r.join('');
|
||||
}
|
||||
bv2av(bv: string): number {
|
||||
let r = 0;
|
||||
for (let i = 0; i < 6; i++) {
|
||||
r += this.TR[bv[this.S[i]]] * 58 ** i;
|
||||
}
|
||||
return (r - this.ADD) ^ this.XOR;
|
||||
}
|
||||
}
|
||||
|
||||
const bvcode = new BvCode();
|
||||
|
||||
console.log(bvcode.av2bv(170001));
|
||||
console.log(bvcode.bv2av('BV17x411w7KC'));
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
BV17x411w7KC
|
||||
170001
|
||||
```
|
||||
|
||||
### Java
|
||||
|
||||
```java
|
||||
/**
|
||||
* 算法来自:https://www.zhihu.com/question/381784377/answer/1099438784
|
||||
*/
|
||||
public class Util {
|
||||
private static final String TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
|
||||
private static final int[] S = new int[]{11, 10, 3, 8, 4, 6};
|
||||
private static final int XOR = 177451812;
|
||||
private static final long ADD = 8728348608L;
|
||||
private static final Map<Character, Integer> MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 58; i++) {
|
||||
MAP.put(TABLE.charAt(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
public static String aidToBvid(int aid) {
|
||||
long x = (aid ^ XOR) + ADD;
|
||||
char[] chars = new char[]{'B', 'V', '1', ' ', ' ', '4', ' ', '1', ' ', '7', ' ', ' '};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int pow = (int) Math.pow(58, i);
|
||||
long i1 = x / pow;
|
||||
int index = (int) (i1 % 58);
|
||||
chars[S[i]] = TABLE.charAt(index);
|
||||
}
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
|
||||
public static int bvidToAid(String bvid) {
|
||||
long r = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
r += MAP.get(bvid.charAt(S[i])) * Math.pow(58, i);
|
||||
}
|
||||
return (int) ((r - ADD) ^ XOR);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Kotlin
|
||||
```kotlin
|
||||
/**
|
||||
* 此程序非完全原创,改编自GH站内某大佬的Java程序,修改了部分代码,且转换为Kotlin
|
||||
* 算法来源同上
|
||||
*/
|
||||
object VideoUtils {
|
||||
//这里是由知乎大佬不知道用什么方法得出的转换用数字
|
||||
var ss = intArrayOf(11, 10, 3, 8, 4, 6, 2, 9, 5, 7)
|
||||
var xor: Long = 177451812 //二进制时加减数1
|
||||
|
||||
var add = 8728348608L //十进制时加减数2
|
||||
|
||||
//变量初始化工作,加载哈希表
|
||||
private const val table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
|
||||
private val mp = HashMap<String, Int>()
|
||||
private val mp2 = HashMap<Int, String>()
|
||||
|
||||
//现在,定义av号和bv号互转的方法
|
||||
//定义一个power乘方方法,这是转换进制必要的
|
||||
fun power(a: Int, b: Int): Long {
|
||||
var power: Long = 1
|
||||
for (c in 0 until b) power *= a.toLong()
|
||||
return power
|
||||
}
|
||||
|
||||
//bv转av方法
|
||||
fun bv2av(s: String): String {
|
||||
var r: Long = 0
|
||||
//58进制转换
|
||||
for (i in 0..57) {
|
||||
val s1 = table.substring(i, i + 1)
|
||||
mp[s1] = i
|
||||
}
|
||||
for (i in 0..5) {
|
||||
r += mp[s.substring(ss[i], ss[i] + 1)]!! * power(58, i)
|
||||
}
|
||||
//转换完成后,需要处理,带上两个随机数
|
||||
return (r - add xor xor).toString()
|
||||
}
|
||||
|
||||
//av转bv方法
|
||||
fun av2bv(st: String): String {
|
||||
try {
|
||||
var s = java.lang.Long.valueOf(st.split("av".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()[1])
|
||||
val sb = StringBuffer("BV1 4 1 7 ")
|
||||
//逆向思路,先将随机数还原
|
||||
s = (s xor xor) + add
|
||||
//58进制转回
|
||||
for (i in 0..57) {
|
||||
val s1 = table.substring(i, i + 1)
|
||||
mp2[i] = s1
|
||||
}
|
||||
for (i in 0..5) {
|
||||
val r = mp2[(s / power(58, i) % 58).toInt()]
|
||||
sb.replace(ss[i], ss[i] + 1, r!!)
|
||||
}
|
||||
return sb.toString()
|
||||
} catch (e: ArrayIndexOutOfBoundsException) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Golang
|
||||
```go
|
||||
package main
|
||||
|
||||
import "math"
|
||||
|
||||
const TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
|
||||
var S = [11]uint{11, 10, 3, 8, 4, 6}
|
||||
const XOR = 177451812
|
||||
const ADD = 8728348608
|
||||
|
||||
var TR = map[string]int64{}
|
||||
|
||||
// 初始化 TR
|
||||
func init() {
|
||||
for i := 0; i < 58; i++ {
|
||||
TR[TABLE[i:i+1]] = int64(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BV2AV(bv string) int64 {
|
||||
r := int64(0)
|
||||
for i := 0; i < 6; i++ {
|
||||
r += TR[bv[S[i]:S[i]+1]] * int64(math.Pow(58, float64(i)))
|
||||
}
|
||||
return (r - ADD) ^ XOR
|
||||
}
|
||||
|
||||
func AV2BV(av int64) string {
|
||||
x := (av ^ XOR) + ADD
|
||||
r := []rune("BV1 4 1 7 ")
|
||||
for i := 0; i < 6; i++ {
|
||||
r[S[i]] = rune(TABLE[x/int64(math.Pow(58, float64(i)))%58])
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func main() {
|
||||
println(AV2BV(170001))
|
||||
println(BV2AV("BV17x411w7KC"))
|
||||
}
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
BV17x411w7KC
|
||||
170001
|
||||
```
|
||||
65
docs/other/errcode.md
Normal file
65
docs/other/errcode.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 公共错误码
|
||||
|
||||
下表为大部分接口返回值中`code`字段值中公共的错误代码
|
||||
|
||||
- [权限类](#权限类)
|
||||
- [请求类](#请求类)
|
||||
|
||||
---
|
||||
|
||||
## 权限类
|
||||
|
||||
| 代码 | 含义 |
|
||||
| ---- | -------------------------- |
|
||||
| -1 | 应用程序不存在或已被封禁 |
|
||||
| -2 | Access Key 错误 |
|
||||
| -3 | API 校验密匙错误 |
|
||||
| -4 | 调用方对该 Method 没有权限 |
|
||||
| -101 | 账号未登录 |
|
||||
| -102 | 账号被封停 |
|
||||
| -103 | 积分不足 |
|
||||
| -104 | 硬币不足 |
|
||||
| -105 | 验证码错误 |
|
||||
| -106 | 账号非正式会员或在适应期 |
|
||||
| -107 | 应用不存在或者被封禁 |
|
||||
| -108 | 未绑定手机 |
|
||||
| -110 | 未绑定手机 |
|
||||
| -111 | csrf 校验失败 |
|
||||
| -112 | 系统升级中 |
|
||||
| -113 | 账号尚未实名认证 |
|
||||
| -114 | 请先绑定手机 |
|
||||
| -115 | 请先完成实名认证 |
|
||||
|
||||
## 请求类
|
||||
|
||||
| 代码 | 含义 |
|
||||
| ---- | --------------------- |
|
||||
| -304 | 木有改动 |
|
||||
| -307 | 撞车跳转 |
|
||||
| -400 | 请求错误 |
|
||||
| -401 | 未认证 (或非法请求) |
|
||||
| -403 | 访问权限不足 |
|
||||
| -404 | 啥都木有 |
|
||||
| -405 | 不支持该方法 |
|
||||
| -409 | 冲突 |
|
||||
| -412 | 请求被拦截 (客户端 ip 被服务端风控) |
|
||||
| -500 | 服务器错误 |
|
||||
| -503 | 过载保护,服务暂不可用 |
|
||||
| -504 | 服务调用超时 |
|
||||
| -509 | 超出限制 |
|
||||
| -616 | 上传文件不存在 |
|
||||
| -617 | 上传文件太大 |
|
||||
| -625 | 登录失败次数太多 |
|
||||
| -626 | 用户不存在 |
|
||||
| -628 | 密码太弱 |
|
||||
| -629 | 用户名或密码错误 |
|
||||
| -632 | 操作对象数量限制 |
|
||||
| -643 | 被锁定 |
|
||||
| -650 | 用户等级太低 |
|
||||
| -652 | 重复的用户 |
|
||||
| -658 | Token 过期 |
|
||||
| -662 | 密码时间戳过期 |
|
||||
| -688 | 地理区域限制 |
|
||||
| -689 | 版权限制 |
|
||||
| -701 | 扣节操失败 |
|
||||
|-8888|对不起,服务器开小差了~ (ಥ﹏ಥ)|
|
||||
44
docs/other/picture.md
Normal file
44
docs/other/picture.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# 图片格式化
|
||||
|
||||
对于\*.hdslb.com/bfs下的图片文件都可以使用以下格式化参数
|
||||
|
||||
> \*.hdslb.com/bfs/\*/\*.\[jpg/png/gif\]@{width}w\_{high}h\_{quality}q.{format}
|
||||
|
||||
| 可选参数 | 含义 | 备注 |
|
||||
| -------- | ---------------- | ---------------- |
|
||||
| width | 图片最大限制宽度 | |
|
||||
| high | 图片最大限制高度 | |
|
||||
| quality | 图片质量百分比 | 仅限webp |
|
||||
| format | 图片格式 | 仅限png/jpg/webp |
|
||||
|
||||
**示例:**
|
||||
|
||||
原始图片
|
||||
|
||||
https://i1.hdslb.com/bfs/archive/e5fff1472bad1c0c6bcb3004205f9be23b58ffc0.jpg
|
||||
|
||||

|
||||
|
||||
高度限制为100
|
||||
|
||||
https://i1.hdslb.com/bfs/archive/e5fff1472bad1c0c6bcb3004205f9be23b58ffc0.jpg@100h
|
||||
|
||||

|
||||
|
||||
宽度限制为100
|
||||
|
||||
https://i1.hdslb.com/bfs/archive/e5fff1472bad1c0c6bcb3004205f9be23b58ffc0.jpg@100w
|
||||
|
||||

|
||||
|
||||
转换格式为webp
|
||||
|
||||
https://i1.hdslb.com/bfs/archive/e5fff1472bad1c0c6bcb3004205f9be23b58ffc0.jpg@.webp
|
||||
|
||||

|
||||
|
||||
转换为webp图片质量为1%
|
||||
|
||||
https://i1.hdslb.com/bfs/archive/e5fff1472bad1c0c6bcb3004205f9be23b58ffc0.jpg@1q.webp
|
||||
|
||||

|
||||
79
docs/other/time_stamp.md
Normal file
79
docs/other/time_stamp.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# 获取当前时间戳
|
||||
|
||||
- [获取当前时间戳](#获取当前时间戳)
|
||||
- [获取当前时间戳](#获取当前时间戳-1)
|
||||
- [获取服务器端UTC时间](#获取服务器端utc时间)
|
||||
|
||||
---
|
||||
|
||||
## 获取当前时间戳
|
||||
|
||||
> https://api.bilibili.com/x/report/click/now
|
||||
|
||||
*请求方式:GET*
|
||||
|
||||
**json回复:**
|
||||
|
||||
根对象:
|
||||
|
||||
| 字段 | 类型 | 内容 | 备注 |
|
||||
| ------- | ---- | -------- | ------- |
|
||||
| code | num | 返回值 | 0:成功 |
|
||||
| message | str | 错误信息 | 默认为0 |
|
||||
| ttl | num | 1 | |
|
||||
| data | obj | 信息本体 | |
|
||||
|
||||
`data`对象:
|
||||
|
||||
| 字段 | 类型 | 内容 | 备注 |
|
||||
| ---- | ---- | ------------ | ---- |
|
||||
| now | num | 当前的时间戳 | |
|
||||
|
||||
**示例:**
|
||||
|
||||
```shell
|
||||
curl 'https://api.bilibili.com/x/report/click/now'
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>查看响应示例:</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "0",
|
||||
"ttl": 1,
|
||||
"data": {
|
||||
"now": 1592666471
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 获取服务器端UTC时间
|
||||
|
||||
> https://interface.bilibili.com/serverdate.js
|
||||
|
||||
*请求方式:GET*
|
||||
|
||||
**js回复:**
|
||||
|
||||
```js
|
||||
window.serverdate = Date.UTC(YYYY, M, D, h, m, s);
|
||||
```
|
||||
|
||||
**示例:**
|
||||
|
||||
```shell
|
||||
curl 'https://interface.bilibili.com/serverdate.js'
|
||||
```
|
||||
|
||||
|
||||
<details>
|
||||
<summary>查看响应示例:</summary>
|
||||
|
||||
```js
|
||||
window.serverdate = Date.UTC(2021, 4, 16, 17, 31, 8);
|
||||
```
|
||||
</details>
|
||||
Reference in New Issue
Block a user