Last active
November 13, 2018 12:32
-
-
Save randphu/5277346 to your computer and use it in GitHub Desktop.
extract buka manga archive (*.buka)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
''' | |
Layout of buka manga archives | |
Whole archive | |
| b"buka" | unknown (16 bytes) | manga title (c string) | entry table | file 1 | file 2 | ... | |
Entry table | |
| table size (uint32) | entry 1 | entry 2 | ... | | |
Entry | |
| offset (uint32) | size (uint32) | name (c string) | | |
Note | |
c string: null terminated, encoded in utf8. | |
unit32: 32 bit, unsigned, little endian. | |
table size contains the size of itself. | |
''' | |
import sys, os, struct | |
def readuint32(src): | |
buf = src.read(4) | |
return struct.unpack('<I', buf)[0] | |
def readcstring(src): | |
buf = b"" | |
while True: | |
ch = src.read(1) | |
if ch[0] == 0: | |
return buf.decode('utf8'), len(buf) + 1 | |
buf += ch | |
def readtable(src): | |
table = [] | |
tsize = readuint32(src) | |
total = 4 | |
while total < tsize: | |
offset = readuint32(src) | |
size = readuint32(src) | |
name, n = readcstring(src) | |
if name not in ["index2.dat", "chaporder.dat", "logo"]: | |
table.append((offset, size, name)) | |
total += n + 8 | |
return table | |
def copysection(dst, src, offset, size): | |
src.seek(offset) | |
dst.write(src.read(size)) | |
def fmtsize(size): | |
for i in "kmgt": | |
size /= 1024 | |
if size < 1024: | |
return "%.2f"%size + i | |
def extract(srcfile): | |
dstdir = os.path.join(os.path.dirname(srcfile), os.path.splitext(os.path.basename(srcfile))[0]) | |
if not os.path.exists(dstdir): | |
os.mkdir(dstdir) | |
with open(srcfile, 'rb') as src: | |
if src.read(4) != b'buka': | |
print("%s: not a buka manga archive" % srcfile) | |
return | |
src.seek(20) | |
title, _ = readcstring(src) | |
table = readtable(src) | |
print("extract %s (%s) to %s/" % (srcfile, title, dstdir)) | |
for offset, size, name in table: | |
dstfile = os.path.join(dstdir, name) | |
with open(dstfile, 'wb') as dst: | |
copysection(dst, src, offset, size) | |
print(" %s (%s)" % (name, fmtsize(size))) | |
for srcfile in sys.argv[1:]: | |
extract(srcfile) |
@jackie840301
这个脚本用了python3.x的特性,2.x是没法正确执行的
如果确保以上没错,再把出错信息、系统、漫画具体话数贴出来
Linux下测试结果,有你的小镇200-226话是可以解的
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
目前發現有完全不能解的文件(有你的小鎮)
更改副檔名為壓縮檔解壓縮失敗,
使用鏈接http://ppt.cc/Q_1t 内的軟体可以解,
但是檔案順序會跑掉,請問是哪裏發生了問題呢?
謝謝!