激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python 25行代碼實現的RSA算法詳解

Python 25行代碼實現的RSA算法詳解

2021-01-29 00:39北門大官人 Python

這篇文章主要介紹了Python 25行代碼實現的RSA算法,結合實例形式詳細分析了rsa加密算法的概念、原理、相關實現技巧與注意事項,需要的朋友可以參考下

本文實例講述了Python 25行代碼實現的RSA算法。分享給大家供大家參考,具體如下:

網絡上很多關于RSA算法的原理介紹,但是翻來翻去就是沒有一個靠譜的算法實現,即使有代碼介紹,也都是直接調用JDK或者Python代碼包中的API實現,或者即使有代碼也都寫得特別爛。無形中讓人感覺RSA加密算法竟然這么高深,然后就看不下去了。還有我發現對于“大整數的冪次乘方取模”竟然采用直接計算的冪次的值,再取模,類似于(2 ^ 1024) ^ (2 ^ 1024),這樣的計算就直接去計算了,我不知道各位博主有沒有運行他們的代碼???知道這個數字有多大嗎?這么說吧,把全宇宙中的物質都做成硬盤都放不下,更何況你的512內存的電腦。所以我說他們的代碼只可遠觀而不可褻玩已。

于是我用了2天時間,沒有去參考網上的代碼重新開始把RSA算法的代碼完全實現了一遍以后發現代碼竟然這么少,25行就全部搞定。為了方便整數的計算,我使用了Python語言。為什么用Python?因為Python在數值計算上比較直觀,而Java語言需要用到BigInteger類,數值的計算都是用方法調用,所以使用起來比較麻煩。如果有同學對我得代碼感興趣的話,先二話不說,不管3X7=22,把代碼粘貼進pydev中運行一遍,是驢是馬拉出來溜溜。看不懂可以私信我,我就把代碼具體講講,如果本文章沒有人感興趣,我就不做講解了。

RSA算法的步驟主要有以下幾個步驟:

①、選擇 p、q兩個超級大的質數
②、令n = p * q。取 φ(n) =(p-1) * (q-1)。
③、取 e ∈ 1 < e < φ(n) ,( n , e )為公鑰對
④、令 ed mod φ(n) = 1,取得d,( n , d ) 為私鑰對。 利用擴展歐幾里的算法進行計算。
⑤、銷毀 p、q。密文 = 明文 ^ e mod n , 明文 = 密文 ^ d mod n。利用蒙哥馬利方法進行計算

代碼主要涉及到三個Python可執行文件:計算最大公約數、大整數冪取模算法、公鑰私鑰生成及加解密。這三個文件構成了RSA算法的核心。

前方高能,我要開始裝逼了。看不懂的童鞋請繞道,先去看看理論,具體內容如下:

1. 計算最大公約數
2. 超大整數的超大整數次冪取超大整數模算法(好拗口,哈哈,不拗口一點就顯示不出這個算法的超級牛逼之處)
3. 公鑰私鑰生成

1、計算最大公約數與擴展歐幾里得算法

gcd.py文件,gcd方法用來計算兩個整數的最大公約數。ext_gcd是擴展歐幾里得方法的計算公式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding: utf-8 -*-
# 求兩個數字的最大公約數(歐幾里得算法)
def gcd(a, b):
  if b == 0:
    return a
  else:
    return gcd(b, a % b)
'''
擴展歐幾里的算法
計算 ax + by = 1中的x與y的整數解(a與b互質)
'''
def ext_gcd(a, b):
  if b == 0:
    x1 = 1
    y1 = 0
    x = x1
    y = y1
    r = a
    return r, x, y
  else:
    r, x1, y1 = ext_gcd(b, a % b)
    x = y1
    y = x1 - a / b * y1
    return r, x, y

2、大整數冪取模算法

exponentiation.py文件,主要用于計算超大整數超大次冪然后對超大的整數取模。我在網上查詢到這個算法叫做“蒙哥馬利算法”。

?
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
# -*- coding: utf-8 -*-
'''
超大整數超大次冪然后對超大的整數取模
(base ^ exponent) mod n
'''
def exp_mode(base, exponent, n):
  bin_array = bin(exponent)[2:][::-1]
  r = len(bin_array)
  base_array = []
  pre_base = base
  base_array.append(pre_base)
  for _ in range(r - 1):
    next_base = (pre_base * pre_base) % n
    base_array.append(next_base)
    pre_base = next_base
  a_w_b = __multi(base_array, bin_array)
  return a_w_b % n
def __multi(array, bin_array):
  result = 1
  for index in range(len(array)):
    a = array[index]
    if not int(bin_array[index]):
      continue
    result *= a
  return result

有同學就不服了,說是我為啥不把這個冪次的數字計算出來,再取模。我說這樣做,理論上是對的,但是實際上行不通。因為:一個2048位的數字的2048位次的冪,計算出來了以后,這個數字很可能把全宇宙的物質都做成硬盤也放不下。不懂的童鞋請私信我。所以需要用“蒙哥馬利算法”進行優化。

3、公鑰私鑰生成

rsa.py,生成公鑰、私鑰、并對信息加密解密。

?
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
# -*- coding: utf-8 -*-
from gcd import ext_gcd
from exponentiation import exp_mode
# 生成公鑰私鑰,p、q為兩個超大質數
def gen_key(p, q):
  n = p * q
  fy = (p - 1) * (q - 1)   # 計算與n互質的整數個數 歐拉函數
  e = 3889          # 選取e  一般選取65537
  # generate d
  a = e
  b = fy
  r, x, y = ext_gcd(a, b)
  print # 計算出的x不能是負數,如果是負數,說明p、q、e選取失敗,一般情況下e選取65537
  d = x
  # 返回:  公鑰   私鑰
  return  (n, e), (n, d)
# 加密 m是被加密的信息 加密成為c
def encrypt(m, pubkey):
  n = pubkey[0]
  e = pubkey[1]
  c = exp_mode(m, e, n)
  return c
# 解密 c是密文,解密為明文m
def decrypt(c, selfkey):
  n = selfkey[0]
  d = selfkey[1]
  m = exp_mode(c, d, n)
  return m
if __name__ == "__main__":
  '''公鑰私鑰中用到的兩個大質數p,q'''
  p = 106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169
  q = 144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209
  '''生成公鑰私鑰'''
  pubkey, selfkey = gen_key(p, q)
  '''需要被加密的信息轉化成數字,長度小于秘鑰n的長度,如果信息長度大于n的長度,那么分段進行加密,分段解密即可。'''
  m = 1356205320457610288745198967657644166379972189839804389074591563666634066646564410685955217825048626066190866536592405966964024022236587593447122392540038493893121248948780525117822889230574978651418075403357439692743398250207060920929117606033490559159560987768768324823011579283223392964454439904542675637683985296529882973798752471233683249209762843835985174607047556306705224118165162905676610067022517682197138138621344578050034245933990790845007906416093198845798901781830868021761765904777531676765131379495584915533823288125255520904108500256867069512326595285549579378834222350197662163243932424184772115345
  '''信息加密'''
  c = encrypt(m, pubkey)
  print c
  '''信息解密'''
  d = decrypt(c, selfkey)
  print d

代碼就是這么簡單,RSA算法就是這么任性。代碼去除掉沒用的注釋或者引用,總長度不會超過25行,有疑問的我們掰扯掰扯。

實測:秘鑰長度在2048位的時候,我的thinkpad筆記本T440上面、python2.7環境的運行時間是4秒,1024位的時候是1秒。說明了RSA加密算法的算法復雜度應該是O(N^2),其中n是秘鑰長度。不知道能不能優化到O(NlogN)

希望本文所述對大家Python程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品视频在线观看免费 | 天天操天天干天天操 | 日韩剧情片 | 国产免费黄网 | 免费成人 | 欧美精品久久久久久久久久 | 狠狠干精品视频 | 亚洲网站在线观看视频 | 久久影院国产精品 | 国产91精品久久久久久久 | 久久精品性视频 | 国产高潮失禁喷水爽到抽搐视频 | 男女生羞羞视频网站在线观看 | 久久久综合 | 久久久久久久久久久久免费 | 国产免费一区二区三区最新不卡 | 欧美在线另类 | 成人免费毛片在线观看 | 午夜男人在线观看 | 久久性生活免费视频 | 精品欧美一区二区精品久久小说 | 亚洲人成网站免费播放 | 欧美成人一区二区三区电影 | 欧美精品成人一区二区三区四区 | 免费看真人a一级毛片 | 国产精品美女一区二区 | 黄色网战在线观看 | 在线观看国产www | 日韩免费黄色 | japan护士性xxxⅹhd | 亚洲第一成人在线视频 | 一区二区三区欧美在线观看 | 视频二区国产 | 日韩在线观看视频一区二区三区 | 黄色伊人网站 | 成人福利视频导航 | 日本黄色免费片 | 一区二区三区视频在线观看 | 精品亚洲视频在线观看 | 国产一区二区三区视频免费 | 99久久久久久久久 |