传统加密 代码篇(附markdown笔记源码)

补一期,光学理论不写码,等于白学,随便写了点,便于自己加深理解

## Cacsar

编写一个加密解密程序实现广义Cacsar密码

广义的Caesar密码,也就是加法密码,是一种简单的加密算法,它通过将字母表中的每个字母移动固定数目的位置来进行加密。

例如,如果移动的数目是3,那么'A'就会变成'D','B'变成'E',以此类推。当到达字母表的末尾时,它会循环回到开头。

python代码


    def caesar_encrypt(text, shift):

        encrypted_text = ""

        for char in text:

            if char.isalpha():  # 检查字符是否是字母

                shifted = ord(char) + shift

                if char.islower():

                    if shifted > ord('z'):

                        shifted -= 26

                    elif shifted < ord('a'):

                        shifted += 26

                elif char.isupper():

                    if shifted > ord('Z'):

                        shifted -= 26

                    elif shifted < ord('A'):

                        shifted += 26

                encrypted_text += chr(shifted)

            else:

                encrypted_text += char  # 非字母字符不变

        return encrypted_text



    def caesar_decrypt(encrypted_text, shift):

        return caesar_encrypt(encrypted_text, -shift)



    # 使用示例

    original_text = "Hello, World!"

    shift_amount = 3



    encrypted = caesar_encrypt(original_text, shift_amount)

    decrypted = caesar_decrypt(encrypted, shift_amount)



    print("Original: ", original_text)

    print("Encrypted: ", encrypted)

    print("Decrypted: ", decrypted)

caesar_encrypt 函数用于加密文本,而 caesar_decrypt 函数则用于解密文本。

shift 参数是字母表中字母移动的数目。加密函数会遍历文本中的每个字符,如果字符是字母,就将其ASCII值加上 shift 的值,如果超出了字母表的范围,就通过减去或加上26来循环回到字母表的开头。非字母字符在加密和解密过程中保持不变。

## 仿射密码

仿射密码是一种单字母替换密码,它使用以下公式进行加密:

$$\it E(x)=(ax+b)\mod m$$

E(x) 是加密后的值。

x 是明文中字母的数值(例如,A=0, B=1, ..., Z=25)。

a 和 b是密钥,a 必须与 m互质gcd(a,m)=1

m 是字母表的大小(对于英文字母表,m=26)

解密公式是

$$D(y) = a^{-1} (y - b) \mod m$$

$$

a^{-1} \text{ 是 } a \text{ 在模 } m \text{ 下的乘法逆元,即 } a \cdot a^{-1} \equiv 1 \mod m。$$

python

 

   def find_multiplicative_inverse(a, m):

        # 使用扩展欧几里得算法找到a在模m下的乘法逆元

        def extended_gcd(a, b):

            if a == 0:

                return b, 0, 1

            else:

                gcd, x, y = extended_gcd(b % a, a)

                return gcd, y - (b // a) * x, x



        gcd, x, y = extended_gcd(a, m)

        if gcd != 1:

            raise Exception('a and m are not coprime')

        else:

            return x % m



    def affine_encrypt(text, a, b):

        encrypted_text = ""

        for char in text:

            if char.isalpha():

                shifted = ord(char.lower()) - ord('a')

                encrypted = (a * shifted + b) % 26

                encrypted_text += chr(encrypted + ord('a'))

            else:

                encrypted_text += char

        return encrypted_text



    def affine_decrypt(encrypted_text, a, b):

        inverse_a = find_multiplicative_inverse(a, 26)

        decrypted_text = ""

        for char in encrypted_text:

            if char.isalpha():

                shifted = ord(char.lower()) - ord('a')

                decrypted = (inverse_a * (shifted - b)) % 26

                decrypted_text += chr(decrypted + ord('a'))

            else:

                decrypted_text += char

        return decrypted_text



    # 使用示例

    original_text = "Hello, World!"

    key_a = 5

    key_b = 8



    encrypted = affine_encrypt(original_text, key_a, key_b)

    decrypted = affine_decrypt(encrypted, key_a, key_b)



    print("Original: ", original_text)

    print("Encrypted: ", encrypted)

    print("Decrypted: ", decrypted)

ffine_encrypt 函数用于加密文本,而 affine_decrypt 函数则用于解密文本。find_multiplicative_inverse 函数使用扩展欧几里得算法来找到 a 在模 m 下的乘法逆元。

## 加法密码进行字母频率攻击

写一个程序,无须人工干预,对加法密码实现字母频率攻击。软件按可能性大小的顺序给出可能的

明文。如果用户界面允许用户定义“给出前10个可能明文”,则更好

要实现一个对加法密码进行字母频率攻击的程序,我们需要遵循以下步骤:

频率分析:计算密文中每个字母的频率,并将其与英语字母表中字母的频率进行比较。

猜测移位:根据频率分析,猜测可能的移位量。

解密尝试:对每个猜测的移位量进行解密尝试。

评估结果:评估解密文本的质量,例如通过检查常见的英语单词来确定最可能的明文。

排序结果:根据某种标准(如卡方统计量)对可能的明文进行排序。

python

    import string

    from collections import Counter

    import re



    # 英语字母表中字母的频率

    ENGLISH_FREQ = {

        'E': 12.70, 'T': 9.06, 'A': 8.17, 'O': 7.51, 'I': 6.97, 'N': 6.75, 'S': 6.33,

        'H': 6.09, 'R': 5.99, 'D': 4.25, 'L': 4.03, 'C': 2.78, 'U': 2.76, 'M': 2.41,

        'W': 2.36, 'F': 2.23, 'G': 2.02, 'Y': 1.97, 'P': 1.93, 'B': 1.29, 'V': 0.98,

        'K': 0.77, 'J': 0.15, 'X': 0.15, 'Q': 0.10, 'Z': 0.07

    }



    def calculate_frequency(text):

        return Counter(c for c in text if c.isalpha())



    def caesar_decrypt(encrypted_text, shift):

        decrypted_text = ""

        for char in encrypted_text:

            if char.isalpha():

                shifted = ord(char) - shift

                if char.islower():

                    if shifted < ord('a'):

                        shifted += 26

                elif char.isupper():

                    if shifted < ord('A'):

                        shifted += 26

                decrypted_text += chr(shifted)

            else:

                decrypted_text += char

        return decrypted_text



    def chi_square(observed, expected):

        return sum((o * (o - e) ** 2) / e for o, e in zip(observed, expected))



    def score_text(text):

        freqs = calculate_frequency(text.lower())

        expected = {char: ENGLISH_FREQ[char] / sum(ENGLISH_FREQ.values()) for char in ENGLISH_FREQ}

        return chi_square(freqs.values(), expected.values())



    def break_caesar_cipher(encrypted_text):

        possible_shifts = range(26)

        possible_texts = [caesar_decrypt(encrypted_text, shift) for shift in possible_shifts]

        scores = [(score_text(text), text) for text in possible_texts]

        return sorted(scores, key=lambda x: x[0])



# 使用示例

encrypted_text = "Bmfs gqfbsy!"

top_n = 10



results = break_caesar_cipher(encrypted_text)

for score, text in results[:top_n]:

    print(f"Score: {score:.2f}, Text: {text}")

calculate_frequency 函数计算文本中每个字母的频率。

caesar_decrypt 函数对给定的密文进行解密,移位量为 shift。

chi_square 函数计算卡方统计量,用于评估解密文本的质量。

score_text 函数使用卡方统计量对文本进行评分。

break_caesar_cipher 函数尝试所有可能的移位量,解密密文,并根据评分对结果进行排序。

## 单表代替

写一个程序,无须人工干预,对单表代替密码实现字母频率攻击。软件按可能性大小的顺序给出可

能的明文。如果用户界面允许用户定义“给出前10个可能明文”,则更好。

单表代替密码(也称为简单替换密码)是一种密码,其中明文中的每个字母被替换为密文中的一个固定字母。要对这种密码进行频率分析,我们需要:

频率分析:计算密文中每个字母的频率,并将其与英语字母表中字母的频率进行比较。

匹配频率:将密文中频率最高的字母与英语中频率最高的字母(通常是'E')匹配,依此类推。

构建替换表:根据频率匹配构建替换表。

解密文本:使用替换表解密整个密文。

评估结果:评估解密文本的质量,例如通过检查常见的英语单词来确定最可能的明文。

排序结果:根据某种标准(如卡方统计量)对可能的明文进行排序。

python

import string

    from collections import Counter

    import itertools



    # 英语字母表中字母的频率

    ENGLISH_FREQ = {

        'E': 12.70, 'T': 9.06, 'A': 8.17, 'O': 7.51, 'I': 6.97, 'N': 6.75, 'S': 6.33,

        'H': 6.09, 'R': 5.99, 'D': 4.25, 'L': 4.03, 'C': 2.78, 'U': 2.76, 'M': 2.41,

        'W': 2.36, 'F': 2.23, 'G': 2.02, 'Y': 1.97, 'P': 1.93, 'B': 1.29, 'V': 0.98,

        'K': 0.77, 'J': 0.15, 'X': 0.15, 'Q': 0.10, 'Z': 0.07

    }



    def calculate_frequency(text):

        return Counter(c for c in text if c.isalpha())



    def decrypt_text(encrypted_text, mapping):

        decrypted_text = ""

        for char in encrypted_text:

            if char in mapping:

                decrypted_text += mapping[char]

            else:

                decrypted_text += char

        return decrypted_text



    def chi_square(observed, expected):

        return sum((o * (o - e) ** 2) / e for o, e in zip(observed, expected))



    def score_text(text):

        freqs = calculate_frequency(text.lower())

        expected = {char: ENGLISH_FREQ[char] / sum(ENGLISH_FREQ.values()) for char in ENGLISH_FREQ}

        return chi_square(freqs.values(), expected.values())



    def break_substitution_cipher(encrypted_text):

        possible_mappings = itertools.permutations(string.ascii_lowercase, 26)

        possible_texts = [decrypt_text(encrypted_text, mapping) for mapping in possible_mappings]

        scores = [(score_text(text), text) for text in possible_texts]

        return sorted(scores, key=lambda x: x[0])



    # 使用示例

    encrypted_text = "Bmfs gqfbsy!"

    top_n = 10



    results = break_substitution_cipher(encrypted_text)

    for score, text in results[:top_n]:

        print(f"Score: {score:.2f}, Text: {text}")

calculate_frequency 函数计算文本中每个字母的频率。

decrypt_text 函数使用给定的映射表解密文本。

chi_square 函数计算卡方统计量,用于评估解密文本的质量。

score_text 函数使用卡方统计量对文本进行评分。

break_substitution_cipher 函数尝试所有可能的字母映射,解密密文,并根据评分对结果进行排序。

## Hill密码

2×2 Hill密码是一种使用2×2矩阵和模运算的多字母替换密码。它使用一个密钥矩阵和一个模26的乘法逆元来加密和解密文本。

首先,我们需要定义一些辅助函数来处理模运算和矩阵操作:

python

  import numpy as np



    #找到模26下的乘法逆元

    def find_inverse(modulus, number):

        for x in range(1, modulus):

            if (number * x) % modulus == 1:

                return x

        return None



    # 模26下的矩阵乘法

    def mod_mul_matrix(a, b, mod):

        return np.dot(a, b) % mod



    # 模26下的矩阵乘法逆元

    def mod_inverse_matrix(matrix, mod):

        det = np.linalg.det(matrix)

        inv_det = find_inverse(mod, det)

        inv_matrix = np.linalg.inv(matrix) * inv_det

        return np.round(inv_matrix).astype(int)



    # 加密一对字母

    def encrypt_pair(plain_pair, key_matrix):

        return mod_mul_matrix(key_matrix, np.array(plain_pair), 26)



    # 解密一对字母

    def decrypt_pair(cipher_pair, inv_key_matrix):

        return mod_mul_matrix(inv_key_matrix, np.array(cipher_pair), 26) % 26

现在,我们可以定义加密和解密函数:




    def hill_encrypt(plain_text, key_matrix):

        encrypted_text = ""

        for i in range(0, len(plain_text), 2):

            pair = plain_text[i:i+2]

            num_pair = [ord(char) - ord('A') for char in pair]

            cipher_pair = encrypt_pair(num_pair, key_matrix)

            encrypted_text += ''.join(chr(code + ord('A')) for code in cipher_pair)

        return encrypted_text



    def hill_decrypt(cipher_text, inv_key_matrix):

        decrypted_text = ""

        for i in range(0, len(cipher_text), 2):

            pair = cipher_text[i:i+2]

            num_pair = [ord(char) - ord('A') for char in pair]

            plain_pair = decrypt_pair(num_pair, inv_key_matrix)

            decrypted_text += ''.join(chr(code + ord('A')) for code in plain_pair)

        return decrypted_text

最后,我们需要一个密钥矩阵及其逆元来测试这些函数:



    # 定义一个密钥矩阵

    key_matrix = np.array([[2, 3], [5, 7]])



    # 找到模26下的密钥矩阵逆元

    inv_key_matrix = mod_inverse_matrix(key_matrix, 26)



    # 测试加密和解密

    plain_text = "HELLO"

    cipher_text = hill_encrypt(plain_text, key_matrix)

    decrypted_text = hill_decrypt(cipher_text, inv_key_matrix)



    print("Plain Text:", plain_text)

    print("Cipher Text:", cipher_text)

    print("Decrypted Text:", decrypted_text)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值