【发布时间】:2020-02-15 20:31:43
【问题描述】:
我必须编写一个程序来解码文件(使用 CP437 编码),方法是根据 CP437 表替换每个符号的 Unicode,然后将其转换为 UTF-8 并将输出打印到文件中。
我有两个文件 - 一个输入文件包含一个长文本,其中包含普通字符和一些奇怪的字符(在结果文件中,这些奇怪的字符将被各种破折号替换),以及一个包含 256 行对的 CP437 文件(第一部分是十进制数,第二部分是Unicode,例如73 0049)。
这就是我试图解决这个问题的方法:
- 使用“RB”标志打开输入文件
- 由于我使用“RB”打开文件,我将每个符号读取为字节,然后将其存储在“文本”列表中
- 读完文件后,循环浏览文本列表
- 在循环过程中,我得到了符号的十进制值
- 我使用十进制值从 CP437.txt 文件中获取 Unicode
- 我将 Unicode 转换为 0 和 1
- 我将 Unicode 的二进制表示形式转换为 UTF-8 和 返回 0 和 1
- 我将那些 UTF-8 0 和 1 转换为字节并将它们写入 使用“WB”标志打开的结果文件
另外,如果 UTF-8 0 和 1 的长度超过 8 个,那么我将每 8 个字符拆分一次,然后将它们转换为字节(我不确定这是否正确)
主要问题是当我尝试编写结果时,我得到了很多乱码,我不确定问题出在哪里。感谢您提供任何帮助,我已经被这个任务困住了一段时间,只是无法弄清楚问题出在哪里。
def convertBinToHex(binary):
binToHex = hex(int(binary, 2))
temp = list(binToHex)
temp = temp[2:]
binToHex = "".join(temp).upper()
return binToHex
def convertUnicodeToUTF(unicodeBin, symbolDecimal, returnBin):
# https://stackoverflow.com/questions/6240055/manually-converting-unicode-codepoints-into-utf-8-and-utf-16
bytesCount = 0
if int("0000", 16) <= symbolDecimal <= int("007F", 16):
if returnBin:
return unicodeBin
return convertBinToHex(unicodeBin)
elif int("0080", 16) <= symbolDecimal <= int("07FF", 16):
bytesCount = 2
elif int("0800", 16) <= symbolDecimal <= int("FFFF", 16):
bytesCount = 3
elif int("10000", 16) <= symbolDecimal <= int("10FFFF", 16):
bytesCount = 4
else:
return
if bytesCount == 2:
template = ['1', '1', '0', 'x', 'x', 'x', 'x', 'x', '1', '0', 'x', 'x', 'x', 'x', 'x', 'x']
elif bytesCount == 3:
template = ['1', '1', '1', '0', 'x', 'x', 'x', 'x', '1', '0', 'x', 'x', 'x', 'x', 'x', 'x', '1', '0', 'x', 'x',
'x',
'x', 'x', 'x']
elif bytesCount == 4:
template = ['1', '1', '1', '1', '0', 'x', 'x', 'x', '1', '0', 'x', 'x', 'x', 'x', 'x', 'x', '1', '0', 'x', 'x',
'x',
'x', 'x', 'x', '1', '0', 'x', 'x', 'x', 'x', 'x', 'x']
else:
return
results = []
unicodeList = list(unicodeBin)
counter = len(unicodeList) - 1
for el in reversed(template):
if el == 'x':
if counter >= 0:
results.append(unicodeList[counter])
counter -= 1
else:
results.append('0')
elif el == '0':
results.append('0')
else:
results.append('1')
results.reverse()
results = "".join(results)
if returnBin:
return results
else:
return convertBinToHex(results)
codePage = {}
with open("CP437.txt") as f:
for line in f:
(key, val) = line.split()
codePage[key] = val
text = []
with open("386intel.txt", 'rb') as f:
while True:
c = f.read(1)
if c:
# Converts bytes to bits (string)
text.append("{:08b}".format(int(c.hex(), 16)))
if not c:
print("End of file")
break
bytesString = 0
bytesStringInt = 0
resultFile = open("rez.txt", "wb")
for item in text:
decimalValue = int(item, 2)
newUnicode = codePage[str(decimalValue)]
unicodeToBin = "{0:08b}".format(int(newUnicode, 16))
bytesString = convertUnicodeToUTF(unicodeToBin, decimalValue, True)
if len(bytesString) > 8:
bytesStringSplit = [bytesString[i:i + 8] for i in range(0, len(bytesString), 8)]
for x in bytesStringSplit:
bytesStringInt = int(x, 2)
resultFile.write(bytes([bytesStringInt]))
# print(bytes([bytesStringInt]))
else:
bytesStringInt = int(bytesString, 2)
resultFile.write(bytes([bytesStringInt]))
# print(bytes([bytesStringInt]))
【问题讨论】:
标签: python unicode utf-8 decode encode