不知道特定编码时如何解码数据 [英] How do I decode data when I don't know the specific encoding
问题描述
我正在使用OSC服务器接收数据,数据看起来像这样:
I'm receiving data using an OSC server and the data looks like this:
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'Muse-C46F/elements/alpha_relative\x00\x00\x00,ffff\x00\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00'
b'Muse-C46F/elements/alpha_session_score\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
我正在尝试从这些编码序列中解码4个浮点数.
I'm trying to decode 4 floats from those encoded sequences.
这是我的完整代码:
print('Program Initiated')
UDP_IP = "192.168.2.57"
UDP_PORT = 4000
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
if 'alpha' in str(data):
print(struct.unpack('>32s8sffff', data))
我看到了一个类似的问题,并使用了print(struct.unpack('>32s8sffff', data))
,但出现unpack requires a buffer of 56 bytes
错误.
I saw a similar question and used the print(struct.unpack('>32s8sffff', data))
, but I get unpack requires a buffer of 56 bytes
as error.
推荐答案
这些OSC消息由三部分组成:
These OSC messages consists of three parts:
- 地址(应该以
b'/'
开头) - 以
b','
开头的类型标记字符串,它定义了后面的参数的类型和数量 - 消息参数,由类型标记字符串定义.
- An address (which ought to start with
b'/'
) - A type tag string, which starts with
b','
, and defines the type and number of arguments that follow - The messages arguments, as defined by the type tag string.
在问题提供的数据中,每个消息包含36或40个字节的地址,然后是5个字节的标记类型字符串.不考虑初始逗号,标记类型字符串由四个'f'组成,因此我们希望参数由四个浮点数组成,包括16个字节(每个浮点数4个).
In the data provided in the question, each message consists of 36 or 40 bytes of address, then 5 bytes of tag type string. Disregarding the initial comma, the tag type string consists of four 'f's, so we expect the arguments to consist of four floats, consisting of 16 bytes (4 per float).
每个消息在四个浮点数所需的16个字节之后都有一些额外的字节;让我们假设 * 这些是可以丢弃的填充.
Each message has some extra bytes after the 16 required for the four floats; let's assume* that these are padding that can be discarded.
因此结构格式将是:可变数量的地址字符,五个标记类型字符和四个浮点数.
Therefore the struct format is going to be: a variable number of address characters, five tag type characters and four floats.
然后提取数据所需的代码如下:
Then the code required to extract the data looks like this:
$ cat osc.py
$ cat osc.py
import struct
data = [
b"Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
b"Muse-C46F/elements/alpha_relative\x00\x00\x00,ffff\x00\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x
b"Muse-C46F/elements/alpha_session_score\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
b"Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
]
if __name__ == "__main__":
for msg in data:
num_address_bytes = msg.index(b",")
num_argument_bytes = len(msg) - (num_address_bytes + 5)
num_extra_bytes = num_argument_bytes - 16
address, type_, *floats = struct.unpack(
">{}s5s4f".format(num_address_bytes), msg[:-num_extra_bytes]
)
print(address, type_, floats)
生成此输出:
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]
b'Muse-C46F/elements/alpha_relative\x00\x00\x00' b',ffff' [1.7796490496925177e-43, -2.000030279159546, -2.000030279159546, -2.000030279159546]
b'Muse-C46F/elements/alpha_session_score\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]
* 进行假设通常不是一个好主意.如果OSC服务器具有说明文件,请检查其格式是否偏离 OSC规范.
* It's generally a bad idea to make assumptions. If the OSC server has documentation, check whether its formats deviate from the OSC spec.
这篇关于不知道特定编码时如何解码数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!