2

未加工のバイト エンコードされた IPv6 アドレスをipaddr-py プロジェクトの IPv6Address オブジェクトに変換する必要がよくあります。次に示すように、バイト エンコードされた IPv6 アドレスは初期化子によって受け入れられません。

>>> import ipaddr   
>>> byte_ip = b'\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
>>> ipaddr.IPAddress(byte_ip)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ipaddr.py", line 78, in IPAddress
    address)
ValueError: ' \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' does
 not appear to be an IPv4 or IPv6 address

バイトエンコーディングを ipaddr-py が理解できる形式に変換する最も簡単な方法は何ですか? ipaddr.py の v. 2.1.10 を使用しています。

これまでの私の唯一の回避策は、単純なタスクには長すぎることです。

>>> def bytes_to_ipaddr_string(c):
...     c = c.encode('hex')
...     if len(c) is not 32: raise Exception('invalid IPv6 address')
...     s = ''
...     while c is not '':
...         s = s + ':'
...         s = s + c[:4]
...         c = c[4:]
...     return s[1:]
...
>>> ipaddr.IPAddress(bytes_to_ipaddr_string(byte_ip))
IPv6Address('2000::1')

編集:クロスプラットフォーム ソリューションを探しています。Unix のみではできません。

誰もがより良い解決策を得ましたか?

4

2 に答える 2

2

Unix IPv6 では、bin -> 文字列の変換は簡単です。必要なのは次のsocket.inet_ntopとおりです。

>>> socket.inet_ntop(socket.AF_INET6, b'\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
'2000::1'
于 2012-05-09T09:52:40.243 に答える
1

見てくださいipaddr_test.py

[...]
# Compatibility function to cast str to bytes objects
if issubclass(ipaddr.Bytes, str):
    _cb = ipaddr.Bytes
else:
    _cb = lambda bytestr: bytes(bytestr, 'charmap')
[...]

それで

_cb('\x20\x01\x06\x58\x02\x2a\xca\xfe'
    '\x02\x00\x00\x00\x00\x00\x00\x01')

Bytesパックされたアドレスを含むとモジュールによって認識されるオブジェクトを提供します。

私はそれをテストしませんでしたが、意図したとおりのように見えます...


その間、私はそれをテストしました。おそらく、オブジェクト_cbを持たない古い moule バージョン用のものです。Bytesだからあなたはただできる

import ipaddr
b = ipaddr.Bytes('\x20\x01\x06\x58\x02\x2a\xca\xfe' '\x02\x00\x00\x00\x00\x00\x00\x01')
print ipaddr.IPAddress(b)

その結果、

2001:658:22a:cafe:200::1

これはおそらくあなたが必要とするものです。

于 2012-05-09T11:24:02.930 に答える