我正在尝试对文件进行匿名化,以便将除某些关键字之外的所有内容替换为乱码,但格式保持不变(包括标点符号、字符串长度和大小写)。例如:
I am testing this, check it out! This is a keyword: long
Wow, another line.
应该变成:
T ad ehistmg ptrs, erovj qo giw! Tgds ar o qpyeogf: long
Yeg, rmbjthe yadn.
我正在尝试在 python 中执行此操作,但我没有找到解决方案。我尝试过通过标记化进行替换并写入另一个文件,但没有取得太大成功。
最佳答案
首先让我们忽略我们必须保留一些关键字的事实。我们稍后会解决这个问题。
执行这种一对一映射的最简单方法是使用方法 str.translate
。 string
模块还包含包含所有 ASCII 小写和大写字符的常量,以及 random.shuffle
可用于获得随机排列。
import string
import random
random_caps = list(string.ascii_uppercase)
random_lows = list(string.ascii_lowercase)
random.shuffle(random_caps)
random.shuffle(random_lows)
all_random_chars = ''.join(random_lows + random_caps)
translation_table = str.maketrans(string.ascii_letters, all_random_chars)
with open('the-file-i-want.txt', 'r') as f:
contents = f.read()
translated_contents = contents.translate(translation_table)
with open('the-file-i-want.txt', 'w') as f:
f.write(translated_contents)
在 python 2 中 str.maketrans
是 string
模块中的函数,而不是 str
的静态方法。
translation_table
是一种从字符到字符的映射,因此它将每个 ASCII 字符映射到另一个字符。 translate
方法只是将此表应用于字符串中的每个字符。
重要说明:上述方法实际上可逆,因为每个字母都映射到唯一的其他字母。这意味着通过对符号频率进行简单分析就可以逆转它。
如果您想让这变得更困难或不可能,您可以为每一行重新创建 translation_table
:
import string
import random
random_caps = list(string.ascii_uppercase)
random_lows = list(string.ascii_lowercase)
with open('the-file-i-want.txt', 'r') as f:
translated_lines = []
for line in f:
random.shuffle(random_lows)
random.shuffle(random_caps)
all_random_chars = ''.join(random_lows + random_caps)
translation_table = str.maketrans(string.ascii_letters, all_random_chars)
translated_lines.append(line.translate(translation_table))
with open('the-file-i-want.txt', 'w') as f:
f.writelines(translated_lines)
另请注意,您可以逐行翻译并保存文件:
with open('the-file-i-want.txt', 'r') as f, open('output.txt', 'w') as o:
for line in f:
random.shuffle(random_lows)
random.shuffle(random_caps)
all_random_chars = ''.join(random_lows + random_caps)
translation_table = str.maketrans(string.ascii_letters, all_random_chars)
o.write(line.translate(translation_table))
这意味着您可以使用此代码翻译大文件,只要行本身不是太长。
<小时/>上面的代码混淆了所有个字符,没有考虑这些关键字。
处理该要求的最简单方法是简单地检查每一行是否出现某个关键字并将其“重新插入”:
import re
import string
import random
random_caps = list(string.ascii_uppercase)
random_lows = list(string.ascii_lowercase)
keywords = ['long'] # add all the possible keywords in this list
keyword_regex = re.compile('|'.join(re.escape(word) for word in keywords))
with open('the-file-i-want.txt', 'r') as f, open('output.txt', 'w') as o:
for line in f:
random.shuffle(random_lows)
random.shuffle(random_caps)
all_random_chars = ''.join(random_lows + random_caps)
translation_table = str.maketrans(string.ascii_letters, all_random_chars)
matches = keyword_regex.finditer(line)
translated_line = list(line.translate(translation_table))
for match in matches:
translated_line[match.start():match.end()] = match.group()
o.write(''.join(translated_line))
<小时/>
示例用法(使用保留关键字的版本):
$ echo 'I am testing this, check it out! This is a keyword: long
Wow, another line.' > the-file-i-want.txt
$ python3 trans.py
$ cat output.txt
M vy hoahitc hfia, ufoum ih pzh! Hfia ia v modjpel: long
Ltj, fstkwzb hdsz.
注意long
是如何保留的。
关于python - 迭代文件并替换字符串,保持字符数不变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38059397/