Lua (5.0) эквивалент python struct.pack - PullRequest
3 голосов
/ 17 марта 2012

Я пытаюсь преобразовать код Python в Lua.Что эквивалентно Lua:

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

Ответы [ 4 ]

3 голосов
/ 18 марта 2012

Как насчет использования struct.pack для Lua (оно основано на коде string.pack)? Он предлагает ту же функциональность, которую вы ожидаете. Поэтому вы можете запустить следующий код:

local key = 'cmpg'
local value1 = '\0\0\0\0\0\1'
local packed = key .. struct.pack('>i', #value1) .. value1

Или, посмотрев примеры в документации, вы также можете сделать это так:

local packed = key .. struct.pack('>ic0', #value1, value1)

Чтобы распаковать такую ​​строку, используйте следующее (при условии, что у вас есть только <length,string> в data):

local unpacked = struct.unpack('>ic0', data)
1 голос
/ 17 марта 2012

Взгляните на string.pack ;Вы можете найти предварительно скомпилированные двоичные файлы для Windows, включенные в Lua для 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))

Если вы используете LuaJIT (что я настоятельно рекомендую), вы можете использовать FFIи приведите исходное значение к байтовому массиву и используйте memcpy.

1 голос
/ 17 марта 2012

Read Write Format Вики-страница содержит функции, которые обеспечивают способ упаковки / распаковки целочисленных значений в двоичную строку.

Пример

-- 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")

Выход

<abcd>
0 голосов
/ 17 марта 2012

Вы сказали в комментарии:

Я смогу обойтись, зная строку, сгенерированную каждым из следующее: struct.pack ('> i', 4), struct.pack ('> i', 8) и struct.pack ( '> я', 10)

эффектор '> i' означает 32-разрядное целое число со знаком бигендии. Для неотрицательного ввода x простой эквивалент Python будет

chr((x >> 24) & 255) + chr((x >> 16) & 255) + chr((x >> 8) & 255) + chr(x & 255)

Вы должны быть в состоянии выразить это в Lua без особых затруднений.

Вы сказали в еще одном комментарии:

Я ... не понимаю ответа (@john machin)

chr (x) легко найти в документации. У Lua должна быть такая функция, возможно, даже с тем же именем.

i >> n сдвигает меня вправо на n бит. Если я без знака, это эквивалентно i // ( 2 ** n), где // - целочисленное деление на пол Python.

i & 255 является побитовым и эквивалентен i % 256.

У Луа должны быть оба.

В этом случае + - это конкатенация строк.

Посмотрите на это:

>>> 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
>>>

Вы заметите, что для 10 необходим вывод '\x00\x00\x00\n' ... обратите внимание, что '\x0a' aka '\n' aka chr(10) нуждается в уходе. Если вы пишете этот материал в файл в Windows, вы должны открыть файл в режиме двоичный ('wb', а не 'w'), в противном случае библиотека времени выполнения вставит байт возврата каретки в соответствовать соглашениям Windows, MS-DOS, CP / M для текстовых файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...