0

我正在尝试使用cryptography模块加密文件,所以我不必缓冲文件的密文,这可能是内存密集型的,然后我必须用加密的文件替换原始文件。所以我的解决方案是加密一个块明文然后尝试一次用 16 个字节的密文替换它(AES-CTR 模式)。问题似乎是循环是一个无限循环。

  • 那么如何解决这个问题。
  • 你建议的其他方法。
  • 下面使用这种方法有什么副作用。
pointer = 0
with open(path, "r+b") as file:
   print("...ENCRYPTING")
   while file:
        file_data = file.read(16)
        pointer += 16
        ciphertext = aes_enc.update(file_data)
        file.seek(pointer-16)
        file.write(ciphertext)
    print("...Complete...")
4

2 回答 2

4
  • 那么如何解决这个问题。

正如 Cyril Jouve 已经提到的,检查if not file_data

  • 你建议的其他方法。
  • 下面使用这种方法有什么副作用。

读取 16 字节的块相对较慢。我猜你有足够的内存来读取更大的块,比如 4096、8192 ...

除非您有非常大的文件和有限的磁盘空间,否则我认为在同一个文件中读写没有任何好处。如果出现错误并且操作系统已经将数据写入磁盘,您将丢失原始数据,并且将有一个不完整的加密文件,您不知道哪个部分被加密。

如果没有错误,创建一个新的加密文件然后删除并重命名会更容易和节省。

加密到新文件,捕获异常,检查加密文件的存在和大小,删除源并重命名加密文件,前提是一切正常。

import os

path = r'D:\test.dat'

input_path = path
encrypt_path = path + '_encrypt'

try:
    with open(input_path, "rb") as input_file:
        with open(encrypt_path, "wb") as encrypt_file:

            print("...ENCRYPTING")

            while True:

                file_data = input_file.read(4096)
                if not file_data:
                    break

                ciphertext = aes_enc.update(file_data)
                encrypt_file.write(ciphertext)

            print("...Complete...")

    if os.path.exists(encrypt_path):
        if os.path.getsize(input_path) == os.path.getsize(encrypt_path):
            print(f'Deleting {input_path}')
            os.remove(input_path)
            print(f'Renaming {encrypt_path} to {input_path}')
            os.rename(encrypt_path, input_path)

except Exception as e:
    print(f'EXCEPTION: {str(e)}')
于 2020-08-30T12:47:06.310 回答
1

文件对象没有“真实性”,因此您不能将其用作循环的条件。

当 read() 返回一个空字节对象(https://docs.python.org/3/library/io.html#io.BufferedIOBase.read)时,文件位于 EOF

with open(path, "r+b") as file:
   print("...ENCRYPTING")
    while True:
        file_data = file.read(16)
        if not file_data:
            break
        ciphertext = aes_enc.update(file_data)
        file.seek(-len(file_data), os.SEEK_CUR)
        file.write(ciphertext)
    print("...Complete...")
于 2020-08-30T11:04:23.540 回答