feat(qs): 汽水音乐平台接入——匿名搜索/试听、抖音扫码登录、解密流代理
- sdk/qs 平台模块(安卓参数指纹匿名搜索)+ sdk/apis/qs 取流: 匿名 30s 试听,登录态走签名 track_v2 + spade key AES-CTR 解密 - /login/qs/qr 抖音扫码登录(授权后 sessionid 解锁完整曲目) - /stream/qs/:id 解密流代理,/url 返回的相对地址按请求 host 补全 - 回归测试覆盖 kw 双通道(VIP 真音频/降级链)与 qs 试听;start.bat 去掉 SOURCE_ENABLED 直启
This commit is contained in:
1 parent
aa4f2eec67
commit
0f9cff2a08
26 files changed
+2172
-9
No files matched your search
@@ -0,0 +1,161 @@
|
||||
function rotateLeft(value: number, shiftBits: number): number {
|
||||
return (value << shiftBits) | (value >>> (32 - shiftBits));
|
||||
}
|
||||
|
||||
function addUnsigned(left: number, right: number): number {
|
||||
return (left + right) >>> 0;
|
||||
}
|
||||
|
||||
function f(x: number, y: number, z: number): number {
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
function g(x: number, y: number, z: number): number {
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
function h(x: number, y: number, z: number): number {
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
function i(x: number, y: number, z: number): number {
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
function ff(a: number, b: number, c: number, d: number, x: number, s: number, ac: number): number {
|
||||
return addUnsigned(rotateLeft(addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac)), s), b);
|
||||
}
|
||||
|
||||
function gg(a: number, b: number, c: number, d: number, x: number, s: number, ac: number): number {
|
||||
return addUnsigned(rotateLeft(addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac)), s), b);
|
||||
}
|
||||
|
||||
function hh(a: number, b: number, c: number, d: number, x: number, s: number, ac: number): number {
|
||||
return addUnsigned(rotateLeft(addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac)), s), b);
|
||||
}
|
||||
|
||||
function ii(a: number, b: number, c: number, d: number, x: number, s: number, ac: number): number {
|
||||
return addUnsigned(rotateLeft(addUnsigned(a, addUnsigned(addUnsigned(i(b, c, d), x), ac)), s), b);
|
||||
}
|
||||
|
||||
function convertToWordArray(bytes: Uint8Array): number[] {
|
||||
const wordCount = Math.ceil((bytes.length + 9) / 64) * 16;
|
||||
const words = new Array<number>(wordCount).fill(0);
|
||||
|
||||
for (let byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
|
||||
const wordIndex = Math.floor(byteIndex / 4);
|
||||
const bytePosition = (byteIndex % 4) * 8;
|
||||
words[wordIndex] = words[wordIndex]! | (bytes[byteIndex]! << bytePosition);
|
||||
}
|
||||
|
||||
const paddingWordIndex = Math.floor(bytes.length / 4);
|
||||
const paddingBytePosition = (bytes.length % 4) * 8;
|
||||
words[paddingWordIndex] = words[paddingWordIndex]! | (0x80 << paddingBytePosition);
|
||||
words[wordCount - 2] = bytes.length << 3;
|
||||
words[wordCount - 1] = bytes.length >>> 29;
|
||||
return words;
|
||||
}
|
||||
|
||||
function wordToHex(value: number): string {
|
||||
let hex = "";
|
||||
for (let byteIndex = 0; byteIndex < 4; byteIndex++) {
|
||||
const byte = (value >>> (byteIndex * 8)) & 0xff;
|
||||
hex += byte.toString(16).padStart(2, "0");
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算 MD5 摘要。
|
||||
*/
|
||||
export default function md5(input: string | ArrayBuffer): string {
|
||||
const bytes = typeof input === "string" ? new TextEncoder().encode(input) : new Uint8Array(input);
|
||||
const words = convertToWordArray(bytes);
|
||||
|
||||
let a = 0x67452301;
|
||||
let b = 0xefcdab89;
|
||||
let c = 0x98badcfe;
|
||||
let d = 0x10325476;
|
||||
|
||||
for (let k = 0; k < words.length; k += 16) {
|
||||
const aa = a;
|
||||
const bb = b;
|
||||
const cc = c;
|
||||
const dd = d;
|
||||
|
||||
a = ff(a, b, c, d, words[k]!, 7, 0xd76aa478);
|
||||
d = ff(d, a, b, c, words[k + 1]!, 12, 0xe8c7b756);
|
||||
c = ff(c, d, a, b, words[k + 2]!, 17, 0x242070db);
|
||||
b = ff(b, c, d, a, words[k + 3]!, 22, 0xc1bdceee);
|
||||
a = ff(a, b, c, d, words[k + 4]!, 7, 0xf57c0faf);
|
||||
d = ff(d, a, b, c, words[k + 5]!, 12, 0x4787c62a);
|
||||
c = ff(c, d, a, b, words[k + 6]!, 17, 0xa8304613);
|
||||
b = ff(b, c, d, a, words[k + 7]!, 22, 0xfd469501);
|
||||
a = ff(a, b, c, d, words[k + 8]!, 7, 0x698098d8);
|
||||
d = ff(d, a, b, c, words[k + 9]!, 12, 0x8b44f7af);
|
||||
c = ff(c, d, a, b, words[k + 10]!, 17, 0xffff5bb1);
|
||||
b = ff(b, c, d, a, words[k + 11]!, 22, 0x895cd7be);
|
||||
a = ff(a, b, c, d, words[k + 12]!, 7, 0x6b901122);
|
||||
d = ff(d, a, b, c, words[k + 13]!, 12, 0xfd987193);
|
||||
c = ff(c, d, a, b, words[k + 14]!, 17, 0xa679438e);
|
||||
b = ff(b, c, d, a, words[k + 15]!, 22, 0x49b40821);
|
||||
|
||||
a = gg(a, b, c, d, words[k + 1]!, 5, 0xf61e2562);
|
||||
d = gg(d, a, b, c, words[k + 6]!, 9, 0xc040b340);
|
||||
c = gg(c, d, a, b, words[k + 11]!, 14, 0x265e5a51);
|
||||
b = gg(b, c, d, a, words[k]!, 20, 0xe9b6c7aa);
|
||||
a = gg(a, b, c, d, words[k + 5]!, 5, 0xd62f105d);
|
||||
d = gg(d, a, b, c, words[k + 10]!, 9, 0x02441453);
|
||||
c = gg(c, d, a, b, words[k + 15]!, 14, 0xd8a1e681);
|
||||
b = gg(b, c, d, a, words[k + 4]!, 20, 0xe7d3fbc8);
|
||||
a = gg(a, b, c, d, words[k + 9]!, 5, 0x21e1cde6);
|
||||
d = gg(d, a, b, c, words[k + 14]!, 9, 0xc33707d6);
|
||||
c = gg(c, d, a, b, words[k + 3]!, 14, 0xf4d50d87);
|
||||
b = gg(b, c, d, a, words[k + 8]!, 20, 0x455a14ed);
|
||||
a = gg(a, b, c, d, words[k + 13]!, 5, 0xa9e3e905);
|
||||
d = gg(d, a, b, c, words[k + 2]!, 9, 0xfcefa3f8);
|
||||
c = gg(c, d, a, b, words[k + 7]!, 14, 0x676f02d9);
|
||||
b = gg(b, c, d, a, words[k + 12]!, 20, 0x8d2a4c8a);
|
||||
|
||||
a = hh(a, b, c, d, words[k + 5]!, 4, 0xfffa3942);
|
||||
d = hh(d, a, b, c, words[k + 8]!, 11, 0x8771f681);
|
||||
c = hh(c, d, a, b, words[k + 11]!, 16, 0x6d9d6122);
|
||||
b = hh(b, c, d, a, words[k + 14]!, 23, 0xfde5380c);
|
||||
a = hh(a, b, c, d, words[k + 1]!, 4, 0xa4beea44);
|
||||
d = hh(d, a, b, c, words[k + 4]!, 11, 0x4bdecfa9);
|
||||
c = hh(c, d, a, b, words[k + 7]!, 16, 0xf6bb4b60);
|
||||
b = hh(b, c, d, a, words[k + 10]!, 23, 0xbebfbc70);
|
||||
a = hh(a, b, c, d, words[k + 13]!, 4, 0x289b7ec6);
|
||||
d = hh(d, a, b, c, words[k]!, 11, 0xeaa127fa);
|
||||
c = hh(c, d, a, b, words[k + 3]!, 16, 0xd4ef3085);
|
||||
b = hh(b, c, d, a, words[k + 6]!, 23, 0x04881d05);
|
||||
a = hh(a, b, c, d, words[k + 9]!, 4, 0xd9d4d039);
|
||||
d = hh(d, a, b, c, words[k + 12]!, 11, 0xe6db99e5);
|
||||
c = hh(c, d, a, b, words[k + 15]!, 16, 0x1fa27cf8);
|
||||
b = hh(b, c, d, a, words[k + 2]!, 23, 0xc4ac5665);
|
||||
|
||||
a = ii(a, b, c, d, words[k]!, 6, 0xf4292244);
|
||||
d = ii(d, a, b, c, words[k + 7]!, 10, 0x432aff97);
|
||||
c = ii(c, d, a, b, words[k + 14]!, 15, 0xab9423a7);
|
||||
b = ii(b, c, d, a, words[k + 5]!, 21, 0xfc93a039);
|
||||
a = ii(a, b, c, d, words[k + 12]!, 6, 0x655b59c3);
|
||||
d = ii(d, a, b, c, words[k + 3]!, 10, 0x8f0ccc92);
|
||||
c = ii(c, d, a, b, words[k + 10]!, 15, 0xffeff47d);
|
||||
b = ii(b, c, d, a, words[k + 1]!, 21, 0x85845dd1);
|
||||
a = ii(a, b, c, d, words[k + 8]!, 6, 0x6fa87e4f);
|
||||
d = ii(d, a, b, c, words[k + 15]!, 10, 0xfe2ce6e0);
|
||||
c = ii(c, d, a, b, words[k + 6]!, 15, 0xa3014314);
|
||||
b = ii(b, c, d, a, words[k + 13]!, 21, 0x4e0811a1);
|
||||
a = ii(a, b, c, d, words[k + 4]!, 6, 0xf7537e82);
|
||||
d = ii(d, a, b, c, words[k + 11]!, 10, 0xbd3af235);
|
||||
c = ii(c, d, a, b, words[k + 2]!, 15, 0x2ad7d2bb);
|
||||
b = ii(b, c, d, a, words[k + 9]!, 21, 0xeb86d391);
|
||||
|
||||
a = addUnsigned(a, aa);
|
||||
b = addUnsigned(b, bb);
|
||||
c = addUnsigned(c, cc);
|
||||
d = addUnsigned(d, dd);
|
||||
}
|
||||
|
||||
return (wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d)).toLowerCase();
|
||||
}
|
||||
Reference in new issue
Block a user