Python 解码使用CP437表编码的文件

Python 解码使用CP437表编码的文件,python,unicode,utf-8,decode,encode,Python,Unicode,Utf 8,Decode,Encode,我必须编写一个程序来解码文件(使用CP437编码),根据CP437表替换每个符号的Unicode,然后将其转换为UTF-8并将输出打印到文件中 我有两个文件——一个输入文件包含一个长文本,其中包含普通字符和一些奇怪的字符(在结果文件中,这些奇怪的字符将被各种破折号替换),另一个CP437文件包含256行对(第一部分是十进制数,第二部分是Unicode,例如73 0049) 这就是我试图解决这个问题的方法: 使用“RB”标志打开输入文件 因为我使用“RB”打开文件,所以我将每个符号都读取为字节,然

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

我有两个文件——一个输入文件包含一个长文本,其中包含普通字符和一些奇怪的字符(在结果文件中,这些奇怪的字符将被各种破折号替换),另一个CP437文件包含256行对(第一部分是十进制数,第二部分是Unicode,例如73 0049)

这就是我试图解决这个问题的方法:

  • 使用“RB”标志打开输入文件
  • 因为我使用“RB”打开文件,所以我将每个符号都读取为字节,然后将其存储在“text”列表中
  • 读完文件后,我循环浏览文本列表
  • 在循环过程中,我得到符号的十进制值
  • 我使用十进制值从CP437.txt文件中获取Unicode
  • 我将Unicode转换为0和1
  • 我将Unicode的二进制表示形式转换为UTF-8和 返回0和1
  • 我将这些UTF-80和1转换为字节,并将它们写入 使用“WB”标志打开的结果文件
  • 另外,如果UTF-80和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]))
    
    def convertBinToHex(二进制):
    binToHex=hex(整数(二进制,2))
    临时=列表(binToHex)
    温度=温度[2:]
    binToHex=“.join(temp.upper)()
    返回binToHex
    def转换器UNICODETOUT(unicodeBin、symbolDecimal、returnBin):
    # https://stackoverflow.com/questions/6240055/manually-converting-unicode-codepoints-into-utf-8-and-utf-16
    字节数=0
    
    如果由于忽略提供输入文件而导致int(“0000”,16)未测试:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use autodie;
    
    my @cp;
    {
        open my $fh, '<', 'CP437.txt';
        while (my $line = readline $fh) {
            chomp $line;
            my ($k, $v) = split ' ', $line;
            $cp[$k] = chr hex $v;
        }
    }
    {
        open my $in, '<:raw', '386intel.txt';
        open my $out, '>:encoding(UTF-8)', '386intel.txt.utf8';
        while (my $line = readline $in) {
            $out->print(
                join '',            # 5. join characters into string
                map {               # 2. loop over octets
                    $cp[            # 4. look up character corresponding to
                                        # octet numeric value
                        ord         # 3. numeric value of octet
                    ]
                }
                split '', $line     # 1. split line into octets
            );
        }
    }
    
    #/usr/bin/env perl
    严格使用;
    使用警告;
    使用自动模具;
    我的@cp;
    {
    打开我的$fh,'
    
    › piconv -f CP437 -t UTF-8 < 386intel.txt > 386intel.txt.utf8