0

我编写了 python 代码,使用 pysnmp 将 snmp get 发送到设备,然后将输出转换为十六进制字符串。该代码在 python 2.7 中成功运行,但在 Python3.7 中没有

在 python2.7 和 python3.7 中,snmp get 返回一个pysnmp.proto.rfc1902.OctetString然后使用binascii.hexlify.

在 python2.7 中,转换是通过将 传递str(OctateString_var)给 hexlify 函数来完成的。

在 python3.7 中,我使用str(OctateString_var).encode()hexlify 函数需要 python3 中的字节字符串。

我注意到生成的十六进制的结果与来自 python3.7 的结果不同,它有额外的字节并最终产生错误的值

import binascii
from pysnmp.entity.rfc3413.oneliner import cmdgen

cmdGen = cmdgen.CommandGenerator()
ip = '10.1.1.1'
oid = '1.3.6.1.2.1.138.1.6.3.1.3'
comm = 'ro'

errIndicator, errStatus, errIndex, var = cmdGen.nextCmd(cmdgen.CommunityData(comm),
                                              cmdgen.UdpTransportTarget((ip, 161)),
                                                                             oid)

for varRow in var:
    for oid, ip in varRow:
        print('ID: ',ip, type(ip))

        try:
        # below is for python3.7
           hex_string = binascii.hexlify(str(ip).encode())
           hex_string = hex_string.decode()

        except:
        # below is for python2.7
           hex_string = binascii.hexlify(str(ip))

        print('HEX: ',hex_string)

在 python2.7 上运行时,我得到以下结果:

('ID: ', <OctetString value object at 0x10506e80 subtypeSpec <ConstraintsIntersection object at 0xe4e0080 consts <ValueSizeConstraint object at 0xe4e0048 consts 0, 65535>> tagSet <TagSet object at 0xe4a9630 tags 0:0:4> encoding iso-8859-1 payload [0x9b0c0065]>, <class 'pysnmp.proto.rfc1902.OctetString'>)
('HEX: ', '9b0c0065')

在 python3.7 上运行时,我得到以下结果:

ID: <0x9b><0x0c><0x00>e <class 'pysnmp.proto.rfc1902.OctetString'>
HEX:  c29b0c0065
4

2 回答 2

1

也许你应该更好地使用 version-neutral .asNumbers()

>>> from pyasn1.type.univ import OctetString
>>> OctetString(hexValue='01020304')
<OctetString value object, tagSet <TagSet object, tags 0:0:4>, encoding iso-8859-1, payload [0x01020304]>
>>> OctetString(hexValue='01020304').asNumbers()
(1, 2, 3, 4)
>>> ''.join('%.2x' % x for x in OctetString(hexValue='01020304').asNumbers())
'01020304'

于 2019-09-17T12:41:38.133 回答
1

我建立的快速修复是将ocatestring的每个八进制(字节)转换为一个字符串并将它们放在一个列表中,因为ip = [str(octate) for octate in ip]这将产生一个代表十进制数字的数字字符列表,然后可以单独转换为十六进制

代码

for varRow in var:
    for oid, ip in varRow:
         decimal_ip_octates = [str(octate) for octate in ip]

于 2019-09-17T12:56:23.923 回答