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