2017-10-09 40 views
0

做一個Unicode的主機名DNS解析返回如下:轉換` 195 164`爲'U' xc4'` - 結果從DNS解析器回爲Unicode

'\195\164\195\182\195\188o.mydomain104.local.' 

\195\164實際上是以下unicode字母:Äu'\xc4')。

原來的主機名是:

ÄÖÜO.mydomain104.local 

我正在尋找一種方式將其轉換回Unicode字符串(在python2.7)

如果需要的原代碼,這是像下面這樣:

from dns import resolver, reversename 
from dns.exception import DNSException 

def get_name(ip_address): 
    answer = None 
    res = resolver.Resolver() 
    addr = reversename.from_address(ip_address) 
    try: 
     answer = res.query(addr, "PTR")[0].to_text().decode("utf-8") 
    except DNSException: 
     pass 
    return answer 

我看着都.encode.decode,該unicodedata lib和codecs,發現沒有任何工作。

+0

這不是一個有效的DNS名稱,DNS中的國際字母必須在punycode('xn --...')中編碼。那麼你是如何檢索這些數據的? –

+0

@KlausD。感謝您的回覆,添加了在那裏使用的Python代碼... – Dekel

+0

請發表'repr(get_name(ip_address))',這樣我們就知道我們正在處理的是什麼'str'。 – unutbu

回答

4

線索#1:

In [1]: print(b'\xc3\xa4\xc3\xb6\xc3\xbc'.decode('utf_8')) 
äöü 

In [2]: print(bytearray([195,164,195,182,195,188]).decode('utf-8')) 
'äöü' 

線索#2:每the docs,Python的解釋\ooo與八進制值ooo,和\xhh與十六進制值hh ASCII字符的ASCII字符。

由於9不是有效的八進制數,所以'\195'被解釋爲'\1''95'

hex(195)'0xc3'。因此,我們不是'\195'而是'\xc3'。 我們需要將每個反斜槓後的小數轉換爲\xhh的形式。


在Python2:

import re 

given = r'\195\164\195\182\195\188o.mydomain104.local.' 
# print(list(given)) 
decimals_to_hex = re.sub(r'\\(\d+)', lambda match: '\\x{:x}'.format(int(match.group(1))), given) 
# print(list(decimals_to_hex)) 
result = decimals_to_hex.decode('string_escape') 
print(result) 

打印

äöüo.mydomain104.local. 

在Python3,使用codecs.escape_decode代替decode('string_escape')

import re 
import codecs 

given = rb'\195\164\195\182\195\188o.mydomain104.local.' 

decimals_to_hex = re.sub(rb'\\(\d+)', 
    lambda match: ('\\x{:x}'.format(int(match.group(1)))).encode('ascii'), given) 
print(codecs.escape_decode(decimals_to_hex)[0].decode('utf-8')) 

將打印相同的結果。