解压缩python gbf文件的值太多

时间:2018-01-12 17:29:42

标签: python

你好我运行我的脚本

时得到python错误太多值来解压python

追溯:

File "C:\Python27.1\perpetuum.py", line 193, in __init__
    header_offset, header_length = struct.unpack('8sii', f.read(16))
ValueError: too many values to unpack.

代码:

class DataFile(object):
    """GBF file reader"""

    def __init__(self, filename):
        self.filename = filename

        with open(filename, 'rb') as f:
            header_offset, header_length = struct.unpack('8sii', f.read(16))
            if magic != 'GXYDATA\x1a':
                raise Exception('Invalid data file (wrong magic)', magic)

        header = self._get_record(header_offset, header_length)
        self._records = self._parse_header(header)

    def _decode(self, data):
        try:
            import numpy as np

            i = np.arange(len(data), dtype=np.byte)
            buf = np.frombuffer(data, np.byte) ^ ((i + 1) * (i ^ -54) - 84)
            return buf.tostring()
        except ImportError:
            buf = array.array('B', data)
            for i in xrange(len(data)):
                buf[i] = 0xff & (buf[i] ^ ((i + 1) * (i ^ 0xca) - 84))
            return buf.tostring()

    def _get_record(self, offset, length):
        with open(self.filename, 'rb') as f:
            f.seek(offset)
            data = f.read(length)
        return self._decode(data)

    def _parse_header(self, header):
        """
        header record format:
            int numRecords
            for each record:
                char[nameLen] nameSZ, 0
                int offset
                int length
                int unkLength
        """

        records = {}
        num_records = struct.unpack_from('i', header)[0]
        pos = 4
        for i in xrange(num_records):
            name_end = header.find('\0', pos)
            name = header[pos:name_end]
            pos = name_end + 1
            offset, length, unkLength = struct.unpack_from('iii', header, pos)
            pos += 12
            # f1Length = min(13, unkLength)
            # f1 = header[pos:pos+f1Length]
            pos += unkLength
            records[name] = (offset, length)
        return records

    PREFIX_MAP = {'\x89PNG': '.png',
                  'DDS ': '.dds',
                  'A3MF': '.a3m',
                  '#': '.txt',
                  '=': '.txt',
                  'Extended Module': '.xm',
                  'RIFF': '.wav',
                  'OggS': '.ogg'}

    def _guess_ext(self, name, data):
        for prefix, ext in self.PREFIX_MAP.iteritems():
            if data.startswith(prefix):
                return ext
        return '.bin'

    CATEGORY_MAP = OrderedDict([
        ('def*.png', 'icons'),
        ('icon*.png', 'icons'),
        ('entityIcon*.png', 'icons'),
        ('noIcon*.png', 'icons'),
        ('gfx_*.png', 'gfx'),
        ('*.a3m', 'models'),
        ('snd_*', 'sound'),
        ('altitude*', 'terrain'),
        ('terrain*', 'terrain'),
        ('altitude0*', 'terrain'),
        ('blocks0*', 'terrain'),
        ('control0*', 'terrain'),
        ('plants0*', 'terrain'),
        ('surface0*', 'terrain'),
        ('tactical*.png', 'tactical_icons'),
        ('font*', 'font'),
        ('textures_*.dds', 'textures'),
        ('corp*.png', 'corp_icons'),
        ('credits.txt', 'misc'),
        ('eula*.txt', 'misc'),
        ('*.txt', 'text_data')])

    def dump_record(self, name, dest_dir, sort=False):
        offset, length = self._records[name]
        print '%08x: %s (%.2f KB)' % (offset, name, length / 1024.)

        data = self._get_record(offset, length)
        name += self._guess_ext(name, data)

        if sort:
            for pattern, category in self.CATEGORY_MAP.iteritems():
                if fnmatch.fnmatch(name, pattern):
                    dest_dir = os.path.join(dest_dir, category)
                    try:
                        os.makedirs(dest_dir)
                    except OSError:
                        pass
                    break

        rec_filename = os.path.join(dest_dir, name)
        with open(rec_filename, 'wb') as f:
            f.write(data)

    def dump_records(self, patterns, dest_dir, sort=False):
        for name in self._records:
            if any(fnmatch.fnmatch(name, pattern) for pattern in patterns):
                self.dump_record(name, dest_dir, sort)

任何想法?

4 个答案:

答案 0 :(得分:0)

代码

struct

解压缩成三个值 - 一个8字节的字符串,以及两个整数,每个整数的长度为4个字节,而你的LHS只有两个变量。

请参阅<html> <head> <title>Facebook Likes</title> <meta http-equiv="Cache-Control" content="no-store" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script> <script src="https://connectors.tableau.com/libs/tableauwdc-2.3.latest.js" type="text/javascript"></script> <script src="FacebookLikes.js" type="text/javascript"></script> </head> <body> <div class="container container-table"> <div class="row vertical-center-row"> <div class="text-center col-md-4 col-md-offset-4"> <button type = "button" id = "submitButton" class = "btn btn-success" style = "margin: 10px;">Get Facebook Likes!</button> </div> </div> </div> </body> </html> 文档,了解其格式字符串。

答案 1 :(得分:0)

这一行做出了错误的假设:

header_offset, header_length = struct.unpack('8sii', f.read(16))

最好检查从struct.unpack返回的元组的大小,然后以条件方式处理结果。

请注意,根据docs,此方法始终返回一个元组,即使该元组的长度为1。

答案 2 :(得分:0)

愚蠢我删除标题偏移之前的魔术。

答案 3 :(得分:0)

drhagen愚蠢的人取-1并且根本没有答案在photoshop获得我的技能,我可以随时笑你