Skip to content

如何使用及示例

nukemiko edited this page Feb 10, 2023 · 3 revisions

概述

当你 import libtakiyasha 时,libtakiyasha 下有四个子模块 ncmqmckgmvprkwm 会被自动导入。这些子模块下各有一个加密文件对象类(qmc 除外,有两个),和一个 probe 开头的探测函数(qmc 除外,有三个),用于确认目标文件是否被该模块支持:

模块 加密文件对象类 探测函数
libtakiyasha.ncm NCM probe_ncm()
libtakiyasha.qmc QMCv1QMCv2 probe_qmc()probe_qmcv1()probe_qmcv2()
libtakiyasha.kgmvpr KGMorVPR probe_kgmvpr()
libtakiyasha.kwm KWM probe_kwm()

每个探测函数都会返回一个内含两个元素的元组:

  • 第一个元素为文件路径或文件对象,取决于探测函数收到的参数;
  • 在探测到受支持的文件时,第二个元素为文件的信息,否则为 None

打开加密文件的一般步骤:在上表找到加密文件格式对应的加密文件对象类,通过它的 open() 方法打开加密文件。你必须提供正确的关键字参数才能正常打开和操作文件;查看 LibTakiyasha 支持的格式以及所需的参数以了解你需要哪些参数才能打开文件。

每一个加密文件对象都可以按照普通文件对象对待(拥有 read()write()seek() 等方法),也拥有一个 save() 方法,以便将该加密文件对象保存到文件。

每个加密文件对象都实现了上下文管理器协议,因此可以使用 with 语句打开加密文件。

使用示例(NCM 和 QMCv2)

  • 本示例是在 Linux 环境下撰写的,下文的所有 PosixPath 在 Windows 平台上都应当是 WindowsPath
  • 打开和保存文件需要特定的参数,每种加密文件格式对应的加密文件对象,所需的参数都不同。查看打开每种加密文件所需的参数
  • 不仅要知其然,还要知其所以然。如果你想搞清楚以下示例中每一步的原因,勤看代码内置的文档。
    • 终端 REPL 界面下:对你想了解的函数/方法/类使用 help()
    • IDE 和某些高级文本编辑器(例如 PyCharm、Visual Studio Code)中:将鼠标移动到你想了解的函数/方法/类的签名上方,停留几秒钟,一般就能看到内置文档。

初始化

>>> import libtakiyasha
>>>
>>> NCM_CORE_KEY = b'YourNCMCoreKey'
>>> NCM_TAG_KEY = b'YourNCMTagKey'
>>> QMCV2_CORE_KEY = b'YourQMCv2CoreKey'
>>> QMCV2_KEYENCV2_GARBLE_KEYS = [b'YourQMCv2GarbleKey1', b'YourQMCv2GarbleKey2', b'YourQMCv2GarbleKey3']
>>>

探测加密文件的信息

>>> ncmfilething, ncmfileinfo = libtakiyasha.ncm.probe_ncm('source.ncm')
>>> ncmfilething
PosixPath('source.ncm')
>>> ncmfileinfo
NCMFileInfo(master_key_encrypted=..., ncm_163key=b"163 k
ey(Don't modify):...", cipher_ctor=<class 'libtakiyasha.stdciphers.ARC4'>, cipher_data_offset=187794, cipher_data_len=41025769, cover_data_offset=817, cover_data_len=186977, opener=<bound method NCM.open of <class 'libtakiyasha.ncm.NCM'>>, opener_kwargs_required=('core_key',), opener_kwargs_optional=('tag_key', 'master_key'))
>>> qmcv2filething, qmcv2fileinfo = libtakiyasha.qmc.probe_qmc('source.mflac')
>>> qmcv2filething
PosixPath('source.mflac')
>>> qmcv2fileinfo
QMCv2FileInfo(cipher_ctor=<bound method Mask128.from_qmcv2_key256 of <class 'libtakiyasha.qmc.qmcdataciphers.Mask128'>>, cipher_data_offset=0, cipher_data_len=37444388, master_key_encrypted=..., master_key_encryption_ver=2, extra_info=None, opener=<bound method QMCv2.open of <class 'libtakiyasha.qmc.QMCv2'>>, opener_kwargs_required=('core_key', 'garble_keys'), opener_kwargs_optional=('master_key',))
>>>

根据上一环节得到的信息,打开一个加密文件

>>> ncmfile = libtakiyasha.ncm.NCM.open('source.ncm', core_key=NCM_CORE_KEY, tag_key=NCM_TAG_KEY)
>>> ncmfile
<libtakiyasha.ncm.NCM at 0x74316d537d80, cipher <libtakiyasha.stdciphers.ARC4 object at 0x74316d693010>, source 'source.ncm'>
>>>
>>> # 上一环节中,qmcv2fileinfo.master_key_encryption_ver == 2,
>>> # 意味着下面打开文件时需要关键字参数 `garble_keys`
>>> qmcv2file = libtakiyasha.qmc.QMCv2.open('source.mflac', core_key=QMCV2_CORE_KEY, garble_keys=QMCV2_KEYENCV2_GARBLE_KEYS)
>>> qmcv2file
<libtakiyasha.qmc.QMCv2 at 0x74316d4a1d00, cipher <libtakiyasha.qmc.qmcdataciphers.Mask128 object at 0x74316d6df790>, source 'source.mflac'>
>>>

每个加密文件对象都实现了上下文管理器协议,因此也可以使用 with 语句打开加密文件:

>>> with libtakiyasha.qmc.QMCv2.open('source.mflac', core_key=QMCV2_CORE_KEY, garble_keys=QMCV2_KEYENCV2_GARBLE_KEYS) as qmcv2file:
...     ...
...
>>>

导出加密文件中的数据

>>> # NCM
>>> ncmfile.seek(0, 0)
0
>>> targetfile_path = ncmfile.source.parent.with_name('target_from_ncm.' + ncmfile.ncm_tag.format)
>>> with open(targetfile_path, mode='wb') as targetfile:
...     for blk in ncmfile:
...         targetfile.write(blk)  # 对每个加密文件对象进行迭代都会产生固定大小的数据;修改 ITER_METHOD 属性的值为 `line` 以使其按行迭代
...
>>>
>>> # QMCv2
>>> qmcv2file.seek(0, 0)
>>> if qmcv2file.source.suffix.lower.startswith('.mflac'):
...     targetfile_path_suffix = '.flac'
... elif qmcv2file.source.suffix.lower.startswith('.mgg'):
...     targetfile_path_suffix = '.ogg'
... else:
...     targetfile_path_suffix = '.qmcv2_decrypted'
>>> targetfile_path = qmcv2file.soource.parent.with_name('target_from_qmcv2' + targetfile_path_suffix)
>>> with open(targetfile_path, mode='wb') as targetfile:
...     for blk in qmcv2file:
...         targetfile.write(blk)
...
>>>

修改和保存加密文件

敬请期待

新建加密文件

敬请期待