使用 LUA 解码 UDP 消息
Decode UDP message with LUA
我对 lua 和一般编程(自学)比较陌生,所以请多多关照!
无论如何,我写了一个 lua 脚本来从游戏中读取 UDP 消息。消息的结构是:
DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH
DATAx = 4 letter ID and x = control character
XXXX = integer shows the group of the data (groups are known)
aaaa...HHHHH = 8 single-precision floating point numbers
最后一个是我需要解码的那些数字。
如果我打印收到的消息,它类似于:
DATA*{V???A?A?...etc.
使用 string.byte(),我得到了这样的字节流(我有 "formatted" 字节来反映上面的结构。
68 65 84 65/42/20 0 0 0/237 222 28 66/189 59 182 65/107 42 41 65/33 173 79 63/0 0 128 63/146 41 41 65/0 0 30 66/0 0 184 65
前5个字节当然是DATA*。接下来的4个是第20组数据。接下来的字节,我需要解码的字节,等于这些值:
237 222 28 66 = 39.218
189 59 182 65 = 22.779
107 42 41 65 = 10.573
33 173 79 63 = 0.8114
0 0 128 63 = 1.0000
146 41 41 65 = 10.573
0 0 30 66 = 39.500
0 0 184 65 = 23.000
我找到了使用 BitConverter.ToSingle() 进行解码的 C# 代码,但我还没有为 Lua 找到任何类似的代码。
有什么想法吗?
IEEE-754单精度二进制小端字节顺序:
例如,0 0 128 63
是:
00111111 10000000 00000000 00000000
(63) (128) (0) (0)
为什么等于 1
要求您了解 IEEE-754 表示的最基本知识,即指数和尾数的使用。请参阅 here 开始。
请参阅上面@Egor 的回答,了解如何在 Lua 5.3 中使用 string.unpack()
以及您可以在早期版本中使用的一种可能实现方式。
你有什么 Lua 版本?
此代码适用于 Lua 5.3
local str = "DATA*[=10=][=10=][=10=]7292..."
-- Read two float values starting from position 10 in the string
print(string.unpack("<ff", str, 10)) --> 39.217700958252 22.779169082642 18
-- 18 (third returned value) is the next position in the string
对于 Lua 5.1 你必须编写特殊函数(或者从 François Perrad's git repo 窃取它)
local function binary_to_float(str, pos)
local b1, b2, b3, b4 = str:byte(pos, pos+3)
local sign = b4 > 0x7F and -1 or 1
local expo = (b4 % 0x80) * 2 + math.floor(b3 / 0x80)
local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1
local n
if mant + expo == 0 then
n = sign * 0.0
elseif expo == 0xFF then
n = (mant == 0 and sign or 0) / 0
else
n = sign * (1 + mant / 0x800000) * 2.0^(expo - 0x7F)
end
return n
end
local str = "DATA*[=11=][=11=][=11=]7292..."
print(binary_to_float(str, 10)) --> 39.217700958252
print(binary_to_float(str, 14)) --> 22.779169082642
我对 lua 和一般编程(自学)比较陌生,所以请多多关照!
无论如何,我写了一个 lua 脚本来从游戏中读取 UDP 消息。消息的结构是:
DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH
DATAx = 4 letter ID and x = control character
XXXX = integer shows the group of the data (groups are known)
aaaa...HHHHH = 8 single-precision floating point numbers
最后一个是我需要解码的那些数字。
如果我打印收到的消息,它类似于:
DATA*{V???A?A?...etc.
使用 string.byte(),我得到了这样的字节流(我有 "formatted" 字节来反映上面的结构。
68 65 84 65/42/20 0 0 0/237 222 28 66/189 59 182 65/107 42 41 65/33 173 79 63/0 0 128 63/146 41 41 65/0 0 30 66/0 0 184 65
前5个字节当然是DATA*。接下来的4个是第20组数据。接下来的字节,我需要解码的字节,等于这些值:
237 222 28 66 = 39.218
189 59 182 65 = 22.779
107 42 41 65 = 10.573
33 173 79 63 = 0.8114
0 0 128 63 = 1.0000
146 41 41 65 = 10.573
0 0 30 66 = 39.500
0 0 184 65 = 23.000
我找到了使用 BitConverter.ToSingle() 进行解码的 C# 代码,但我还没有为 Lua 找到任何类似的代码。 有什么想法吗?
IEEE-754单精度二进制小端字节顺序:
例如,0 0 128 63
是:
00111111 10000000 00000000 00000000 (63) (128) (0) (0)
为什么等于 1
要求您了解 IEEE-754 表示的最基本知识,即指数和尾数的使用。请参阅 here 开始。
请参阅上面@Egor 的回答,了解如何在 Lua 5.3 中使用 string.unpack()
以及您可以在早期版本中使用的一种可能实现方式。
你有什么 Lua 版本?
此代码适用于 Lua 5.3
local str = "DATA*[=10=][=10=][=10=]7292..."
-- Read two float values starting from position 10 in the string
print(string.unpack("<ff", str, 10)) --> 39.217700958252 22.779169082642 18
-- 18 (third returned value) is the next position in the string
对于 Lua 5.1 你必须编写特殊函数(或者从 François Perrad's git repo 窃取它)
local function binary_to_float(str, pos)
local b1, b2, b3, b4 = str:byte(pos, pos+3)
local sign = b4 > 0x7F and -1 or 1
local expo = (b4 % 0x80) * 2 + math.floor(b3 / 0x80)
local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1
local n
if mant + expo == 0 then
n = sign * 0.0
elseif expo == 0xFF then
n = (mant == 0 and sign or 0) / 0
else
n = sign * (1 + mant / 0x800000) * 2.0^(expo - 0x7F)
end
return n
end
local str = "DATA*[=11=][=11=][=11=]7292..."
print(binary_to_float(str, 10)) --> 39.217700958252
print(binary_to_float(str, 14)) --> 22.779169082642