python - 密文 Letter Freq Substitution : Comparing 2 dictionaries' dict keys by value and altering a text

标签 python dictionary substitution encryption letter

我看过类似的主题,但我找不到与我正在努力实现的目标完全相符的解决方案。

我有一个密文,需要根据每个字母在文本中出现的频率进行简单的字母替换。我已经有一个规范化文本的功能(小写,没有非字母字符,没有,计算字母出现的次数,然后得到每个字母的相对频率。字母是字典中的键,频率是值。

我在单独的字典中也有 A-Z 的预期字母频率(k=字母,v=频率),但我对接下来要做什么感到有点困惑。

我认为我需要做的是采用规范化密文、预期字母 freq dict [d1] 和密文字母 freq dict [d2] 并按如下方式迭代它们(部分伪代码):

for word in text:
    for item in word:
        for k,v in d2.items():
            if d2[v] == d1[v]:
                replace any instance of d2[k] with d1[k] in text
    decoded_text=open('decoded_text.txt', 'w')
    decoded_text.write(str('the decoded text')

在这里,我想获取文本并说“如果 d2 中的值与 d1 中的值匹配,则将文本中 d2[k] 的任何实例替换为 d1[k]”。

我意识到我一定在那里犯了一些基本的 Python 逻辑错误(我在 Python 方面相对较新),但我走在正确的轨道上吗?

提前致谢

更新:

感谢您提供的所有有用建议。我决定尝试 Karl Knechtel 的方法,并进行一些改动以适合我的代码。但是,我仍然遇到问题(完全在我的实现中)

我做了一个解码函数来获取有问题的密文文件。这会调用之前创建的计数函数,它返回一个字典(字母: float 形式的频率)。这意味着“制作大写版本”代码将不起作用,因为 k 和 v 不是 float 并且不能将 .upper 作为属性。因此,调用此解码函数会返回密文字母频率,然后是密文本身,仍然经过编码。

def sorted_histogram(a_dict):
    return [x[1] for x in sorted(a_dict.items(), key=itemgetter(1))]

def decode(filename):
    text=open(filename).read()
    cipher=text.lower()

    cipher_dict=count(filename)

    english_histogram = sorted_histogram(english_dict)
    cipher_histogram = sorted_histogram(cipher_dict)

    mapping = dict(zip(english_histogram, cipher_histogram)

    translated = ''.join(
    mapping.get(c, c)
    for c in cipher
    )
    return translated

最佳答案

您并不是真的想做您想做的事情,因为样本中字符的频率通常不会与引用数据中的确切频率分布相匹配 .您真正要做的是找到最常见 字符并将其替换为“e”,然后将其替换为“t”,依此类推。

所以我们要做的是:

  1. (我假设你已经可以完成这部分)构造一个包含密文中实际字母频率的字典。

  2. 我们定义了一个函数,该函数接受 {letter: frequency} 字典并生成按频率顺序排列的字母列表。

  3. 我们按照频率顺序在我们的引用文献(即,现在我们有一个最常见的英语字母的有序列表)和样本(类似地)中获取字母。

  4. 假设样本中最常见的字母对应于英语中最常见的字母,依此类推:我们创建了一个新词典,将第一个列表中的字母映射到第二个列表中的字母。 (我们还可以创建一个用于 str.translate 的翻译表。)我们将制作同一词典的大写和小写版本(我假设您的原始词典只有小写)并合并它们在一起。

  5. 我们使用此映射来翻译密文,单独保留其他字符(空格、标点符号等)。

因此:

# 2.
import operator
def sorted_histogram(a_dict):
  return [
    x[1] # the value
    for x in sorted(a_dict.items(), key=operator.itemgetter(1))
    # of each dict item, sorted by value (i.e. the [1] element of each item).
  ]

# 3.
english_histogram = sorted_histogram(english_dict)
cipher_histogram = sorted_histogram(cipher_dict)

# 4.
# Make the lowercase version
mapping = dict(zip(english_histogram, cipher_histogram))
# Make the uppercase version, and merge it in at the same time.
mapping.update(dict(
  (k.upper(), v.upper()) for (k, v) in zip(english_histogram, cipher_histogram)
))

# 5.
translated = ''.join( # make this list of characters, and string them together:
  mapping.get(c, c) # the mapped result, if possible; otherwise the original
  for c in cipher
)

# 6. Do whatever you want with 'translated' - write to file, etc.

关于python - 密文 Letter Freq Substitution : Comparing 2 dictionaries' dict keys by value and altering a text,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4425131/

相关文章:

python - 带有行号和列标签的 Pandas Dataframe 2D 选择

python - 无法使用请求从网页获取所有表格内容

java - 将结果集值放入 Collection 对象,然后添加到 ArrayList

regex - 使用 s///e 进行评估

python - MySQL存储和搜索文本

python - SymPy - 如何检查两项是否相等但不相同

ios - 将 NSDictionary 转换为 Json String 会导致元素重新排序

arrays - 如何返回满足给定谓词的 Dictionary 值?

r - 如何检索...的内容作为调用列表?

通过 exec 对 find 的输出进行 Bash 变量替换