代码之家  ›  专栏  ›  技术社区  ›  murgatroid99 dhg

英文文本中通常会出现哪些可打印的ASCII字符?

  •  4
  • murgatroid99 dhg  · 技术社区  · 15 年前

    我一直在努力解决 Project Euler's problem #59 有一段时间,我遇到了麻烦,因为有些问题似乎比以前的问题更模糊。

    作为背景,问题是给定的文本文件是加密文本,ASCII码保存为数字。加密方法是将3个小写字母与明文循环异或(因此是可逆的)。该问题需要将文件解密为英文文本的密钥。我应该如何限制我的输出字符集来得到答案,而不是试图筛选所有可能的明文(26^3)?

    我试过限制字母、空格和标点符号,但没有成功。

    澄清一下:我想确定,在所有可打印的ASCII字符中,哪些可以丢弃,哪些可以放在纯文本字符串中。

    5 回复  |  直到 10 年前
        1
  •  4
  •   Daniel Wedlund    15 年前

    在分析所使用的算法时,您是否尝试过两种最“基本”和最常用的工具?

    1. 分析字符的频率,并尝试将其与英语字母频率相匹配
    2. Bruteforce使用单词列表中的键,最常见的单词被“哑巴”用户用作键

    79  59  12
    2   79  35
    8   28  20
    2   3   68
    ...
    

    你必须分析每一列的频率,因为现在它们独立于键。

    Col1  Col2  Col3
    71    79    68
    2     1     1
    

    现在,如果您检查例如: http://en.wikipedia.org/wiki/Letter_frequency 你有最常见的字母,别忘了你有空格和其他字符,但我想你可以假设空格是最常见的字符。

    所以现在只是一个时间问题xor:ing the 表中最常用的字符我提供了英语中最常用的字符,看看你有没有小写字符,我发现了一个三个字母的单词,我想只有这个数据才是答案。

    祝你好运,顺便说一句,这是个好问题!

        2
  •  2
  •   Thomas Pornin    15 年前

    一个可能的解决方案是简单地假设加密文本中存在给定的三字符序列。你可以使用一个三个字母的单词,或者一个可能出现在英语文本中的三个字母的序列(例如。 " a " :两个空格之间的字母“a”)。然后简单地尝试加密文本中该序列的所有可能位置。每个位置允许您简单地重新计算密钥,然后将整个文本解密为一个文件。

    由于原始文本的长度为1201,因此需要浏览1199个文件。在这一点上,这只是一个耐心的问题,但你可以通过使用一个简单的文本搜索工具在另一个频繁的英语序列(例如。 "are" ),例如使用Unix工具 grep

    我就这么做了,不到五分钟就得到了解密文本。

        3
  •  1
  •   NickHalden    15 年前

    然而,它似乎非常类似于维格纳密码的概念。特别是在他们提到的不可破解加密中,密钥长度等于消息长度。这叫维南密码。

    here 记住,维格纳是一系列凯撒密码。

    这个问题让你很容易,因为你已经知道键长了。正因为如此,正如您所提到的,您可以通过尝试每一个3个字母的组合来简单地使用bruteforce。

    我要做的是:取一个大小合理的密文块,比如说10-20个字符,然后尝试使用暴力方法。跟踪所有似乎可以创建可理解字母序列的密钥,然后在整个密文中使用这些密钥。这样我们就可以使用明显的暴力强制方法,但不必对整个问题进行暴力强制,所以我认为您不必担心限制输出。

    也就是说,我同意在创建输出时,如果您得到一个不可打印的字符,您可能会中断循环并继续下一个键。我不会尝试任何比这更具体的东西,因为谁知道最初的信息可能有什么,永远不要对你正在处理的数据做出假设。短路这样的逻辑总是一个好主意,尤其是在实现暴力解决方案时。

        4
  •  0
  •   pauljwilliams    15 年前

    密文1包括第1、4、7、10…个数字 密文2包含第2、5、8、11…个数字 密文3包括第3、6、9、12…个数字

    现在您知道每个cyphertext都是用相同的密钥字母加密的。现在做一个标准频率分析。这应该能给你足够的线索来说明这封信是什么。

        5
  •  0
  •   Corey Ogburn    14 年前

    首先,我假设密钥与前面描述的完全一样,三个小写ASCII字母。所以我在“aaa”开始暴力强迫,然后去了“zzz”。解密时,如果任何结果字节的值小于32(空格的ASCII值,最低的“可打印”ASCII值)或高于126(颚化符“~”的ASCII值,这是ASCII中最高的可打印字符),因为32和126之外的任何值对于纯文本的英语都是无效字符。一旦有一个字节超出这个范围,我就停止解密并转到下一个可能的密钥。

    一旦我使用一个特定的密钥解密了整个消息(在通过了所有字节都是可打印字符的第一个测试之后),我就需要一种方法来验证它是否是有效的解密。我希望结果是一个简单的单词列表,没有特定的顺序或意义。通过其他密码学的经验,我想到了字母频率,最简单的是,你的平均英文单词在文本中是5个字符长。该文件包含1201个输入字节。所以这意味着平均会有240个单词。解密后,我计算了结果输出字符串中的空格数。因为projecteuler并不是平均数,所以我将空格的数量与200进行了比较,这代表了更长、更晦涩的单词。当一个输出中有超过200个空格时,我打印出解密的密钥和输出文本。唯一一个超过200个空格的输出就是答案。让我告诉你,当你看到答案时,很明显你已经找到了答案。

    需要指出的是,问题的答案不是关键。它是输出字符串的所有ASCII值的总和。这种方法也会在一分钟内解出方程,实际上,它的时间大约在3到4秒。

    推荐文章