|
|
@ -1,5 +1,6 @@ |
|
|
|
import QMCCryptoModule from '@jixun/qmc2-crypto/QMC2-wasm-bundle'; |
|
|
|
import { MergeUint8Array } from '@/utils/MergeUint8Array'; |
|
|
|
import { QMCCrypto } from '@jixun/qmc2-crypto/QMCCrypto'; |
|
|
|
|
|
|
|
// 检测文件末端使用的缓冲区大小
|
|
|
|
const DETECTION_SIZE = 40; |
|
|
@ -7,14 +8,22 @@ const DETECTION_SIZE = 40; |
|
|
|
// 每次处理 2M 的数据
|
|
|
|
const DECRYPTION_BUF_SIZE = 2 * 1024 * 1024; |
|
|
|
|
|
|
|
export interface QMC2DecryptionResult { |
|
|
|
success: boolean; |
|
|
|
data: Uint8Array; |
|
|
|
songId: string | number; |
|
|
|
error: string; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 解密一个 QMC2 加密的文件。 |
|
|
|
* |
|
|
|
* 如果检测并解密成功,返回解密后的 Uint8Array 数据。 |
|
|
|
* @param {ArrayBuffer} mggBlob 读入的文件 Blob |
|
|
|
* @return {Promise<Uint8Array|false>} |
|
|
|
*/ |
|
|
|
export async function DecryptQMCWasm(mggBlob: ArrayBuffer) { |
|
|
|
export async function DecryptQMCWasm(mggBlob: ArrayBuffer): Promise<QMC2DecryptionResult> { |
|
|
|
const result: QMC2DecryptionResult = { success: false, data: new Uint8Array(), songId: 0, error: '' }; |
|
|
|
|
|
|
|
// 初始化模组
|
|
|
|
const QMCCrypto = await QMCCryptoModule(); |
|
|
|
|
|
|
@ -34,12 +43,26 @@ export async function DecryptQMCWasm(mggBlob: ArrayBuffer) { |
|
|
|
const position = QMCCrypto.getValue(pDetectionResult, 'i32'); |
|
|
|
const len = QMCCrypto.getValue(pDetectionResult + 4, 'i32'); |
|
|
|
|
|
|
|
result.success = detectOK; |
|
|
|
result.error = QMCCrypto.UTF8ToString( |
|
|
|
pDetectionResult + QMCCrypto.offsetof_error_msg(), |
|
|
|
QMCCrypto.sizeof_error_msg(), |
|
|
|
); |
|
|
|
const songId = QMCCrypto.UTF8ToString(pDetectionResult + QMCCrypto.offsetof_song_id(), QMCCrypto.sizeof_song_id()); |
|
|
|
if (!songId) { |
|
|
|
console.debug('qmc2-wasm: songId not found'); |
|
|
|
} else if (/^\d+$/.test(songId)) { |
|
|
|
result.songId = songId; |
|
|
|
} else { |
|
|
|
console.warn('qmc2-wasm: Invalid songId: %s', songId); |
|
|
|
} |
|
|
|
|
|
|
|
// 释放内存
|
|
|
|
QMCCrypto._free(pDetectionBuf); |
|
|
|
QMCCrypto._free(pDetectionResult); |
|
|
|
|
|
|
|
if (!detectOK) { |
|
|
|
return false; |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
// 计算解密后文件的大小。
|
|
|
@ -75,5 +98,7 @@ export async function DecryptQMCWasm(mggBlob: ArrayBuffer) { |
|
|
|
QMCCrypto._free(buf); |
|
|
|
hCrypto.delete(); |
|
|
|
|
|
|
|
return MergeUint8Array(decryptedParts); |
|
|
|
result.data = MergeUint8Array(decryptedParts); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|