Search code examples
python-2.7hexnet-snmp

How to convert from hex-encoded string to a "human readable" string?


I'm using the Net-SNMP bindings for python and I'm attempting to grab an ARP cache from a Brocade switch. Here's what my code looks like:

#!/usr/bin/env python

import netsnmp

def get_arp():
    oid = netsnmp.VarList(netsnmp.Varbind('ipNetToMediaPhysAddress'))
    res = netsnmp.snmpwalk(oid, Version=2, DestHost='10.0.1.243', Community='public')
    return res

arp_table = get_arp()

print arp_table

The SNMP code itself is working fine. Output from snmpwalk looks like this:

<snip>
IP-MIB::ipNetToMediaPhysAddress.128.10.200.6.158 = STRING: 0:1b:ed:a3:ec:c1
IP-MIB::ipNetToMediaPhysAddress.129.10.200.6.162 = STRING: 0:1b:ed:a4:ac:c1
IP-MIB::ipNetToMediaPhysAddress.130.10.200.6.166 = STRING: 0:1b:ed:38:24:1
IP-MIB::ipNetToMediaPhysAddress.131.10.200.6.170 = STRING: 74:8e:f8:62:84:1
</snip>

But my output from the python script yields a tuple of hex-encoded strings that looks like this:

('\x00$8C\x98\xc1', '\x00\x1b\xed;_A', '\x00\x1b\xed\xb4\x8f\x81', '\x00$86\x15\x81', '\x00$8C\x98\x81', '\x00\x1b\xed\x9f\xadA', ...etc)

I've spent some time googling and came across the struct module and the .decode("hex") string method, but the .decode("hex") method doesn't seem to work:

Python 2.7.3 (default, Apr 10 2013, 06:20:15)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hexstring = '\x00$8C\x98\xc1'
>>> newstring = hexstring.decode("hex")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/hex_codec.py", line 42, in hex_decode
    output = binascii.a2b_hex(input)
TypeError: Non-hexadecimal digit found
>>>

And the documentation for struct is a bit over my head.


Solution

  • Some more clever google-fu uncovered this code snippet, which gives me the results I expect:

    def convertMac(octet):
        mac = [binascii.b2a_hex(x) for x in list(octet)]
        return ":".join(mac)
    

    So "decoding" is really a misnomer, because this code also yields a proper result (with encode and decode appearing to be syntactic sugar for binascii.a2b() and binascii.b2a()):

    Python 2.7.3 (default, Apr 10 2013, 06:20:15)
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> string = '\x00$8\xa1\x1c2'
    >>> string.encode("hex")
    '002438a11c32'
    >>>