我正在尝试使用Qt库(python中的Pyside2)将一些函数从C++传递到Python。目前,一切都可以正常工作,将代码从一侧传递到另一侧并将其适应Python,但是当我开始处理某些文件"翻译"时,我得到了不同的结果,有时甚至是错误。
我应该得到这个:
结果 1
但我得到这个:
结果 2
或者我让每个字节附加到数组chr()
得到这个:
结果 3
我是一个处理字节和字节数组的新手,所以我不知道我是否必须保存从解码算法中获得的每个结果,或者如果我必须保存字节数组中的每个字节,然后在完成后对其进行解码。如果尝试最后一个选项,我会收到"溢出"错误,而这部分没有更多上下文decryptedFile.append(currentByte ^ 0x33)
我想修复此代码以正常工作。谢谢大家!
这是C++中的原始函数:
QByteArray NosTextDatFileDecryptor::decrypt(QByteArray &array) {
QByteArray decryptedFile;
int currIndex = 0;
while (currIndex < array.size()) {
unsigned char currentByte = array.at(currIndex);
currIndex++;
if (currentByte == 0xFF) {
decryptedFile.push_back(0xD);
continue;
}
int validate = currentByte & 0x7F;
if (currentByte & 0x80) {
for (; validate > 0; validate -= 2) {
if (currIndex >= array.size())
break;
currentByte = array.at(currIndex);
currIndex++;
int firstByte = cryptoArray.at((currentByte & 0xF0) >> 4);
decryptedFile.push_back(firstByte);
if (validate <= 1)
break;
int secondByte = cryptoArray.at(currentByte & 0xF);
if (!secondByte)
break;
decryptedFile.push_back(secondByte);
}
} else {
for (; validate > 0; --validate) {
if (currIndex >= array.size())
break;
currentByte = array.at(currIndex);
currIndex++;
decryptedFile.push_back(currentByte ^ 0x33);
}
}
}
return decryptedFile;
}
这是我为该项目的Python版本编写的代码:
from PySide2.QtCore import QByteArray
def dat_file_decryptor(array):
decryptedFile = QByteArray()
currIndex = 0
while currIndex < array.size():
currentByte = ord(array[currIndex]) #unsigned char
currIndex += 1
if currentByte == 0xFF:
decryptedFile.append(0xD)
#pass
validate = currentByte & 0x7F
if currentByte & 0x80:
while validate > 0:
if currIndex >= array.size():
break
currentByte = ord(array[currIndex])
currIndex += 1
firstByte = cryptoArray[(currentByte & 0xF0) >> 4]
decryptedFile.append(firstByte)
if validate <= 1:
break
secondByte = cryptoArray[currentByte & 0xF]
if not secondByte:
break
decryptedFile.append(secondByte)
validate -= 2
else:
while validate > 0:
if currIndex >= array.size():
break
currentByte = ord(array[currIndex])
currIndex +=1
decryptedFile.append(chr(currentByte ^ 0x33)) #If I don't use chr() here I get an OverFlow error
validate -= 1
return decryptedFile
如果您想自己尝试,以下是您需要的数据:
array = b'nx10x13rPGx13wRGRxff$x10x0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0exffx04wRGRx8
9x15x15x15x15@xffx04wRGRx88x16x15x16x1axffx04wRGRx88x17x15x17x1cxffx04wRGRx89x18x15x18x15@xffx04wRGRx88x19x15x19x1axffx04wRGRx88x1ax15x1ax1axffx04
wRGRx88x1bx16x15x17xffx04wRGRx88x1cx16x16x16xffx04wRGRx88x1dx16x17x17xffx04wRGRx89x15Aax81pxffx04wRGRx89x15Qax91Pxffx04wRGRx89x15aaxa1Pxffx04wRGRx89x
15qqQ`xffx04wRGRx89x15x81qapxffx04wRGRx89x15x91qq`xffx04wRGRx89x15xa1qx81pxffx04wRGRx89x15xb1qx91pxffx04wRGRx89x15xc1qxa1`xffx04wRGRx89x15xd1x81QPxffx0
4wRGRx89x16Ax91Q`xffx04wRGRx89x16Qxa1QPxffx04wRGRx8ax16axb1QTxffx04wRGRx89x16qxb1ax90xffx03V]Wxff$x10x0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0
ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex10xffx07x10x13gZG_Vxfftr:x02:IG@x02Vxfftr:x01:IG@x01Vxfftr:x00:IG@x00Vxfftr:x07:IG@x07Vxff
tr:x06:IG@x06Vxffx07r:x05:IG@x84vxd4x01Vxffx07r:x04:IG@x84vxd5x01Vxffx01Mxff'
似乎问题在于您错过了将C++continue
语句转换为 Python。
替换注释掉的行
#pass
跟
continue
因为 Python 也有一个continue
语句,你的代码应该可以工作。
在循环中,continue
语句会导致循环的当前迭代的其余部分结束,并且执行从下一次迭代恢复。
代码似乎正在对传入的数据进行某种解压缩/解码,它可以在两种模式下运行:
- "异或"模式,其中输入中的字符在附加到输出之前先用
0x33
进行异或处理, - "解压缩"模式,从
cryptoArray
中读取字符,假定包含 16 个常规出现的字符。每个字节的前四位和后四位是对应于要输出的字符的cryptoArray
索引。
解码首先通过读取一个字节进行,该字节告诉它使用哪种模式以及在该模式下读取多少字节。 此字节的顶部位明确使用 XOR 模式并设置为使用解压缩模式,其余 7 位给出在该模式下要读取的字节数。 特殊字符xff
指示应改为输出换行符。
您的源数据以nx10x13rPGx13wRGR
开头,这表示在 XOR 模式下读取 10 个字节(n
是字符 10)。 将 10 个字节x10x13rPGx13wRGR
与0x33
进行 XOR 运算会得到文本# Act Data
。
稍后在数据中,有序列x89x15x15x15x15@
. 这表示在解压缩模式下读取 9 个字符,索引 1、5、1、5、1、5 和 4 在cryptoArray
中。 (@
是字符x40
。 这对应于输出中的1 1 1 10
,因此我们可以由此推断出cryptoArray
索引 1、5 和 4 处的字符分别是空格、1
和0
。
您没有在问题中指定cryptoArray
的内容,但以下内容似乎为我提供了正确的输出:
# 0123456789abcdef
cryptoArray = QByteArray(b'X XX0123456789XX')
X
表示在此特定转换中未使用的字节,因此我无法说出它们在您的代码中是什么。
那么为什么你的代码生成了不正确的输出呢? 缺少的continue
语句在处理xff
字节时,指示输出换行符。 如果没有continue
语句,代码将输出换行符,然后错误地尝试在解压缩模式下从接下来的 64 个字节的数据中解码 127 个字符。
无论如何,您的函数dat_file_decryptor
返回一个QByteArray
。 我将其分配给一个变量result
,并且可以通过运行以下行从源数据中获得所需的输出:
print(bytes(result).decode("ascii").replace("r", "n"))
免责声明:我没有在 PySide 中测试过这个,只有 PyQt5。 我不知道这是否有区别。