RSA算法python代码

RSA加密方案

在这里插入图片描述

用到的算法:

1.快速模幂算法

def quickMod(x, n, p):
    result = 1
    while n > 0:
        if n & 1:  # 判断二进制最低位是否为1
            result = (result * x) % p
        x = (x * x) % p
        n >>= 1  # 右移一位,相当于除以2
    return result

这段代码是一个快速模幂算法,用于计算 (x^n \mod p) 的值。函数接受三个参数 x, n, p,分别代表底数、指数和模数。算法通过循环迭代的方式,将指数 n 转换为二进制形式,然后根据二进制形式逐位计算结果。具体来说,当二进制形式的 n 的最低位为 1 时,将结果 result 乘以 x 并对 p 取模;然后将 x 自乘并对 p 取模;最后将 n 右移一位(相当于除以 2)。最终得到的 result 就是 (x^n \mod p) 的值。

2.Miller-Rabin算法

def getprime():#Miller-Rabin算法
    def is_prime(n, k=5): 
        if n <= 1 or (n > 2 and n % 2 == 0):
            return False
        elif n == 2 or n == 3:
            return True

        s, d = 0, n - 1
        while d % 2 == 0:
            s, d = s + 1, d // 2

        for _ in range(k):
            a = random.randint(2, n - 1)
            x = pow(a, d, n)
            if x == 1 or x == n - 1:
                continue
            for _ in range(s - 1):
                x = pow(x, 2, n)
                if x == n - 1:
                    break
            else:
                return False
        return True

    def generate_prime(min_value, max_value, k=5):
        while True:
            n = random.randint(min_value, max_value)
            if is_prime(n, k):
                return n
    # 使用示例:
    prime = generate_prime(10**528,10**529)  # 生成一个10的16次方到10的17次方之间的素数
    print(prime)
    return prime

这段代码是一个用于生成素数的函数。它使用了Miller-Rabin算法来判断一个数是否为素数。

首先,代码定义了一个内部函数is_prime(n, k),其中n是待判断的数,k是进行Miller-Rabin算法的迭代次数。函数首先判断n是否小于等于1或者大于2且为偶数,如果是则返回False。然后判断n是否等于2或者3,如果是则返回True。

接下来,代码计算出n-1的二进制表示中最低位的1的位置s和d。然后进行k次迭代,每次迭代选择一个随机数a,计算x = a^d mod n。如果x等于1或者x等于n-1,则继续下一次迭代。否则,对x进行s-1次平方运算,如果得到的结果等于n-1,则继续下一次迭代。如果所有迭代都无法满足条件,则返回False。最后,如果所有迭代都通过了,函数返回True,表示n可能是一个素数。

接着,代码定义了另一个内部函数generate_prime(min_value, max_value, k),用于生成指定范围内的素数。函数使用一个无限循环,每次生成一个在[min_value, max_value]范围内的随机数n,并调用is_prime函数判断n是否为素数。如果是素数,则返回n。

最后,代码使用示例展示了如何使用这个函数来生成一个在10^3
到10^4之间的素数,并将结果打印出来。最后,函数返回生成的素数。

最终代码部分

但是只能加密数字,若想要加密字符则需要构造字典,可以参考这篇文章http://t.csdnimg.cn/buxyB

import math
import random
from sympy import mod_inverse

def quickMod(x, n, p):
    result = 1
    while n > 0:
        if n & 1:  # 判断二进制最低位是否为1
            result = (result * x) % p
        x = (x * x) % p
        n >>= 1  # 右移一位,相当于除以2
    return result

def RSA_encrypt(p, q, e, m):
    n = p * q
    c = quickMod(m, e, n)
    return c

def RSA_decrypt(p, q, e, c):
    n = p * q
    d = mod_inverse(e, (p-1)*(q-1))
    m = quickMod(c, d, n)
    return m

def get_e(phi_n):
    # 选择常用的e,这里以65537为例,它与大多数φ(n)互质
    # 65537是费马素数,且NIST SP800-78 Rev 1 (2007) 曾强调“不允许使用比65537更低的公钥指数e”,但PKCS#1却从未有过类似的建议。
    e = 65537
    # 确保e与φ(n)互质
    assert math.gcd(e, phi_n) == 1, "e must be coprime to phi(n)"
    return e

def getprime():#Miller-Rabin算法
    def is_prime(n, k=5): 
        if n <= 1 or (n > 2 and n % 2 == 0):
            return False
        elif n == 2 or n == 3:
            return True

        s, d = 0, n - 1
        while d % 2 == 0:
            s, d = s + 1, d // 2

        for _ in range(k):
            a = random.randint(2, n - 1)
            x = pow(a, d, n)
            if x == 1 or x == n - 1:
                continue
            for _ in range(s - 1):
                x = pow(x, 2, n)
                if x == n - 1:
                    break
            else:
                return False
        return True

    def generate_prime(min_value, max_value, k=5):
        while True:
            n = random.randint(min_value, max_value)
            if is_prime(n, k):
                return n
    # 使用示例:
    prime = generate_prime(10**3,10**4)  # 生成一个10的3次方到10的4次方之间的素数
    print(prime)
    return prime

def get_valid_input(message):
    while True:
        try:
            value = input(message)
            return value
        except ValueError:
            print("无效的输入,请重新输入一个整数。")

if __name__ == "__main__":
    m = int(get_valid_input("请输入明文: "))
    p = int(getprime())
    q = int(getprime())
    phi_n = (p - 1) * (q - 1)
    e = get_e(phi_n)
    c = RSA_encrypt(p, q, e, m)
    print("加密后的密文为:", c)
    print("解密后的明文为:", RSA_decrypt(p, q, e, c))
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值