【问题标题】:Python - Increment file by 1Python - 将文件增加 1
【发布时间】:2014-11-20 15:08:34
【问题描述】:

我有一个包含以下十六进制值的文件:

00 00 00 00 00 00 00 00

我想要做的实际上是将这个文件加一。即运行程序后,我会留下:

00 00 00 00 00 00 00 01

当我到达:

00 00 00 00 00 00 00 FF

我希望下一个增量留给我:

00 00 00 00 00 00 01 00

有没有一种简单的方法可以用字节数组或类似的东西来做到这一点?

编辑:

这有点像我之前的代码:

filename  = 'file'

with open(filename, "rb+") as file:
    seek = -1
    while True:
        file.seek(seek, 2)
        value = file.read(1).encode('hex')
        file.seek(seek, 2)
        if value != 0xFF:
            file.write(str(int(value, 16) + 0x1))
            break
        else:
            file.write(str(0x00))
            seek -= 1

它给出了……意想不到的结果。

【问题讨论】:

  • 是的,有办法做到这一点,到目前为止你有什么尝试?请发布您的代码。
  • @ SO 这里的想法是,您将尝试一些东西,发布该代码并询问我们为什么/如何失败 - 而不是“向我发送 codez”........
  • 文件是否包含 8 个字节,值为 0 还是包含字符串 "00 00 00 00 00 00 00 00"
  • 我正在把我的代码放在一起。这是我前一阵子尝试写的东西,最近才想到。
  • Matthias - 正如我原来的问题中提到的,该文件包含十六进制值 00 00 00 00 00 00 00 00

标签: python file hex byte


【解决方案1】:

如果你使用的是Python3,你可以使用int.from_bytes()int.to_bytes()

filename = 'file'

with open(filename, "rb") as data_file:
    data = data_file.read()
    length = len(data)
    data = int.from_bytes(data, 'big')

data += 1

with open(filename, "wb") as data_file:
    data = data.to_bytes(length, 'big')
    data_file.write(data)

【讨论】:

  • 完美。非常符合我的期望。
【解决方案2】:

您可以先将文件内容读取为整数,然后将整数递增,然后将整数作为十六进制写入文件

value = int('0x' + open(filename,'r').read()) value += 1 open(filename, 'w').write(str(hex(value)).replace('0x','')

【讨论】:

  • 根据我对 cme​​ts 的理解,该文件实际上并不包含这些字符; OP 只是写出(二进制)文件的十六进制转储表示。
  • @KarlKnechtel OP 在他的示例代码中有,例如,file.write(str(0x00))。我被引导认为他正在编写一个代表他的整数的字符串,逐个构建。
【解决方案3】:

如果您知道文件中的总字节数,您可以将整个内容读入bytearraybytes 对象,然后将其传递给struct.unpack()。但这不适用于大于 64 位(8 字节)的任何内容,如果字节数不是 2 的幂,则需要填充它。

在更一般的情况下,您可以使用按位运算将数字合理地简单地吸入内存:

number = 0
while True:
    next_byte = f.read(1)
    if next_byte == b'':
        break
    number <<= 8
    number |= next_byte[0]

不幸的是,将其写回并不那么简单:

import io
scratch = io.BytesIO()
while number:
    scratch.write(number & 0xFF)
    number >>= 8
data = scratch.value()[::-1]
f.write(data)

【讨论】:

  • 字节数可以变化。我想出了另一个解决方案(我稍后会发布),但我会看看你的答案,因为它似乎比我的更有效率。
【解决方案4】:

根据我之前的尝试,我想出了一个答案:

import binascii
filename  = 'file'

with open(filename, "rb+") as file:
    seek = -1
    while True:
        file.seek(seek, 2)
        value = file.read(1).encode('hex')
        file.seek(seek, 2)
        if value != 'ff':
            hb = binascii.a2b_hex("%02x" % (int(value, 16) + 0x01))
            file.write(hb)
            break
        else:
            file.write(binascii.a2b_hex('00'))
            seek -= 1

我不喜欢它,但它现在有效。

如果可能,我希望看到更好的答案? :)

【讨论】:

    【解决方案5】:

    您的 Q 并不完全清楚,但我知道您的文件最初包含 24 个字符 '0' '0' ' ' ... ' ' '0' '0' 'LF'

    如果我没记错的话,你可以从文件中读取签名作为字符串,将其传递给下面的函数,然后在任何你想要的地方写入它返回的字符串。

    def hex_incr(str):
        hl = str.split()
        num = 1
        for i, h in enumerate(hl):
            num += int(h,16)*256**(7-i)
        rep = "%016X"%(num,)
        return " ".join([rep[i:i+2] for i in range (0,16,2)])
    

    我也有一些测试

    print hex_incr("00 00 00 00 00 10 01 01")
    print hex_incr("00 00 00 00 00 00 00 FF")
    print hex_incr("00 00 00 00 00 10 FF FF")
    print hex_incr("00 00 00 00 0D 10 01 01")
    

    产生

    00 00 00 00 00 10 01 02
    00 00 00 00 00 00 01 00
    00 00 00 00 00 11 00 00
    00 00 00 00 0D 10 01 02
    

    期待已久的单线

    def hex_incr(s): return " ".join([r[i:i+2] for r in ["%016X" % (1 + int("".join(s.split()), 16),)] for i in range(0,16,2)])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 1970-01-01
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      相关资源
      最近更新 更多