# 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

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