Java 从反向工程lua文件解码Ascii字符串值

Java 从反向工程lua文件解码Ascii字符串值,java,python,decoding,Java,Python,Decoding,我用unluac反编译了一个lua文件,结果发现所有的字符串变量都不可读,而是ascii编码的 clues = { { answer = { "\216\173", "\216\177", "\216\168", "\216\167", "\216\161" }, text = "\216\173\217\138\217\136\216\167\217\134\032\216\178\216\167\216\

我用unluac反编译了一个lua文件,结果发现所有的字符串变量都不可读,而是
ascii编码的

clues = {
  {
    answer = {
      "\216\173",
      "\216\177",
      "\216\168",
      "\216\167",
      "\216\161"
    },
    text = "\216\173\217\138\217\136\216\167\217\134\032\216\178\216\167\216\173\217\129\032\217\138\216\186\217\138\216\177\032\217\132\217\136\217\134\032\216\172\217\132\216\175\217\135",
    syllables = {
      {"\216\173", "\216\177"},
      {"\216\168", "\216\167"},
      {"\216\161"}
    }
如何在python或java中解码整个文件,忽略任何非ascii字符

import re

data = '\\216\\173\\217\\138\\217\\136\\216\\167\\217\\134\\032\\216\\178\\216\\167\\216\\173\\217\\129\\032\\217\\138\\216\\186\\217\\138\\216\\177\\032\\217\\132\\217\\136\\217\\134\\032\\216\\172\\217\\132\\216\\175\\217\\135'
decoded_data = re.sub('\\\\(\d{1,3})', lambda x: chr(int(x.group(1))), data).decode('utf-8')

print(repr(decoded_data))
您有UTF-8编码的数据,不是ASCII,每个字节都使用十进制数编码为三位转义序列。实际文本主要由阿拉伯语书写

您需要用相应的字节值替换每个
\ddd
序列,然后解码为UTF-8。在Python 3中:

utf8_data = bytes([int(data[i + 1:i + 4]) for i in range(0, len(data), 4)])
print(utf8_data.decode('utf8'))
演示:

谷歌翻译告诉我这是一种用英语改变皮肤颜色的令人毛骨悚然的动物

否则,我们可以使用基于堆栈的解析器将Lua语法转换为JSON:

import re
import json

def lua_to_python(lua_data):
    return json.loads(''.join(_convert_lua_to_json_chunks(lua_data)))

def _lua_bytes_to_text(data):
    return bytes(
        [int(data[i + 1:i + 4]) for i in range(0, len(data), 4)]
    ).decode('utf8')

def _convert_lua_to_json_chunks(lua_data):
    tokens = re.split(br'(["{},])', lua_data)
    stack = []
    pos_tokens = enumerate(tokens)
    for pos, token in pos_tokens:
        if b'=' in token:
            if not stack:
                # top-level key-value, produce JSON object syntax
                stack.append('}')
                yield '{'
            yield '"{}":'.format(token.strip().rstrip(b' =').decode('utf8'))
        elif token == b'{':
            # array or object?
            next_nonws = next(t for t in tokens[pos + 1:] if t.strip())
            if b'=' in next_nonws:
                stack.append('}')
                yield '{'
            else:
                stack.append(']')
                yield '['
        elif token == b'}':
            yield stack.pop()
        elif token == b'"':
            yield '"'
            for pos, s in pos_tokens:
                if s == b'"':
                    yield '"'
                    break
                yield _lua_bytes_to_text(s)
        else:
            yield token.decode('utf8')
    yield from stack
在末尾添加两个
}
字符后,您的数据将生成:

>>> lua_to_python(lua_data)
{'clues': [{'answer': ['ح', 'ر', 'ب', 'ا', 'ء'], 'text': 'حيوان زاحف يغير لون جلده', 'syllables': [['ح', 'ر'], ['ب', 'ا'], ['ء']]}]}
>>> pprint(lua_to_python(lua_data))
{'clues': [{'answer': ['ح', 'ر', 'ب', 'ا', 'ء'],
            'syllables': [['ح', 'ر'], ['ب', 'ا'], ['ء']],
            'text': 'حيوان زاحف يغير لون جلده'}]}

这将为您提供大量选项来进一步处理数据。

可能会在每个斜杠上拆分字符串,然后将单个数字字符串转换为整数,然后再转换为字符。此时,您可以检查该值是否低于127,以过滤非ascii字符。@jawnythonpson:wow,该页面的名称太错误了。它们不是在解码ASCII码。他们正在解码二进制数据。页面恰好使用UTF-8作为编码,这就是它工作的原因。UTF-8是ASCII的超集(ASCII的编码方式以及前128个Unicode编码点编码为UTF-8的方式恰好产生相同的二进制数据)。@Jawnythonpson:下面的代码接受二进制数据;如果
unluac
生成一个字符串对象(
type(obj)
打印
),则需要首先使用
obj.encode('ascii')
将其编码为字节。如果
unluac
已经生成了一个
bytes
对象,您就可以开始了@Jawnythonpson:如果我误解了
unluac
生成的文件,请使用
open(filename,'rb')
以Python二进制文件的形式打开该文件,然后读取数据并将其传递给我编写的函数。@Jawnythonpson:您确实需要使用能够处理阿拉伯语的编解码器打开输出文件。例如,使用
open(filename'w',encoding='utf8')
。起初我是这样想的,但我在问题中找到了
\168
。由于
8
不能是八进制数,我认为这些是十进制数。是的,我在发表评论时就知道我在计算中遗漏了一个数字,并且刚刚发现了这一点。在这一点上,这看起来像是乱七八糟的输出(如果我们假定
text='..'
保存的是实际的文本,而不是二进制数据)。此代码段应在python 2中运行。我用
data='\\216\\173\\217\\138\\217\\136\\216\\167\\217\\134\\032\\216\\178\\216\\216\\173\\217\\129\\032\\217\\138\\216\\186\\217\\138\\216\\177\\032\\217\\132\\217\\136\\217\\032\\216\\172\\217\\132\\216\\175\\217\\135'
(这是问题中的
文本的符号字符串)输出是
。在这种情况下,它将取决于您的控制台编码,因为您正在向控制台或终端打印原始字节。
>>> lua_to_python(lua_data)
{'clues': [{'answer': ['ح', 'ر', 'ب', 'ا', 'ء'], 'text': 'حيوان زاحف يغير لون جلده', 'syllables': [['ح', 'ر'], ['ب', 'ا'], ['ء']]}]}
>>> pprint(lua_to_python(lua_data))
{'clues': [{'answer': ['ح', 'ر', 'ب', 'ا', 'ء'],
            'syllables': [['ح', 'ر'], ['ب', 'ا'], ['ء']],
            'text': 'حيوان زاحف يغير لون جلده'}]}