Featured image of post CTF Crypto

CTF Crypto

zyt大佬捏:horostal.github.io

Pisano 周期

2n+2 = b * un+1 + c * un

1
2
3
4
5
6
7
8
9
#sage
g = 17665922529512695488143524113273224470194093921285273353477875204196603230641896039854934719468650093602325707751568
mod = 100000007
R = BinaryRecurrenceSequence(6,1)
#计算序列的周期
cycle = R.period(mod)
print(R(g%cycle)%mod)

#output :41322239

Virgenene(维吉尼亚)

取一个长度为$x$的$key$,则在每一个长度为$x$的明文区间内,每一个字母本身都在进行凯撒式移位加密。例如选取$key$为vector,则对应数字为(21, 4, 2, 19, 14, 17),之后对明文进行加密:

1
2
3
(明文) h   e   r   e   i   s   h   o   w   i   t   w   o   r   k   s
(密钥) 21  4   2   19  14  17  21  4   2   19  14  17  21  4   2   19
(密文) c   i   t   x   w   j   c   s   y   b   h   n   j   v   m   l

那如果有密文,可以通过猜测明文前几位算出$key$,找到循环点并截取出正确的$key$,在进行解密即可。推荐一个爆破维吉尼亚的网站:https://www.guballa.de/vigenere-solver,下面是自己手撸的加解密和猜测密钥。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def encode(plaintext, key):
    li = []
    j = 0
    for i in range(len(plaintext)):
        if 'a' <= plaintext[i] <= 'z':
            li.append(chr((ord(plaintext[i]) - ord('a') + ord(key[j].lower()) - ord('a')) % 26 + ord('a')))
            j = (j + 1) % len(key)
        elif 'A' <= plaintext[i] <= 'Z':
            li.append(chr((ord(plaintext[i]) - ord('A') + ord(key[j].upper()) - ord('A')) % 26 + ord('A')))
            j = (j + 1) % len(key)
        else:
            li.append(plaintext[i])
    print(''.join(li))
    # print(''.join([chr((ord(st[i]) - ord('a') + ord(s[i % len(s)]) - ord('a')) % 26 + ord('a')) for i in range(len(st))]))

def decode(ciphertext, key):
    li = []
    j = 0
    for i in range(len(ciphertext)):
        if 'a' <= ciphertext[i] <= 'z':
            li.append(chr((ord(ciphertext[i]) - ord(key[j].lower())) % 26 + ord('a')))
            j = (j + 1) % len(key)
        elif 'A' <= ciphertext[i] <= 'Z':
            li.append(chr((ord(ciphertext[i]) - ord(key[j].upper())) % 26 + ord('A')))
            j = (j + 1) % len(key)
        else:
            li.append(ciphertext[i])
    print(''.join(li))
    # print(''.join([chr((ord(t[i]) - ord('a') - ord(s[i % len(s)]) + ord('a')) % 26 + ord('a')) for i in range(len(t))]))

def check(plaintext, ciphertext):
    t = min(len(plaintext), len(ciphertext))
    li = []
    for i in range(t):
        if 'a' <= ciphertext[i] <= 'z':
            li.append(chr((ord(ciphertext[i]) - ord(plaintext[i].lower())) % 26 + ord('a')))
        elif 'A' <= ciphertext[i] <= 'Z':
            li.append(chr((ord(ciphertext[i]) - ord(plaintext[i].upper())) % 26 + ord('A')))
        else:
            continue
    return ''.join(li)
    # ''.join([chr((ord(ciphertext[i]) - ord(plaintext[i])) % 26 + ord('a')) for i in range(t)])
最后更新于 Jun 01, 2025 16:35 +0800
小哀不是小林
使用 Hugo 构建
主题 StackJimmy 设计