Lua (5.0) equivalent to python struct.pack

I am trying to convert Python code to Lua. Which is the Lua equivalent:

value2 = ''
key = 'cmpg'
value1 = '\x00\x00\x00\x00\x00\x00\x00\x01'
Value2 += '%s%s%s' % (key, struct.pack('>i', len(value1)), value1)

      

+3


source to share


4 answers


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.

-1


source


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)

      

+3


source


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.

+2


source


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>

      

+1


source







All Articles