优化: KGM解密并行化,多线程处理block,提升服务器卡顿时转码速度
This commit is contained in:
+15
-4
@@ -9,6 +9,7 @@ from mutagen.flac import FLAC
|
||||
from mutagen.oggvorbis import OggVorbis
|
||||
from mutagen.id3 import ID3, TIT2, TPE1, TALB, APIC
|
||||
from pydub import AudioSegment
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
NCM_MAGIC = b"CTENFDAM"
|
||||
CORE_KEY = b"hzHRAmso5kInbaxW"
|
||||
@@ -262,16 +263,26 @@ class KgmDecoder:
|
||||
pub_len = len(self.pub_key)
|
||||
out = bytearray(len(audio))
|
||||
block_count = (len(audio) + BLOCK - 1) // BLOCK
|
||||
for block_idx in range(block_count):
|
||||
if block_idx >= pub_len:
|
||||
if block_count > pub_len:
|
||||
raise ValueError("Key file mismatch")
|
||||
# Pre-compute all 17 phase tables; workers only read from cache
|
||||
for phase in range(17):
|
||||
self._phase_tables(phase, own_key, self.pub_key)
|
||||
# Parallel block decryption: each block is independent
|
||||
def _decrypt_block(block_idx):
|
||||
phase = block_idx % 17
|
||||
tables = self._phase_tables(phase, own_key, self.pub_key)
|
||||
pub_value = self.pub_key[block_idx]
|
||||
start = block_idx * BLOCK
|
||||
end = min(start + BLOCK, len(audio))
|
||||
for col, offset in enumerate(range(start, end)):
|
||||
out[offset] = tables[col][pub_value][audio[offset]]
|
||||
blk = bytearray(end - start)
|
||||
for col in range(end - start):
|
||||
blk[col] = tables[col][pub_value][audio[start + col]]
|
||||
return start, bytes(blk)
|
||||
max_workers = min(16, max(1, block_count))
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
for start, blk in executor.map(_decrypt_block, range(block_count)):
|
||||
out[start:start + len(blk)] = blk
|
||||
payload = bytes(out)
|
||||
container = _sniff_container(payload[:64])
|
||||
return payload, container, {}, None
|
||||
|
||||
Reference in New Issue
Block a user