Lua (5.0) equivalent to python struct.pack
You said in a comment:
I may be able to get around knowing the string generated by each of the following: struct.pack ('> i', 4), struct.pack ('> i', 8) and struct.pack ('> I', 10)
Effector '> i' means bidian 32-bit integer. For non-negative input x, the simple Python equivalent would be
chr((x >> 24) & 255) + chr((x >> 16) & 255) + chr((x >> 8) & 255) + chr(x & 255)
You may be able to express this in Lua without too much difficulty.
You said in another comment:
I ... don't understand the answer (@john machin)
chr (x) is easy to find in the docs. Lua should have such a function, perhaps even with the same name.
i >> n
shifts i to the right n bits. If I'm unsigned, this is equivalent i // ( 2 ** n)
to where //
is integer division in Python.
i & 255
is bitwise and equivalent i % 256
.
Lua must have both of these.
+
in this case is string concatenation.
Look at this:
>>> import binascii
>>> def pack_be_I(x):
... return (
... chr((x >> 24) & 255) +
... chr((x >> 16) & 255) +
... chr((x >> 8) & 255) +
... chr(x & 255)
... )
...
>>> for anint in (4, 8, 10, 0x01020304, 0x04030201):
... packed = pack_be_I(anint)
... hexbytes = binascii.hexlify(packed)
... print anint, repr(packed), hexbytes
...
4 '\x00\x00\x00\x04' 00000004
8 '\x00\x00\x00\x08' 00000008
10 '\x00\x00\x00\n' 0000000a
16909060 '\x01\x02\x03\x04' 01020304
67305985 '\x04\x03\x02\x01' 04030201
>>>
You will notice that the required output for 10
is '\x00\x00\x00\n'
... note that '\x0a'
aka '\n'
aka chr(10)
needs help. If you are writing this stuff to a file on Windows, you must open the file in binary ( 'wb'
, not 'w'
) mode , otherwise the runtime library inserts a carriage return byte to comply with Windows, MS-DOS, CP / M requirements for text files.
source to share
How about using it struct.pack
for Lua (it's code based string.pack
)? It offers the same functionality you'd expect. Therefore, you can run the following code:
local key = 'cmpg'
local value1 = '\0\0\0\0\0\1'
local packed = key .. struct.pack('>i', #value1) .. value1
Or, looking at the examples in the docs, you can also do it like this:
local packed = key .. struct.pack('>ic0', #value1, value1)
To unpack this line, use the following (if you have only <length,string>
to data
):
local unpacked = struct.unpack('>ic0', data)
source to share
Take a look at string.pack ; you can find the precompiled binaries for Windows included with Lua for Windows .
value2 = ''
key = 'cmpg'
value1 = '\x00\x00\x00\x00\x00\x00\x00\x01'
value2 = string.format("%s%s%s", key, string.pack(">i", #value1, value))
If you are using LuaJIT (which I highly recommend) you can use FFI and cast the original value into a byte array and use memcpy.
source to share
The Read Write Format wiki page contains functions that provide a way to batch / unpack integer values into a binary string.
Example
-- Write an integer in MSB order using width bytes.
function numbertobytes(num, width)
local function _n2b(t, width, num, rem)
if width == 0 then return table.concat(t) end
table.insert(t, 1, string.char(rem * 256))
return _n2b(t, width-1, math.modf(num/256))
end
return _n2b({}, width, math.modf(num/256))
end
io.write("<", numbertobytes(0x61626364, 4), ">\n")
Output
<abcd>
source to share