以发疯文学为载体,加密传输信息。
破解的前题是知道这有个东西能破解。
——沃茨基·硕德
如果你看到一串 16 进制,你会立即知道这里面是隐藏了信息的。但如果是这样呢:
本家快当被这句品竹调丝弗拉迪受援了鉏。耐烦本家打字先后座!换句话安养检控
什么加密不加密的?我只是在玩抽象,玩发疯文学。
- 这是一种古典密码,在同一段文本中,明文与密文的每个词都是一一对应的;
- 一些部分不会被加密:
- 标点符号;
- 英文和数字;
- 词库里单独占据一个词性的词(如“了”“的”);
- 词库里没有的词(如“猫娘”“男娘”“三连”)。
- 当您需要和特定的人保持秘密通信,但不宜暴露出你们的通信是被加密的(会是什么呢?);
- 欢迎补充。
我希望有一天,不再有人需要这个算法。
您应该和对方约定好完全相同的种子,这相当于秘钥。
然后在程序内根据提示操作即可。
对于更专业的解释,请查看 原理-信息密度。
简单地说,信息密度是一个用来衡量文本是否含有有效意义的量。文本越有意义,该值越低;文本越杂乱无章,该值越高。
一般来说,判定线保持默认即可。
来到设置页面,把信息密度判定线拉高,解密进程就会以为它已经成功了而停下来。
我还没做(逃
直接叉掉,简单粗暴。
主要依靠第三方库 jieba 对句子进行分词。
在 jieba 的词库文件 dict.txt 中,每行为 词语 词频 词性,依据此,我们就可以得到每个词的词性,并计算出它们出现的概率。
假设您看过一些信息论的科普视频,并且能正确理解信息熵与信息量的区别。
对于一个词语
在本程序的计算中,一段文本的总信息量仅为各单词的信息量的简单相加,并不会去考虑整段文本的总体情况。例如,“中国国足获得了世界冠军”的信息量并不会显著高于“中国乒乓球获得了世界冠军”。但是 我们的目的仅是为了鉴别一段文本是有意义的还是由杂乱无章的词拼起来的 ,所以该算法是足够且合适的。
计算时,不会考虑词库里没有的东西,它们将被直接忽略,也不会被算到单词总数里。
本程序中的信息密度为总信息量与单词数的比值,单位为 bit/词。通常,15 以下的文本就是有意义的。
您输入的字符串种子将被 SHA-256 哈希为一个整数作为基本种子,再加上程序自动调节的 偏移量 得到最终的种子用于随机数的生成。
我们将词库里的词按照词性分类,然后根据种子将每个词性的词分别打乱,建立起一一对应的映射关系,这样,每个词只会被映射到相同词性的词上。
以下为某个种子的映射表的一部分:
| 明文 | 密文 |
|---|---|
| ... | ... |
| 我们 | 那么些 |
| 中出 | 错误掺入 |
| 了 | 了 |
| 一个 | 四口 |
| 叛徒 | 估价单 |
| ... | ... |
划分句子成分,然后分别映射每个词,最后再拼起来,得到结果。
我们中出了一个叛徒 --> 我们/中出/了/一个/叛徒 --> 那么些/错误掺入/了/四口/估价单 --> 那么些错误掺入了四口估价单
如果是在解密,那就反过来映射。
加密有可能会失败,原因是对句子结构的划分前后不一致,导致对密文解密出来的结果与原文不一致。
最简单的解决方法就是更换种子。加密时,从偏移量 0 开始,程序会在您的整数种子上添加偏移量作为真正的种子来生成映射,在得到密文后会检查解密结果是否与原文一致,若不一致,就增加偏移量继续尝试;解密时,会从偏移量 0 开始向上尝试,直到找到信息密度低于特定值,即有意义的文本。
- Python 3.11
- jieba 0.42.1
- 其他
requirements.txt里要求的
core/- 加密算法的核心dictionary.py- 加载并处理词库mapping.py- 映射表生成info.py- 信息论相关encryption.py- 加密器类
gui/- 顾名思义ui_*.ui- 直接设计的页面,应由Qt Designer或FluentDesigner打开ui_*.py- 由pyuic5编译ui_*.ui得到的 Python 文件interface_*.py- 实现各个子页面的功能,进行多进程控制
main.py- 主程序入口