diff --git a/package.json b/package.json index 4fe5021..f38a486 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "fix-compatibility": "node ./src/fix-compatibility.js" }, "dependencies": { + "base64-js": "^1.3.1", "browser-id3-writer": "^4.4.0", "core-js": "^3.6.4", "crypto-js": "^4.0.0", diff --git a/src/decrypt/qmc.js b/src/decrypt/qmc.js index 9490d55..c68d711 100644 --- a/src/decrypt/qmc.js +++ b/src/decrypt/qmc.js @@ -1,7 +1,8 @@ import {AudioMimeType, DetectAudioExt, GetArrayBuffer, GetFileInfo, GetMetaCoverURL, RequestJsonp} from "./util"; import {QmcMaskCreate58, QmcMaskDetectMflac, QmcMaskDetectMgg, QmcMaskGetDefault} from "./qmcMask"; -import {decode} from "iconv-lite" + +import {fromByteArray as Base64Encode, toByteArray as Base64Decode} from 'base64-js' const musicMetadata = require("music-metadata-browser"); @@ -25,9 +26,11 @@ export async function Decrypt(file, raw_filename, raw_ext) { const fileData = new Uint8Array(await GetArrayBuffer(file)); let audioData, seed, keyData; if (handler.detect) { - audioData = fileData.slice(0, -0x170); + const keyLen = new DataView(fileData.slice(fileData.length - 4).buffer).getUint32(0, true) + const keyPos = fileData.length - 4 - keyLen; + audioData = fileData.slice(0, keyPos); seed = handler.handler(audioData); - keyData = fileData.slice(-0x170); + keyData = fileData.slice(keyPos, keyPos + keyLen); if (seed === undefined) seed = await queryKeyInfo(keyData, raw_filename, raw_ext); if (seed === undefined) return {status: false, message: raw_ext + "格式仅提供实验性支持"}; } else { @@ -76,7 +79,7 @@ function reportKeyUsage(keyData, maskData, artist, title, album, filename, forma method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({ - Mask: Array.from(maskData), Key: Array.from(keyData), + Mask: Base64Encode(new Uint8Array(maskData)), Key: Base64Encode(keyData), Artist: artist, Title: title, Album: album, Filename: filename, Format: format }), }).then().catch() @@ -87,10 +90,10 @@ async function queryKeyInfo(keyData, filename, format) { const resp = await fetch("https://stats.ixarea.com/collect/qmcmask/query", { method: "POST", headers: {"Content-Type": "application/json"}, - body: JSON.stringify({Format: format, Key: Array.from(keyData), Filename: filename}), + body: JSON.stringify({Format: format, Key: Base64Encode(keyData), Filename: filename, Type: 44}), }); let data = await resp.json(); - return QmcMaskCreate58(data.Matrix58, data.Super58A, data.Super58B); + return QmcMaskCreate58(Base64Decode(data.Matrix44)); } catch (e) { console.log(e); }