CTF常见编码
Jackie

补充

计算机中的数据都是按字节存储。一个字节(Byte)由8个二进制位组成(bit)。(组成范围是0~255(28)) 一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。

ASCII编码

ASCII 码是对英语字符与二进制位之间的关系,做了统一规定。基本的 ASCII 字符集共有 128 个字符,其中有 96 个可打印字符,包括常用的字母、数字、标点符号等。如:

空格SPACE 是32(二进制:00100000);数字0是48(二进制:00110000);大写字母A是65(二进制:01000001)

另外还有 32 个控制字符(不能打印出来)

这128个符号,只占用了一个字节的后面7位,最前面的一位统一规定为0。

特征:只含有数字

  • 0-9:49-57
  • A-Z:65-90
  • a-z:97-122
明文:hello,world.
十六进制:0x680x650x6c0x6c0x6f0xff0c0x770x6f0x720x6c0x640x2e
十进制:1041011081081112551211911111410810046
二进制:011010000110010101101100011011000110111100101100011101110110111101110010011011000110010000101110

解码链接1

解码链接2

ASCII码对照表

image

Base家族编码

base16/base32/base64/base58/base85/base100

Base16编码是将二进制文件转换成由(0-9、A-F)16个字符组成的文本

Base32编码由(A-Z、2-7)32个可见字符构成,"="符号用作后缀填充。

Base36的密文由(A-Z、0-9)36个字符组成,加密仅支持整数数字,解密仅支持字符串,不支持中文

Base64的编码表是由(A-Z、a-z、0-9、+、/)64个可见字符构成,“=”符号用作后缀填充。

Base58的编码表相比base64少了数字0,大写字母I,O,小写字母 l (这个是L),以及符号‘+’和‘/’

Base91的密文由91个字符(0-9,a-z,A-Z,!#$%&()*+,./:;<=>?@[]^_`{|}~”)组成

Base100编码/解码工具(又名:Emoji表情符号编码/解码),可将文本内容编码为Emoji表情符号;同时也可以将编码后的Emoji表情符号内容解码为文本。

明文:hello,world.123456
base16: 68656C6C6F2C776F726C642E313233343635
特征:大写字母(A-Z)和数字(0-9),不用‘=’补齐,且数字要多于字母。
base32: NBSWY3DPFR3W64TMMQXDCMRTGQ3DK===
特征:大写字母(A-Z)和数字(2-7),不满5的倍数,用‘=’补齐。
base58: 2smDFYXWKE8vc8XA8dadEYcSqcQb
特征:相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号,最主要的是后面不会出现'='。
base64: aGVsbG8sd29ybGQuMTIzNDY1
特征:大小写字母(A-Z,a-z)和数字(0-9)以及特殊字符‘+’,‘/’,不满3的倍数,用‘=’补齐。
base85: BOu!rDst>tGAhM<A1fSl1GgsI
特征:特点是奇怪的字符比较多,但是很难出现等号
base91: TPwJh>go2Tv!_,aRA2IbLmA
特征:由91个字符(0-9,a-z,A-Z,!#$%&()*+,./:;<=>?@[]^_`{|}~”)组成
不支持中文。
base100: 👟👜👣👣👦📦💳💃👮👦👩👣👛🐥🐨🐩🐪🐫🐬🐭
特征:就是一堆Emoji表情

base16 / base32 / base64

base58

base85

base91

base100

MD5、SHA1、HMAC、NTLM等类似加密型

MD5

一般MD5值是32位由数字"0-9"和字母"a-f"所组成的字符串,字母大小写统一。如果出现这个范围以外的字符说明这可能是个错误的md5值,就没必要再拿去解密了。

也有可能是MD5&Salt(discuz)

md5(md5(password).salt)

salt是一个随机的6位字符串,保存在ucenter_members表中。该表和common_member表中都存有password字段,需要注意的是,这两个表中的password字段的值是不一样的,用户在做登录的时候,实际上判断的是ucenter_members表中的密码字段,common_member表中的密码字段是没有意义的,可以任意更改。

在通过其它途径需要往论坛添加可登录用户的时候,只需要向ucenter_members表中插入数据即可登录,然后登录的时候系统会让该帐号激活,激活成功后即可登录。如果在两张表中都有插入数据的话,用户登录的时候就不需要激活,直接登录。(建议只在一张表中插入数据,激活的时候让系统自动往common_member表中插数据,避免手动插入的数据错乱。)

16位值是取的是8~24位。

特征:

有固定长度,一般是32位或者16位

由数字“0-9”和字母“a-f”组成

明文:hello,world.123456
md5(hello,world.123456,32) = 5189503aae1b1c0a6fbf7ea9e3128ab0
md5(hello,world.123456,16) = ae1b1c0a6fbf7ea9

MD5解密1

MD5解密2

SHA1

SHA1是一种密码散列函数,SHA1可以生成一个被称为消息摘要的160位,20字节的散列值,散列值通常的呈现形式为40位十六进制数。这种加密和MD5类似。

特征:

有固定长度,为40位的字符串

明文:hello,world.123456
sha1(hello,world.123456)= 0179303b8f08fbc3d16cd23a4be5828790e12375

SHA1加解密1

SHA1加解密2

HMAC

简述:

HMAC(Hash-based Message Authentication Code)常用于接口签名验证,这种算法就是在前两种加密的基础上引入了秘钥,而秘钥又只有传输双方才知道,所以基本上是破解不了的。

特征:

和MD5类似,但是有秘钥。

HAMC加解密

NTLM

这种加密是Windows的哈希密码,是Windows NT早期版本的标准安全协议。与它相同的还有Domain Cached Credentials(域哈希)。

NTML加解密

类似加密穷举

# 算法 长度
1 md5 32/16
2 sha1 40
3 sha256 64
4 sha512 128
5 adler32 8
6 crc32 8
7 crc32b 8
8 fnv132 8
9 fnv164 16
10 fnv1a32 8
11 fnv1a64 16
12 gost 64
13 gost-crypto 64
14 haval128,3 32
15 haval128,4 32
16 haval128,5 32
17 haval160,3 40
18 haval160,4 40
19 haval160,5 40
20 haval192,3 48
21 haval192,4 48
22 haval192,5 48
23 haval224,3 56
24 haval224,4 56
25 haval224,5 56
26 haval256,3 64
27 haval256,4 64
28 haval256,5 64
29 joaat 8
30 md2 32
31 md4 32
32 ripemd128 32
33 ripemd160 40
34 ripemd256 64
35 ripemd320 80
36 sha224 56
37 sha3-224 56
38 sha3-256 64
39 sha3-384 96
40 sha3-512 128
41 sha384 96
42 sha512/224 56
43 sha512/256 64
44 snefru 64
45 snefru256 64
46 tiger128,3 32
47 tiger128,4 32
48 tiger160,3 40
49 tiger160,4 40
50 tiger192,3 48
51 tiger192,4 48
52 whirlpool 128
53 mysql 老MYSQL数据库用的,16位,且第1位和第7位必须为0-8
54 mysql5 40
55 NTLM 32
56 Domain Cached Credentials 32

埃特巴什码

一种古老的加密技术,属于简单替换密码的范畴。其基本原理是,在字母表中,每一个字母都被替换为其在字母表中的对称字母。

埃特巴什码在线解密

AES、DES、RC4、Rabbit、3DES型加密

简述:

以上都是非对称性加密算法,就是引入了密钥,密文特征与Base64类似。

非对称加密

Rabbit加密开头部分通常为U2FsdGVkX

Unicode编码

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。

它用两个字节来编码一个字符,字符编码一般用十六进制来表示。

明文:hello,world.
&#x [hex]:&#x0068;&#x0065;&#x006C;&#x006C;&#x006F;&#xFF0C;&#x0077;&#x006F;&#x0072;&#x006C;&#x0064;&#x002E;

&# [hex]:&#00104;&#00101;&#00108;&#00108;&#00111;&#65292;&#00119;&#00111;&#00114;&#00108;&#00100;&#00046;

\u [hex]:\U0068\U0065\U006C\U006C\U006F\U002C\U0077\U006F\U0072\U006C\U0064\U002E

\u+ [hex]:\U+0068\U+0065\U+006C\U+006C\U+006F\U+FF0C\U+0077\U+006F\U+0072\U+006C\U+0064\U+002E

unicode16进制

unicode

常见\u方式

HTML实体编码

字符实体是用一个编号写入HTML代码中来代替一个字符,在使用浏览器访问网页时会将这个编号解析还原为字符以供阅读。

明文:hello,world.
十进制:&#104;&#101;&#108;&#108;&#111;&#65292;&#119;&#111;&#114;&#108;&#100;&#46;
十六进制:&#x68;&#x65;&#x6C;&#x6C;&#x6F;&#xFF0C;&#x77;&#x6F;&#x72;&#x6C;&#x64;&#x2E;

HTML实体加解密1

HTML实体加解密2

Escape、Unescape编码(%u)

Escape/Unescape加密解码/编码解码,又叫%u编码,其实就是字符对应UTF-16 16进制表示方式前面加%u。

Unescape解码/解密就是去掉"%u"后,将16进制字符还原后,由utf-16转码到自己目标字符。如:字符"中",UTF-16BE是:“6d93”,因此Escape是“%u6d93”,反之也一样。

明文:hello,world.
密文:%u0068%u0065%u006c%u006c%u006f%uff0c%u0077%u006f%u0072%u006c%u0064%u002e

Escape编码/解码

URL编码

url编码又叫百分号编码,是统一资源定位(URL)编码方式。URL地址(常说网址)规定了常用地数字,字母可以直接使用,另外一批作为特殊用户字符也可以直接用(/,:@等),剩下的其它所有字符必须通过%xx编码处理。现在已经成为一种规范了,基本所有程序语言都有这种编码,如js:有encodeURL、encodeURIComponent,PHP有 urlencode、urldecode等。编码方法很简单,在该字节ascii码的的16进制字符前面加%如空格字符,ascii码是32,对应16进制是20,那么urlencode编码结果是:%20。

URL加解密

Hex编码

Hex全称是Intel HEX。Hex文件是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。

特征:

十六进制(Hexadecimal)

由0-9,A-F组成,字母不区分大小写

与10进制的对应关系是:0-9不变,A-F对应10-15

明文:hello,world.
密文(带%):%68%65%6c%6c%6f%ef%bc%8c%77%6f%72%6c%64%2e
密文(不带%):68656C6C6FEFBC8C776F726C642E

不带%

带%

文本隐藏加密

特征:

加密过的密文会比原文的字节数多,当你按删除键的时候会发现某一处要按好多下才能把前面的字删掉

原理:

在密文中加入了不可见字符组成的编码,例如上述看似九个字符的一句话,通过字数查询可知它实际上有87个字符,多出的字符是由零宽空格实现的编码,因为零宽空格不占据空间,所以看不出它的存在。

在进行文本隐藏加密时,将需要隐藏的文字写在括号中,就像这样“你好(有才华),我好喜欢你(画的画)!”,然后加密即可隐藏括号内的文字。同时可以设定一个密码,这样只有知道密码的人才能解密隐藏的文字。密码可以是数字、字母和下划线,最多九位。

文本隐藏加密

零宽隐写

特征:

解密后明文与密文会分开显示,密文一般隐藏在第一个字后面

这里加密过的密文在文本隐藏加密中解不出来

零宽隐写

js专用加密

JS颜文字加密

特征:

一堆颜文字构成的js代码,在F12中可直接解密执行

JS颜文字加密

解密在F12的console中

Jother编码

jother是一种运用于javascript语言中利用少量字符构造精简的匿名函数方法对于字符串进行的编码方式。

特征:

只用**!+()[]{}**这八个字符就能完成对任意字符串的编码。可在F12中解密执行

Jother

JSFuck编码

特征:

与jother很像,只是少了{}

JSFuck加密

解密在F12的console中

Quoted-printable编码

它是多用途互联网邮件扩展(MIME)一种实现方式。有时候我们可以邮件头里面能够看到这样的编码。

特征:

任何一个8位的字节值可编码为3个字符:一个等号"="后跟随两个十六进制数字(0–9或A–F)表示该字节的数值。

明文:天上掉下了个猪八戒
密文:=E5=A4=A9=E4=B8=8A=E6=8E=89=E4=B8=8B=E4=BA=86=E4=B8=AA=E7=8C=AA=E5=85=AB=E6=88=92

在线编码

XXencode

XXencode将输入文本以每三个字节为单位进行编码。如果最后剩下的资料少于三个字节,不够的部分用零补齐。这三个字节共有24个Bit,以6bit为单位分为4个组,每个组以十进制来表示所出现的数值只会落在0到63之间。以所对应值的位置字符代替。

特征:

字符范围是:0-9,A-Z,a-z一共64个字符。

跟base64打印字符相比,就是UUencode多一个"-“字符,少一个”/"字符。

明文:hello,world.
密文:BO4JgP4yXf5RjQalY9U++

UUencode加解密

UUencode

UUencode是一种二进制到文字的编码,最早在unix邮件系统中使用,全称:Unix-to-Unix encoding,UUencode将输入文本以每三个字节为单位进行编码,如果最后剩下的资料少于三个字节,不够的部份用零补齐。三个字节共有24个Bit,以6-bit为单位分为4个组,每个组以十进制来表示所出现的字节的数值。这个数值只会落在0到63之间。然后将每个数加上32,所产生的结果刚好落在ASCII字符集中可打印字符(32-空白…95-底线)的范围之中。

明文:hello,world.
密文:,:&5L;&\L=V]R;&0N

UUencode1

UUencode2

aaencode编码

特征:

将JS代码转换成常用的网络表情

aaencode1

aaencode2

aaencode3

jjencode编码

特征:

将JS代码转换成只有符号的字符串。

jjencode加密

jjencode解密

brainfuck编码

Brainfuck是一种极小化的计算机语言,按照"Turing complete(完整图灵机)"思想设计的语言,它的主要设计思路是:用最小的概念实现一种"简单"的语言。

特征:

BrainFuck语言只有八种符号,所有的操作都由这八种符号 (> < + - . , [ ]) 的组合来完成。

明文:hello,world.
密文:+++++ +++++ [->++ +++++ +++<] >++++ .---. +++++ ++..+ ++.<+ +++++ ++[->
----- ---<] >---. <++++ ++++[ ->+++ +++++ <]>++ +++++ ++++. ----- ---.+
++.-- ----. ----- ---.< +++++ ++[-> ----- --<]> ----- .<

Brainfuck1

Brainfuck2

Ook!编码

它与Brainfuck完全相同,只是说明被改成了Orangutan单词。它代表了一长串Brainfuck命令替换中的第一个。因此,它是TrivialBrainfuckSubstitution编程语言家族的一员。

Ook!

摩斯电码

摩尔斯电码(Morse Code)是由美国人萨缪尔·摩尔斯在1836年发明的一种时通时断的且通过不同的排列顺序来表达不同英文字母、数字和标点符号的信号代码,摩尔斯电码主要由以下5种它的代码组成:

  1. 点(.)
  2. 划(-)
  3. 每个字符间短的停顿(通常用空格表示停顿)
  4. 每个词之间中等的停顿(通常用/划分)
  5. 以及句子之间长的停顿
A .- B -… C -.-. D -… E . F …-. G –. H …. I … J .—
K -.- L .-… M – N -. O — P .–. Q –.- R .-. S … T -
U …- V …- W .– X -…- Y -.– Z –… 0 —– 1 .—- 2 …— 3 …–
4 ….- 5 …… 6 -…. 7 –… 8 —… 9 —-. . .-.-.- , –…– ? …–… - -….-
= -…- : —… ; -.-.-. ( -.–. ) -.–.- / -…-. “ .-…-. $ …-…- ‘ .—-. ¶ .-.-…
_ …–.- @ .–.-. ! —. ! -.-.– + .-.-. ~ .-… # …-.- & . … ⁄ -…-.

特征:

由 . - “空格” / 表示。

莫斯电码1

莫斯电码2

社会主义编码

特征:

字符全部是社会主义核心价值观。

社会主义编码

与佛论禅

特征:

密文以"佛曰:"开头,密文一般是与关佛经的汉字

与佛论禅

新与佛论禅

新约佛论禅加密算法,简称"新佛曰"。相较于佛曰算法而言,在链接加密方面拥有更高的压缩率。

特征:

密文以"新佛曰:"开头,密文一般是与关佛经的汉字

新与佛论禅

百家姓暗号

百家姓

卡尔达诺栅格码

特征:

把明文伪装成垃圾邮件

解密

文本加密为汉字

解密

汉信码

汉信码与现有二维码相比较,具有如下特点:

  • 汉字编码能力强:支持GB18030中规定的160万个汉字信息字符,采用12位二进制数进行表示,在现有的二维码中表示汉字效率最高。

  • 信息容量大:最多可表示7829个数字、4350个ASCII字符、2174个汉字、3262个8位字节信息

  • 编码范围广:可以对照片、指纹、掌纹、签字、声音、文字等数字化信息进行编码。

  • 抗污损、抗畸变识读能力强:能够容忍较大面积的符号污损,特别适合在恶劣条件下使用。

  • 具备纠错能力:具备四种纠错等级:8%、15%、23% 、30%,不输QR码。

  • 识读速度快:汉信码的识读速度比国际上的主流二维码DataMatrix还要高。

image

汉信码

Whitespace加密

大多数的编程语言都会忽略代码中的空白字符,"Whitespace"是专门来弥补普通编程语言,它给予这些空白字符最重要的地位。

在"Whitespace"编程语言中,任何非空白的字符都是被忽略的,只有空格符、tab和换行符被认为是有效的语义字符。

Whitespace

后端代码加密

PHP:乱码,头部有信息

.NET:DLL封装代码文件(dnSpy、ILSpy)

JAVA:JAR&CLASS文件

举例:Zend ILSpy IDEA

应用场景:版权代码加密,开发特性等

Poem Code

链接

加密原理

  1. 选诗歌和关键词

首先,选好一首诗,不要求完整,可以只是片段。PoemCode加密本质上只是想在这首诗里找几个词作为关键词,为后面的加密做准备

选一首《Right Here Waiting》的歌词做加密用的诗歌,再选几个关键词(下面标成黄色的):

Oceans apart day after day

And I slowly go insane

I hear your voice on the line

But it doesn’t stop the pain

If I see you next to never

How can we say forever

  1. 给关键词的每个字母标号
  • 把所有关键词按照在诗歌中出现的顺序排在一起,中间不要空格,如下:
d a y s l o w l y h e a r l i n e
  • 按照字母表的顺序,从a开始,用1,2,…依次给每个字母编号(注意:相同的字母按从左到右的顺序依次标号)

    先标a

d a y s l o w l y h e a r l i n e
1 2

没b,c就到d:

d a y s l o w l y h e a r l i n e
3 1 2

再到e:

d a y s l o w l y h e a r l i n e
3 1 4 2 5

最后结果:

d a y s l o w l y h e a r l i n e
3 1 16 14 8 12 15 9 17 6 4 2 13 10 7 11 5
  1. 密文对号入座

    设我们要传的密文是:Remember me though I have to say goodbye.

    1. 去掉空格和特殊符号

      很多时候,还会统一大小写

      明文经过这一步处理得到的是:remembermethoughihavetosaygoodbye

    2. 对号入座

      首先,看关键词一共有多少个字母,day:3个,slowly:6个,hear:4个,line:4个,一共17个。

      这个从上一步的标号也可以看出,因为标号最大是17

      创建一个这样的表格,列数为字母个数,分别标上1-17,再把需要加密的内容从左到右,从上到下依次放进去。如果最后一行没满,就随机填充字母,一般都默认用abcdef…下面第二行最后那个a就是填充字符

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
r e m e m b e r m e t h o u g h i
h a v e t o s a y g o o d b y e a
  1. 明文转密文

    用上面每列字母去代替关键词(dayslowlyhearline)中相应标号的字母,即:

    关键词中第一个字母(d)的标号是3,那我们就用第3列的mv取代之

    关键词中第二个字母(a)的标号是1,那我们就用第1列的rh取代之

    关键词中第三个字母(y)的标号是16,那我们就用第16列的he取代之

    以此类推

    原本的关键词就会被替换成:mvrhheubrahogymyiaboeeeaodegestomt

    一般习惯把密文以4个字母为一组分块(PS:几个字母一组不影响解密,但是每块里面的字母个数必须可以被总数整除,否则最后一块就缺了)

    此例中,有17列,2行,所以字母总数是34,选2为因子分组

    分块后就长这样:mv rh he ub ra ho gy my ia bo ee ea od eg es to mt

  2. 添加密钥

    要让对方收到你的密文之后可以解密,别忘了还得告诉他你选了哪几个关键词

    实现方法就是在上面分好块的密文前面再加上一块字母

    这块字母的个数为关键词的个数,与密文每块字母的个数无关

    这块字母在字母表中的顺序就代表关键词在诗歌中的顺序

    比如acm代表选择了诗歌中的第1、第3和第13个单词作为关键词。此例中,day是第3个词,slowly是第8个词,hear是第12个词,line是第17个词,所以加上的字母块就是chlq

    接收方收到的密文就是: chlq mv rh he ub ra ho gy my ia bo ee ea od eg es to mt


    如果选了大于字母表中的字母个数个词作为关键词,模26

    例如选第33个词作为关键词,用第33%26=7个字母,也就是’g’来表示

解密原理

收到的诗歌+密文如下

Oceans apart day after day
And I slowly go insane
I hear your voice on the line
But it doesn't stop the pain
If I see you next to never
How can we say forever

cypher text: chlq mv rh he ub ra ho gy my ia bo ee ea od eg es to mt
  1. 根据第一块字母提取出关键词

    第一块字母为:chlq,在字母表中的顺序分别为:3,8,12,17,诗歌中一共有35个单词,所以

    第一个关键词可能是第3个词“day”,也可能是第3+26=29个词“to”

    第二个关键词可能是第8个词“slowly”,也可能是第8+26=34个词“say”

    第三个关键词只可能是第12个词“hear”,因为诗歌没有第12+26=38个单词

    第四个关键词只可能是第17个词“line”,因为诗歌没有第17+26=43个单词

    综上,关键词的组合有2 *2 *1 *1=4种

  2. 筛选可能的关键词组合

    根据上一步得到四种关键词组合:1.dayslowlyhearline 2.daysayhearline 3.toslowlyhearline 4.tosayhearline

    为方便讲述,定义几个量:

    CN=明文数据字母数+填充数据字母数
    KN=关键词字母数

    密文除了第一块表示密钥,后面都是经加密的明文数据+填充数据。所以根据3.2中的表格和2.2节我们知道:

    KN*行数=CN,即CNKN的倍数

    上面例子中密文内容除掉提示关键词的chlq,剩下的经加密的明文数据+填充数据一共有34个字母(CN=34),为mv rh he ub ra ho gy my ia bo ee ea od eg es to mt

    意味着,所有的关键词的字母加起来的个数(KN),应该可以被34整除
    一个个来看刚刚的4个组合:
    第一个,dayslowlyhearlineKN=17,17可以被34整除,可能是解密的关键词组合
    第二个,daysayhearlineKN=14,14不可以被34整除,所以这不是解密的关键词组合
    第三个,toslowlyhearlineKN=15,15不可以被34整除,所以这不是解密的关键词组合
    第四个,tosayhearlineKN=13,13不可以被34整除,所以这不是解密的关键词组合

  3. 给筛选出来的关键词字母标号

    标号规则和加密的步骤2一样,得到的结果如下:

d a y s l o w l y h e a r l i n e
3 1 16 14 8 12 15 9 17 6 4 2 13 10 7 11 5
  1. 找到密文和标号的对应关系

    1. KN为列数,列的标号顺序同关键词字母标号顺序,CN/KN为行数,列一个表格如下
3 1 16 14 8 12 15 9 17 6 4 2 13 10 7 11 5
  1. 把密文从左到右按列的填入(不用管标号)

    密文:mv rh he ub ra ho gy my ia bo ee ea od eg es to mt

3 1 16 14 8 12 15 9 17 6 4 2 13 10 7 11 5
m r h u r h g m i b e e o e e t m
v h e b a o y y a o e a d g s o t
  1. 将表格列数标号从小到大重排
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
r e m e m b e r m e t h o u g h i
h a v e t o s a y g o o d b y e a
  1. 按行读取得到明文

解密代码

需要两个参数:

  1. 诗歌的路径,诗歌文本要去掉逗号之类的特殊字符,但空格不能去掉
  2. 密文的路径,密文文本要去掉前面冗余的数据(比如"cypher text:"),只留下密文内容
import sys
import itertools
import re
from os import listdir
from os.path import isfile, join
# modified by Clover on 2022/05/23
abc='abcdefghijklmnopqrstuvwxyz'

def loadlist(infile):
tlist = []
for line in open(infile,'r'):
for w in line.split(): tlist.append(w.lower())
return tlist


def decrypt(poem, cip):
# Load all words of the poem into a temporary list
twords = loadlist(poem)

# Load all cipher chunks of the ciphertext into a list
cwords = loadlist(cip)

# Get the code rom the first chunk and remove it from the ciphertext list
code = []
for i in cwords.pop(0): #get keywords tips
code.append(abc.index(i))
# Select only those words specified in the code in a new multi-arrayed list
xwords = [[] for x in range(len(code))]
for xcount, c in enumerate(code):
tlen = c
while(c<len(twords)):
xwords[xcount].append(twords[c].lower())
c+=26

# Get all possible combinations
CN=len(cwords)*len(cwords[0])
for comb in itertools.product(*xwords):
pwords = ''
for c in comb: pwords+=c
KN = len(pwords)
if CN%KN!=0 : continue

#re-devide the cyber text by CN/KN
c_text=''
for i in range(0,len(cwords)):
c_text+=cwords[i]

c_text_list = re.findall(r'\w{'+str(CN/KN)+'}', c_text)

# Rearrange the chunks according to the key
pcode = [None] * KN#len of pcode is equal to the numbers in keywords group
count = 0
while(count<KN):
for al in abc:
for pc, pl in enumerate(pwords):

if al!=pl: continue
pcode[count]=c_text_list[pc]#put cyber-text blocks in the right position
count+=1

# Decrypt the ciphertext
msg = ''
for c in range(0, CN/KN):
for word in pcode:
msg+=word[c]
print msg

# first argument = poem
# second argument = ciphertxt or msg
if len(sys.argv) != 3: sys.exit(2)

decrypt(sys.argv[1], sys.argv[2])
 评论
评论插件加载失败
正在加载评论插件