如何将ASCII字节写入二进制文件?

3 投票
2 回答
5467 浏览
提问于 2025-04-17 03:28

我在做一个关于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 ca b5

我之前有一个链接指向我的输入文件,但好像被管理员删掉了。这个文件每一行都是用ASCII写的十六进制字节。

编辑:解决了!感谢Circumflex。

我有两个不同的文本文件,每个文件里有128个ASCII字节。我把它们转换成二进制格式,然后用struck.pack写入,成功得到了一个MD5碰撞。

2 个回答

0
>>> 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)
4

如果你想把数据写成原始字节,可以使用 struct 类型的 pack() 方法。

你可以把 MD5 值写成两个长整型数字,但需要把它分成两个 8 字节的部分来写。

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

编辑:

举个例子:

import struct

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

如果我理解没错,你是想把一些包含十六进制字符串的文本提取出来,转换成二进制格式,然后输出?如果是这样的话,这段代码应该能满足你的需求。

它基本上是把原始的十六进制字符串转换成一个整数,然后把它以二进制形式(作为字节)打包成一个字符串。

你可以对输入字符串中的每个字节进行类似这样的循环处理。

撰写回答