如何在数据和大小未定义时使用struct.pack

0 投票
1 回答
784 浏览
提问于 2025-04-18 05:48

我需要从CSV文件动态生成一个二进制文件。

举个例子:

CSV file:
#size, #data
1    , 0xAB
2    , 1234              (0x04D2)
5    , "ascii"           (0x6173636969)
1    , "\x23"            (0x23)

Expected binary file:
'\xAB\x04\xD2\x61\x73\x63\x69\x69\x23'

这些数据可以是字符串、无符号整数或者十六进制值。在我的程序中,我是这样处理的:

  • 我从CSV文件中读取大小和数据
  • 我使用eval函数来获取数据的值
  • 我使用Struct.pack函数来生成输出数据

现在的问题是,如何使用Struct.pack函数来处理字符串或数值。

我尝试过这样做:

  • 检查值是否是字符串类型,使用isinstance(value, basestring)来处理字符串
  • 但是我不知道如何处理以十六进制定义的无符号值(我也不知道如何为特殊大小指定格式类型,比如5字节)

我在考虑把任何值放入一个十六进制字符串中……

处理(字符串/无符号值转为指定大小的二进制输出)的最简单方法是什么?

1 个回答

1

如果你遇到一个字符串,只需要用 encode 方法把它转换成字节字符串。如果你遇到一个数值,可以尝试把它转换成十进制或十六进制的整数,然后再用 struct.pack 来处理:

formats = {
    1: "B",
    2: "H",
    4: "I",
    8: "Q"
}

def handle_value (size, value):
    try:
        value = int(value)
    except:
        try:
            value = int(value, 16)
        except:
            pass
    if type(value) == str:
        value = value[value.find('"') + 1, value.find('"') + 1 + size]
        value = value.encode("ascii") # or whatever encoding you want
    else:
        value = struct.pack(">" + formats[size], value)
    return value

接下来,要读取整个文件:

output = bytes()
for line in files:
    size, value = line.split(",")
    size = int(size.strip())
    value = value.strip()
    output += handle_value(size, value)

补充:我没注意到你是从CSV文件中获取大小的,所以如果这个值是整数的话,你可以根据这个大小推断出你想要的格式。

撰写回答