【发布时间】:2020-06-14 05:48:01
【问题描述】:
我一直在尝试制作一个文件粉碎机,它将用一个新的随机字节覆盖任何文件的每个字节,重命名它,然后删除它。我禁用了删除以检查输出的内容,并且由于某种原因,输出文件的大小小于原始文件的大小(正好是 1 个字节的大小)。在这发生之前,它实际上变得比原始文件大小更大。我一直在搞乱代码几个小时,但还没有发现错误。是什么导致它变小了?
def shred_file(path : str, passes : int, max_filename : int):
global dir_char
valid_chars = string.ascii_letters + string.digits
valid_bytes = [ b"%c" %byte for byte in range(0x0, 0xFF+1)]
filename_len = range(1, max_filename + 1)
if(os.path.isfile(path) == True):
filesize = os.path.getsize(path)
for temp in range(0, passes):
file = open(path, "wb")
#Overwrite bytes
for i in range(0, filesize + 1):
file.seek(i)
file.write(b"%c" %random.choice(valid_bytes))
file.close()
#Rename file
new_name = str("".join(random.choices(valid_chars, k=random.choice(filename_len))))
new_path = ""
if(len(path.split(f"{dir_char}")) > 1):
new_path = f"{dir_char}".join(path.split(f"{dir_char}")[0:-1]) + f"{dir_char}{new_name}"
else:
new_path = f"{dir_char}".join(path.split(f"{dir_char}")[0:-1]) + f"{new_name}"
os.rename(path, new_path)
path = new_path
#os.remove(path)
【问题讨论】:
-
顺便说一句,对文件的写入可能会转到与原始文件不同的扇区。您并没有真正擦除数据。你需要文件系统感知工具来做到这一点。
-
@tdelaney 必须可以仅使用打开的文件句柄覆盖磁盘上的数据,否则我无法看到 GNU shred(同样可以以非 root 身份运行,无需直接访问原始块)设备)可以运行。虽然文件可能希望以
rb+模式而不是wb模式打开。 -
查看
strace,shred使用O_WRONLY|O_NOCTTY。 pythonopen模式都没有做到这一点,尽管rb+做到了O_RDWR。wb和wb+都涉及O_TRUNC,我猜这可能会导致数据被写入磁盘的其他位置。O_RDWR可能就足够了,当然os.open可以用来强制使用与shred完全相同的模式。 -
致 OP:多出一个字节是因为你的循环
range(0, filesize + 1)。对于filesize迭代,您应该只使用range(filesize)(值从0到filesize - 1)。 -
对于 OP:我不确定
valid_bytes = [ b"%c" %byte for byte in range(0x0, 0xFF+1)]做了什么,因为在我使用的 python 版本中,%不是bytes类型的对象的有效运算符,但你应该检查你正在写的项目的长度。希望它们的长度为 1,在这种情况下,您也不需要搜索。
标签: python file byte file-writing