Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何对pysnmp获取的不透明数据进行解码?_Python_Python 3.x_Encoding_Snmp_Pysnmp - Fatal编程技术网

Python 如何对pysnmp获取的不透明数据进行解码?

Python 如何对pysnmp获取的不透明数据进行解码?,python,python-3.x,encoding,snmp,pysnmp,Python,Python 3.x,Encoding,Snmp,Pysnmp,我将通过pysnmp库通过其OID从SNMP设备读取数据。但是,我正在处理来自不透明类型的错误: 从pysnmp导入hlapi def构造对象类型(OID列表): 对象类型=[] 对于\u oid列表中的oid: object_types.append(hlapi.ObjectType(hlapi.ObjectIdentity(oid))) 返回对象类型 def get(目标,OID,凭证,端口=161,引擎=hlapi.SnmpEngine(), context=hlapi.ContextDa

我将通过
pysnmp
库通过其OID从SNMP设备读取数据。但是,我正在处理来自不透明类型的错误:

从pysnmp导入hlapi
def构造对象类型(OID列表):
对象类型=[]
对于\u oid列表中的oid:
object_types.append(hlapi.ObjectType(hlapi.ObjectIdentity(oid)))
返回对象类型
def get(目标,OID,凭证,端口=161,引擎=hlapi.SnmpEngine(),
context=hlapi.ContextData()):
handler=hlapi.getCmd(
引擎,
资格证书
hlapi.udptTransportTarget((目标,端口)),
上下文
*构造对象类型(OID)
)
返回获取(处理程序,1)[0]
def cast(值):
尝试:
返回int(值)
除了(ValueError、TypeError):
尝试:
返回浮动(值)
除了(ValueError、TypeError):
尝试:
返回str(值)
除了(ValueError,TypeError)作为exc:
打印(exc)
返回值
def fetch(处理程序,计数):
结果=[]
对于范围内的i(计数):
(错误指示、错误状态、,
错误索引,变量绑定)=下一个(处理程序)
如果非错误指示和非错误状态:
项目={}
打印(变量绑定)
对于var_绑定中的var_绑定:
items[str(变量绑定[0])]=cast(变量绑定[1])
结果。追加(项)
其他:
引发运行时错误(f'SNMP错误:{error\u indication}')
返回结果
打印(获取(“192.168.100.112”、[”.1.3.6.1.4.1.9839.1.2.532.0”,
'.1.3.6.1.4.1.9839.1.2.513.0'],
hlapi.CommunityData(“public”))
输出:

[ObjectType(ObjectIdentity(),),ObjectType(ObjectIdentity(),)]
{'1.3.6.1.4.1.9839.1.2.532.0':'\x9fx\x04AÌF','1.3.6.1.4.1.9839.1.2.513.0':10}
第一个OID(
.1.3.6.1.4.1.9839.1.2.532.0
)返回不透明值(
\x9fx\x04AÌF
),我不知道如何将其转换为浮点值。我应该补充一点,那就是温度值
25.5℃


换句话说,我如何通过彼此达到以下值

  • 25.5
  • 编码iso-8859-1,有效载荷[0x9f780441ccb646]
  • '\x9fx\x04ĄF'

您的值
0x9f780441ccb646
可以

  • 分成两个浮动,其中一个是
    25.589001
    ,另一个是其他部分,或者
  • 中间是
    pysnmp
    对象(
    \uuuu repr\uuuu
    )的表示,没有已知的解释(可能缺少MIB),或者
  • 已转换为字节表示形式(使用iso-8859-1编码),即字符串
    '\x9fx\x04ĄF'
因此,数据就在那里,它只需要从SNMP数据包中提取。正确的方法是为pysnmp提供相应的MIB条目

或者(回答第二个问题),手动解码字节的方法可以使用Python模块完成

导入结构
data=0x9f780441ccb646#这是您从pysnmp获得的数据
字节=结构包(“l”,数据)
打印(字节.解码('latin1'))
打印(字节)
打印(结构解包(“ff”,字节))
给予

FÌAx
b'F\xb6\xccA\x04x\x9f\x00'
(25.58900071904297、1.4644897383138518e-38)
MIB将告诉您应该如何解释其他数据,而不是将数据解包为两个浮点,因此,您可能不需要
解包(“ff”…
,而是查看可用的,例如
“fhh”
将给出
(25.5890007190429730724159)

编辑:

TL;DR:

data = '\0\x9fx\x04A̶F'
print("temperature: %f°C" % struct.unpack('>ff', data.encode('latin1'))[1])
详细说明字符串表示法:您看到的字节的顺序与我的打印语句中的字节的顺序相反,因为它们的顺序不同。字节顺序已在您在输出中提供的、我在co中使用的
int
转换数据
0x9f780441ccb646
中更正转换示例。如果要从编码字符串开始,首先需要将其转换回正确的内存表示形式:

data = '\0\x9fx\x04A̶F'       # (initial '\0' is for filling the 8-bytes in correct alignment)
thebytes =  data.encode('latin1')
但这只是技巧的一半,因为现在endianess仍然是错误的。幸运的是,
struct
有相应的标志来纠正这一点。您可以按两个字节顺序解包并选择正确的一个

print("unpacked little-endian: ", struct.unpack("<ff", thebytes))
print("unpacked big-endian:    ", struct.unpack(">ff", thebytes))
unknown, temperature = struct.unpack(">ff", thebytes)
print("temperature: %f°C" % temperature)
不透明数据包的正确端号是SNMP标准的一部分(那么“网络字节顺序”可能是正确的),或也应在MIB中与需要作为格式说明符提供的正确字段类型一起提供。如果数据包的长度始终为7字节,则可以尝试将其添加到7字节而不是8字节的组合(
ff
=4+4),那么您也可以省略添加填充字节。

根据加上一些更改,并且知道
不透明的
帧由
7个
字节组成,其中
3个
字节是常量(
\x9fx\x04
159\120\4
),我编写了以下代码片段来处理该问题:

。。。
handler=get(“192.168.100.112”,[”.1.3.6.1.4.1.9839.1.2.532.0”,
'.1.3.6.1.4.1.9839.1.2.513.0'],
hlapi.CommunityData('public'))
对于键,handler.items()中的值:
尝试:
如果len(value)==7和值[0],则编码('latin1')[0]==159\
和值[1]。编码('latin1')[0]==120\
和值[2]。编码('latin1')[0]==4:
数据=值[3:]
打印(结构解包('>f',数据编码('latin1'))[0])
其他:
打印(值)
除属性错误外:
打印(值)
输出:


[注意]:

  • 不透明是一种小的尾端格式(
    结构中的

[更新]:

更多智慧
data = '\0\x9fx\x04A̶F'       # (initial '\0' is for filling the 8-bytes in correct alignment)
thebytes =  data.encode('latin1')
print("unpacked little-endian: ", struct.unpack("<ff", thebytes))
print("unpacked big-endian:    ", struct.unpack(">ff", thebytes))
unknown, temperature = struct.unpack(">ff", thebytes)
print("temperature: %f°C" % temperature)
unpacked little-endian:  (2.9225269119838333e-36, 23398.126953125)
unpacked big-endian:     (1.4644897383138518e-38, 25.589000701904297)
temperature: 25.589001°C
25.589001
10