python中素数_素数判断算法(基于python实现)

素数是只能被1与自身整除的数,根据定义,我们可以实现第一种算法。

算法一:

defisprime(n):if n < 2: returnFalsefor i in range(2,int(math.sqrt(n))+1):if n % i ==0:returnFalsereturn True

任意一个合数都可分解为素数因子的乘积,观察素数的分布可以发现:除 2,3 以外的素数必定分布在 6k (k为大于1的整数) 的两侧。6k % 6 == 0, (6k+2) % 2== 0,(6k+3) %3==0,(6k+4)%2==0,

所以2,3外的素数形式只能写成 6k+1 或 6k-1的形式。据此,我们可以缩小因子范围。

算法二:

def isprime(n):

if n == 2 or n == 3:

return True

if n % 2 == 0 or n % 3 == 0:

return False

for k in range(6,int(math.sqrt(n)) + 2, 6):

if n % (k-1) == 0 or n % (k+1) == 0:

return False

return True

建立一个大小为n的数组,初始值置为真。从2开始设置步长(length)直至n的平方根,将length*i (i > 1) 的值置为False。这就是埃拉托斯特尼筛法的基本思想。适用于筛选小于n的所有素数,算法如下:

算法三:

defisprime(n):

r= [[i,True] for i in range(1,n+1)]

r[0]= [1,False]for i in range(1,int(math.sqrt(n))):

j= i * 2 + 1

while j

r[j]= [j+1,False]

j+= i + 1

return r

费马小定理: ap-1= 1 (mod p) ,其中gcd(p,a) = 1 且 p 为素数

p为素数时等式一定成立,但使等式成立的p不一定都是素数,但非素数p数量极少,称之为伪素数。

任意大素数n可写成 n = u * 2t + 1, 其中 t 为 大于1 的整数,u为奇数。an - 1 = (au)2^t, 求出au 后,连续t次平方即可求得。

算法四:

defisprime_fourth(n):if n == 2: returnTrueif n % 2 == 0: returnFalse#若n为大于2的素数,形式可写成 n=u*(2^t) + 1, t >= 1 and u % 2 == 1

t =0

u= n - 1

while u % 2 ==0:

t+= 1u//= 2

#随机选择底数,若n为素数,gcd(a,n)==1

a = random.randint(2,n-1)#若n为素数,则a^(n-1) % n == 1;先计算 a^u % n,再连续t次平方可得

r =pow(a,u,n)if r != 1:while t > 1 and r != n-1:

r= (r*r) %n

t-= 1

if r != n - 1:returnFalsereturn True

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
和求原根的过程。 为了实现ElGamal数字签名算法,我们需要进行以下几个步骤: 1. 生成两个随机数p和g,其p是大素数,g是模p意义下的原根。 2. 选择一个私钥d,使得1 < d < p - 1。 3. 计算公钥y = g**d mod p。 4. 对原始数据进行哈希处理,得到哈希值h。 5. 选择一个随机数k,使得1 < k < p - 1,且k与p - 1互质。 6. 计算r = g**k mod p,s = (h - d * r) * k**-1 mod (p - 1)。 7. 返回数字签名(r, s)。 以下是ElGamal数字签名算法Python实现: ```python import random # 判断一个数是否为素数 def is_prime(n): if n <= 1: return False # 小于1000的素数表 primes_under_1000 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541] # 判断是否在素数表内 if n in primes_under_1000: return True # 排除一些低效的情况 if n % 2 == 0 or n % 3 == 0: return False # Miller-Rabin素性测试 s = 0 d = n - 1 while d % 2 == 0: s += 1 d //= 2 for _ in range(30): 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 # 求模p意义下的原根 def primitive_root(p): factors = [p - 1] phi = p - 1 # 分解phi for i in range(2, int(phi ** 0.5) + 1): if phi % i == 0: factors.append(i) factors.append(phi // i) # 尝试每一个数 for g in range(2, p): flag = True for factor in factors: if pow(g, phi // factor, p) == 1: flag = False break if flag: return g return None # ElGamal数字签名算法 def elgamal_sign(msg, p, g, d): h = hash(msg) while True: k = random.randint(1, p - 2) if math.gcd(k, p - 1) == 1: break r = pow(g, k, p) s = (h - d * r) * pow(k, -1, p - 1) % (p - 1) return r, s # 例子 if __name__ == '__main__': p = 11 g = primitive_root(p) d = 7 msg = 'Hello, World!' signature = elgamal_sign(msg, p, g, d) print(f'Signature: {signature}') ``` 在上述代码,我们使用了Miller-Rabin素性测试来判断一个数是否是素数,在求模p意义下的原根时,我们使用了试除法和欧拉定理。 当我们运行这段代码时,它会输出签名的r和s值。需要注意的是,在实际应用,我们需要将消息和签名一起发送给验证者,验证者会根据公钥重新计算哈希值,然后使用公钥、消息和签名进行验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值