我正在尝试移植一些Delphi代码,将数据发送到Universe数据库。为了使文本易读的数据库,我们需要在原始设备制造商编码它。你知道吗
在Delphi中是这样做的:
procedure TForm1.GenerarTablasNLS;
var
i: integer;
begin
for i := 0 to 255 do
begin
TablaUV_NLS[i] := AnsiChar(i);
TablaNLS_UV[i] := AnsiChar(i);
end;
// Nulo final
TablaUV_NLS[256] := #0;
TablaNLS_UV[256] := #0;
OemToCharA(@TablaUV_NLS[1], @TablaUV_NLS[1]);
CharToOemA(@TablaNLS_UV[1], @TablaNLS_UV[1]);
然后我们就这样翻译我们的文本
function StringToUniverse(const Value: string): AnsiString;
var
p: PChar;
q: PAnsiChar;
begin
SetLength(Result, Length(Value));
if Value = '' then Exit;
p := Pointer(Value);
q := Pointer(Result);
while p^ <> #0 do
begin
q^ := TablaNLS_UV[Ord(AnsiChar(p^))];
Inc(p);
Inc(q);
end;
end;
我在Python中遵循相同的逻辑,使用一个存储每个字符翻译的字典
class StringUniverseDict(dict):
def __missing__(self, key):
return key
TablaString2UV = StringUniverseDict()
def rellenar_tablas_codificacion():
TablaString2UV['á'] = ' ' # chr(225) = chr(160)
TablaString2UV['é'] = '‚' # chr(233) = chr(130)
TablaString2UV['í'] = '¡' # chr(237) = chr(161)
TablaString2UV['ó'] = '¢' # chr(243) = chr(162)
TablaString2UV['ú'] = '£' # chr(250) = chr(163)
TablaString2UV['ñ'] = '¤' # chr(241) = chr(164)
TablaString2UV['ç'] = '‡' # chr(231) = chr(135)
TablaString2UV['Á'] = 'µ' # chr(193) = chr(181)
TablaString2UV['É'] = chr(144) # chr(201) = chr(144)
TablaString2UV['Í'] = 'Ö' # chr(205) = chr(214)
TablaString2UV['Ó'] = 'à' # chr(211) = chr(224)
TablaString2UV['Ñ'] = '¥' # chr(209) = chr(165)
TablaString2UV['Ç'] = '€' # chr(199) = chr(128)
TablaString2UV['ü'] = chr(129) # chr(252) = chr(129)
TablaString2UV[chr(129)] = '_' # chr(129) = chr(095)
TablaString2UV[chr(141)] = '_' # chr(141) = chr(095)
TablaString2UV['•'] = chr(007) # chr(149) = chr(007)
TablaString2UV['Å'] = chr(143) # chr(197) = chr(143)
TablaString2UV['Ø'] = chr(157) # chr(216) = chr(157)
TablaString2UV['ì'] = chr(141) # chr(236) = chr(141)
只要我使用可打印的字符进行翻译,这个工作就“很好”。例如,字符串
"á é í ó ú ñ ç Á Í Ó Ú Ñ Ç"
在Delphi中转换为以下字节:
0xa0 0x20 0x82 0x20 0xa1 0x20 0xa2 0x20 0xa3 0x20 0xa4 0x20 0x87 0x20 0xb5 0x20 0xd6 0x20 0xe0 0x20 0xe9 0x20 0xa5 0x20 0x80 0xfe 0x73 0x64 0x73
(a)转换为“”,即十六进制的chr(160)或0xA0。éis'''或chr(130),0x82在hexa中,íis''',char(161)或0xA1在hexa中,依此类推)
在Python中,当我尝试将其编码到OEM时,我会执行以下操作:
def convertir_string_a_universe(cadena_python):
resultado = ''
for letra in cadena_python:
resultado += TablaString2UV[letra]
return resultado
然后,得到字节
txt_registro = convertir_string_a_universe(txt_orig)
datos = bytes(txt_registro, 'cp1252')
通过这个,我得到以下字节:
b'\xa0 \x82 \xa1 \xa2 \xa3 \xa4 \x87 \xb5 \xd6 \xe0 \xe9 \xa5 \x80 \x9a'
我的问题是,这种原始设备制造商编码使用不可打印的字符,如在'É'=chr(144)(0x90在十六进制)。如果我尝试用数组调用bytes(txt_registro,'cp1252'),其中我将'É'翻译成chr(0x90),我会得到以下错误:
caracteres_mal = 'Éü'
txt_registro = convertir_string_a_universe(txt_orig)
datos = bytes(txt_registro, 'cp1252')
File "C:\Users\Hector\PyCharmProjects\pyuniverse\pyuniverse\UniverseRegister.py", line 138, in reconstruir_registro_universe
datos = bytes(txt_registro, 'cp1252')
File "C:\Users\Hector\AppData\Local\Programs\Python\Python36-32\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character '\x90' in position 0: character maps to <undefined>
如何在不引发此UnicodeEncodeError的情况下执行此OEM编码?你知道吗
这是因为
cp1252
不知道chr(0x90)
。如果你试着用utf-8
来代替,它会工作的。你知道吗我不明白你为什么要转换成
cp1252
:你已经应用了一个自定义的转换映射,然后用bytes(txt_registro, 'cp1252')
,你又将结果转换成cp1552
。你知道吗我想你想要的是:
其中
uv
是cutom编解码器。你知道吗因此,您必须为它编写一个编码器和一个解码器(这基本上是您已经完成的工作)。看看https://docs.python.org/3/library/codecs.html#codecs.register 注册新的编解码器。您将向其注册的函数应该返回文档中上面描述的CodecInfo对象。你知道吗
编辑
编码器/解码器函数应该返回字节,因此需要更新
convertir_string_a_universe
一点。你知道吗相关问题 更多 >
编程相关推荐