解码使用CP437表编码的文件

问题描述 投票:0回答:1

我必须编写程序来解码文件(使用CP437编码),方法是根据CP437表替换每个符号的Unicode,然后将其转换为UTF-8并将输出打印到文件中。

我有两个文件-一个输入文件,其中包含一个包含正常字符和一些奇怪字符的长文本(在结果文件中,这些奇怪字符将由各种破折号代替),以及一个CP437文件,其中包含256行对(第一部分是十进制数字,第二部分是Unicode,例如73 0049)。

这是我试图解决此问题的方式:

  1. 使用'RB'标志打开输入文件
  2. 因为我使用'RB'打开文件,所以我将每个符号读取为字节,然后将其存储在'文本'列表中
  3. 阅读完文件后,我在文本列表中循环浏览
  4. 在循环期间,我得到了符号的十进制值
  5. 我使用十进制值从CP437.txt文件中获得Unicode
  6. 我将Unicode转换为0和1s
  7. 我将Unicode的二进制表示形式转换为UTF-8,然后收到0和1返回
  8. 我将那些UTF-8 0和1转换为字节并将其写入到用“ WB”标志打开的结果文件

此外,如果UTF-8 0和1s的长度大于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]))

我必须编写程序来解码文件(使用CP437编码),方法是根据CP437表替换每个符号的Unicode,然后将其转换为UTF-8并将输出打印到文件中。...

python unicode utf-8 decode encode
1个回答
0
投票

未经测试,因为您忽略了提供输入文件:

© www.soinside.com 2019 - 2024. All rights reserved.