2017-10-09 1 views
0

Faire une résolution DNS sur un nom d'hôte unicode-retour ce qui suit:Convert ` 195 ` u 164` pour ' xc4'` - résultat du résolveur DNS Retour à unicode

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

Le \195\164 est en fait la lettre unicode suivante: Ä (u'\xc4').

Le nom d'hôte d'origine est:

ÄÖÜO.mydomain104.local 

Je suis à la recherche d'un moyen de le reconvertir à la chaîne unicode (en python2.7)

Dans le cas où le code d'origine est nécessaire, il est quelque chose comme ce qui suit:

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 

je regardais les deux .encode et .decode, le unicodedata lib et codecs et n'a rien trouvé qui a fonctionné.

+0

Ce n'est pas un nom DNS valide, les lettres internationales dans DNS doivent être codées en punycode ('xn --...'). Alors, comment avez-vous récupéré ces données? –

+0

@KlausD. merci pour la réponse, ajouté le code python utilisé là ... – Dekel

+0

S'il vous plaît poster 'repr (get_name (ip_address))' afin que nous sachions exactement quelle 'str' nous traitons. – unutbu

Répondre

4

Clue # 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')) 
'äöü' 

Clue # 2: Par the docs, Python interprète \ooo comme le caractère ASCII avec la valeur octal ooo et \xhh comme le caractère ASCII avec valeur hexadécimale hh. Comme 9 n'est pas un nombre octal valide, '\195' est interprété comme '\1' et '95'.

hex(195) est '0xc3'. Donc, au lieu de '\195', nous voulons '\xc3'. Nous devons convertir les nombres décimaux après chaque barre oblique inversée en \xhh.


En 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) 

impressions

äöüo.mydomain104.local. 

En python3, utilisez codecs.escape_decode au lieu de 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')) 

imprime le même résultat.