【问题标题】:How to write a file of ASCII bytes to a binary file as actual bytes?如何将 ASCII 字节文件作为实际字节写入二进制文件?
【发布时间】:2011-11-28 20:28:38
【问题描述】:

尝试做一个 MD5 冲突作业问题,但我不确定如何在 Python 中编写原始字节。我试了一下,但最终得到了一个包含 ASCII 的 .bin 文件。这是我的代码:

fileWriteObject1 = open("md5One.bin", 'wb')
fileWriteObject2 = open("md5Two.bin", 'wb')
fileReadObject1 = open('bytes1.txt', 'r')
fileReadObject2 = open('bytes2.txt', 'r')

bytes1Contents = fileReadObject1.readlines()
bytes2Contents = fileReadObject2.readlines()

fileReadObject1.close()
fileReadObject2.close()


for bytes in bytes1Contents:
    toWrite = r"\x" + bytes
    fileWriteObject1.write(toWrite.strip()) 

for bytes in bytes2Contents:
    toWrite = r"\x" + bytes
    fileWriteObject2.write((toWrite.strip())

fileWriteObject1.close()
fileWriteObject2.close()

样本输入: d1 31 dd 02 c5 e6 ee c4 69 3d 9a 06 98 af f9 5c 2f 约 b5

我有一个指向我的输入文件的链接,但似乎是一个 mod 删除了它。这是一个文件,每行都有一个用 ASCII 写的十六进制字节。

编辑:已解决!感谢 Circumflex。

我有两个不同的文本文件,每个文件都有 128 字节的 ASCII。我将它们转换为二进制文件并使用strike.pack 编写它们,结果发生了MD5 冲突。

【问题讨论】:

  • 您的输入实际上是什么样的? (从技术上讲,没有“ASCII 字节”之类的东西,但是有很多方法可以使用 ASCII 字符来表示任意字节。你应该指定你在说的是哪一种)
  • 我有一个指向我的输入文件的链接,但似乎是一个 mod 删除了它。这是一个文件,每行都有一个用 ASCII 写的十六进制字节。
  • 因此您需要将每对字符转换为一个字节,并将它们写入文件。要开始使用,请尝试int("d1", base=16)
  • int 占用的空间不是比字节多吗?
  • @advocate(3 cmets 以上):不是版主,只是普通用户的编辑,可能碰巧出现在错误的时间。 (顺便说一句,无需编辑您的问题以包含答案)

标签: python hex ascii


【解决方案1】:

如果要将它们写为原始字节,可以使用struct 类型的pack() 方法。

您可以将 MD5 写为 2 个 long long int,但您必须将其写入 2 个 8 字节的部分

http://docs.python.org/library/struct.html

编辑:

一个例子:

import struct

bytes = "6F"
byteAsInt = int(bytes, 16)
packedString = struct.pack('B', byteAsInt)

如果我说得对,您是在尝试提取一些写有十六进制字符串的文本,将它们转换为二进制格式并输出?如果是这种情况,该代码应该做你想做的事。

它基本上将原始的十六进制字符串转换为 int,然后以二进制形式(作为字节)将其打包成字符串。

您可以为输入字符串中的每个字节循环类似这样的内容

【讨论】:

  • 你有没有机会给我举个例子?我不确定格式字符。文档对我来说没有多大意义。
  • 当然,我已经在我的答案中添加了一个示例 :)
  • 这看起来很完美。我也在研究 binascii 包,它使用:binascii.a2b_hex('ee') 但它返回的缓冲区与字符串类不兼容,因此不确定如何保存或写入结果。
  • 使用encodedecode 代替struct。例如:'41'.decode('hex') 给你A'A'.encode('hex') 给你'41'
  • 但是如何将 'A'.encode('hex') 的结果写入文件呢?
【解决方案2】:
>>> import binascii
>>> binary = binascii.unhexlify("d131dd02c5")
>>> binary
'\xd11\xdd\x02\xc5'

binascii.unhexlify()binascii.c 中定义。这是 Python 中“接近 C”的实现:

def binascii_unhexlify(ascii_string_with_hex):
    arglen = len(ascii_string_with_hex) 
    if arglen % 2 != 0:
       raise TypeError("Odd-length string")

    retval = bytearray(arglen//2)
    for j, i in enumerate(xrange(0, arglen, 2)):
        top = to_int(ascii_string_with_hex[i])
        bot = to_int(ascii_string_with_hex[i+1])
        if top == -1 or bot == -1:
           raise TypeError("Non-hexadecimal digit found")
        retval[j] = (top << 4) + bot

    return bytes(retval)

def to_int(c):
    assert len(c) == 1
    return "0123456789abcdef".find(c.lower())

如果没有binascii.unhexlify()bytearray.fromhex()str.decode('hex') 或类似的,你可以这样写:

def unhexlify(s, table={"%02x" % i: chr(i) for i in range(0x100)}):
    if len(s) % 2 != 0: 
        raise TypeError("Odd-length string")
    try:
        return ''.join(table[top+bot] for top, bot in zip(*[iter(s.lower())]*2))
    except KeyError, e:
        raise TypeError("Non-hexadecimal digit found: %s" % e)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 2011-08-06
    • 2021-05-17
    • 2013-05-13
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多