【问题标题】:What config file format to use for user-friendly strings of arbitrary bytes?用于用户友好的任意字节字符串的配置文件格式是什么?
【发布时间】:2023-03-20 14:58:01
【问题描述】:

所以我制作了一个简短的 Python 脚本,通过首先检查 magic number/file signature 来在 Windows 中启动具有模糊扩展名的文件:

我想将它编译为 .exe 以使关联更容易(使用 bbfreeze 或用 C 重写),但我需要某种用户友好的配置文件来指定匹配的字节字符串和程序路径。基本上我想以某种方式将此信息放入纯文本文件中:

magic_numbers = {
# TINA
'OBSS': r'%PROGRAMFILES(X86)%\DesignSoft\Tina 9 - TI\TINA.EXE',

# PSpice
'*version': r'%PROGRAMFILES(X86)%\Orcad\Capture\Capture.exe', 
'x100\x88\xce\xcf\xcfOrCAD ': '', #PSpice?

# Protel
'DProtel': r'%PROGRAMFILES(X86)%\Altium Designer S09 Viewer\dxp.exe', 

# Eagle
'\x10\x80': r'%PROGRAMFILES(X86)%\EAGLE-5.11.0\bin\eagle.exe',
'\x10\x00': r'%PROGRAMFILES(X86)%\EAGLE-5.11.0\bin\eagle.exe',
'<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE eagle ': r'%PROGRAMFILES(X86)%\EAGLE-5.11.0\bin\eagle.exe',

# PADS Logic
'\x00\xFE': r'C:\MentorGraphics\9.3PADS\SDD_HOME\Programs\powerlogic.exe', 
}

(十六进制字节只是任意字节,而不是 Unicode 字符。)

我猜这种格式的 .py 文件可以工作,但我必须不编译它,并以某种方式仍将其导入到编译后的文件中,并且还有一堆无关的内容,如 {, 被混淆通过/搞砸。

我查看了 YAML,它会很棒,只是它首先需要 base64 编码的二进制内容,而这并不是我真正想要的。我希望配置文件包含字节的十六进制表示。还有 ASCII 表示,如果这就是文件签名的全部内容的话。也许还有正则表达式。 :D(例如,如果基于 XML 的格式可以用不同数量的空格编写)

有什么想法吗?

【问题讨论】:

  • 你看过python-magic吗?
  • @jterrace:不,但是 1. 如果您只处理一个文件扩展名,这可能是矫枉过正? 2. libmagic 可能无法识别我关心的格式?不过,Their file format 似乎很相关。我没有意识到他们也处理正则表达式。
  • libmagic 的好处在于您可以添加自己的自定义格式,因此您可以轻松地用自己的格式扩展它
  • @jterrace:是的,确认file command 只是说这些是“数据”并且不知道更多。可以添加自定义格式,但我只是在完成我已经完成的事情。
  • 是的,我想我会解耦这两个配置文件:一个用于将幻数与 mimetypes 关联,另一个用于将 mimetypes 与启动器路径关联

标签: python configuration-files binary-data magic-numbers


【解决方案1】:

我使用了一些包来构建配置文件,还有 yaml。我建议你使用 ConfigParser 或 ConfigObj。

最后,最好的选择如果你想用 cmets 构建一个人类可读的配置文件,我强烈建议使用 ConfigObj。

享受吧!

ConfigObj 示例

使用此代码:

您也可以使用 ConfigObj 来存储它们。试试这个: 导入配置对象

def createConfig(path):
    config = configobj.ConfigObj()
    config.filename = path
    config["Sony"] = {}
    config["Sony"]["product"] = "Sony PS3"
    config["Sony"]["accessories"] = ['controller', 'eye', 'memory stick']
    config["Sony"]["retail price"] = "$400"
    config["Sony"]["binary one"]= bin(173)
    config.write()

你得到这个文件:

[Sony]
product = Sony PS3
accessories = controller, eye, memory stick
retail price = $400
binary one = 0b10101101

【讨论】:

  • 没有提到如何表示二进制值?
  • 目标是手动编写配置文件并让软件读取它们,而不是相反。
  • "INI 文件通常被限制在两个级别(节和属性),不能很好地处理二进制数据。"
【解决方案2】:

你已经得到了答案:YAML。

您在上面发布的数据是存储二进制数据的文本表示;这对 YAML 来说很好,你只需要正确解析它。通常你会使用 binascii 模块中的一些东西;在这种情况下,可能是 binascii.a2b_qp 函数。

magic_id_str = 'x100\x88\xce\xcf\xcfOrCAD '
magic_id = binascii.a2b_qp(magic_id_str)

为了说明,我将使用 unicode 字符作为将二进制数据粘贴到 REPL (Python 2.7) 中的一种简单方法:

>>> a = 'Φ'  
>>> a  
'\xce\xa6'  
>>> binascii.b2a_qp(a)  
'=CE=A6'  
>>> magic_text = yaml.load("""  
... magic_string: '=CE=A6'  
... """)  
>>> magic_text  
{'magic_string': '=CE=A6'}  
>>> binascii.a2b_qp(magic_text['magic_string'])  
'\xce\xa6'  

【讨论】:

  • 等等,那么你将如何将它写入配置文件并与yaml.load 一起使用?现在我认为格式可能稍微复杂一些,带有数据类型的说明符,您可以输入[string, DProtel][hex, 88 ce cf cf] 之类的内容,程序会以不同方式处理。
  • 我现在用yaml.add_implicit_resolver 隐式地工作了。 88 ce cf c4 形式的任何内容都将转换为二进制,不需要标记。其他任何内容都被解释为字符串。
【解决方案3】:

我建议这样做有点不同。我会将这两个设置相互分离:

  1. 幻数签名 ===> mimetype
  2. mimetype ==> 程序启动器

对于第一部分,我将使用python-magic,这是一个绑定到libmagic 的库。您可以让 python-magic 使用这样的自定义魔法文件:

import magic
m = magic.Magic(magic_file='/path/to/magic.file')

您的用户可以指定将幻数映射到 mimetype 的自定义幻数文件。魔术文件的语法是documented。这是一个显示 TIFF 格式的魔法文件的示例:

# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com)
# The second word of TIFF files is the TIFF version number, 42, which has
# never changed.  The TIFF specification recommends testing for it.
0       string          MM\x00\x2a      TIFF image data, big-endian
!:mime  image/tiff
0       string          II\x2a\x00      TIFF image data, little-endian
!:mime  image/tiff

那么第二部分就很简单了,因为您现在只需要指定文本数据。您可以按照其他人的建议使用 INI 或 yaml 格式,或者您甚至可以只有一个简单的制表符分隔文件,如下所示:

image/tiff         C:\Program Files\imageviewer.exe
application/json   C:\Program Files\notepad.exe

【讨论】:

    猜你喜欢
    • 2018-08-28
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多