Python乘法密碼

來源:互聯網
上載者:User

標籤:todo   partial   密鑰   for   world   歐幾裡得   isp   log   個數   

乘法密碼

屬於替換密碼技術的一種
乘法密碼技術的加密變換:\[ Ek(Ai)=Aj \]\[j=ik(mod n) ,gcd(k,n)=1\]

  • 0<k<n
  • kn互素,即要滿足gcd(k, n)=1,否則不存在模逆元,不能正確解密

設明文訊息為M,訊息元素為m元素下標為i;
則密文訊息為C,密文元素為c元素下標為j; \[c=i*k mod n\]

乘法密碼的密碼空間大小,即小於n且與n互素的非負整數的個數,是\(φ(n)\),\(φ(n)\)是歐拉函數。
n26字母,則與26互素的數是\[{1、3、5、7、9、11、15、17、19、21、23、25}\]

,即\(φ(n)=12\) 因此乘法密碼的密鑰空間為12
注意:k=1時 加密變換為恒等變換(即無變化)
乘法密碼也稱採樣密碼,因為密文字母表是將明文字母按照下標每隔k位取出一個字母排列而成。
例如對26個字母產生密碼錶(下標由0開始,0-25
k=9

  • 明文字母 \[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z\]
  • 數組下標 \[0 ,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 \]
  • 密文字母 \[a ,j, s, b, k, t, c, l, u, d, m, v, e, n, w, f, o, x, g, p, y, h, q, z, i, r, \]
  • 數組下標 \[0 ,9, 18, 1, 10, 19, 2, 11, 20, 3, 12, 21, 4, 13, 22, 5, 14, 23, 6, 15, 24, 7, 16, 25, 8, 17 \]

正如上所述,從下標0開始, 明文a: 0X9%26=0 -->[0]=a 明文b: 1X9%26=9 -->[9]=j
其實即是通過公式算出密文密碼錶,其意義與明文表相一一對應。

乘法密碼技術的解密變換: \[Dk(Aj)=Ai\]
\[i=jX(mod n)\]

? \(X\)為\(k\)的逆元(最小正整數)
對於正整數 kn,如果有\(kX≡1(mod n)\),那麼把這個同餘方程中\(X\)的最小正整數解叫做\(k模n\)的逆元。

由於\(k\)的取值是從\(φ(n)\) 密碼空間中獲得,則必定k 123 = 1*123+ 0*11

11 = 0*123+ 1*11 |11
2 = 1*123+ (-11)*11 |5
1 = (-5)*123+ 56*11
聰明的你, 一定看出來了吧. 對! 我們將123和11都表示成 x * 123 + y * 11 的 格式, 然後相減, 在最右側一欄寫上每次減去的被減數的倍數. 依次進行, 知道減數變為1為止. 然後我們取第三列的最下面的一個數, 再對123 模數 即得11 對123的模逆.

Python實現求逆元:

from math import floordef inverseElement(k2, Z=26):    '''    to get the inverse element for k2 % Z    '''    a = [Z, 1, 0]    b = [k2, 0, 1]    while(1):        if b[0] == 1:            break        temp = b        q = floor(a[0] / b[0])        b = [i * q for i in b]        b = [a[i] - b[i] for i in range(len(b))]        a = temp    return b[-1] % Z

完整的加密解密代碼:

# -*- coding:utf-8 -*-from math import floordef gcd(x, y):    if x < y:        t = x        x = y        y = t    if y == 0:        return x    if y != 0:        return gcd(y, x % y)    else:        # print(x)        return xdef str2num(str):    '''    TODO:transfermation between the unicode num and str    '''    strL = list(str)    numL = [ord(i) - 97 for i in strL]    return numLdef num2str(num):    numL = [i + 97 for i in num]    strL = ''.join([chr(int(i)) for i in numL])    return strLdef inverseElement(k2, Z=26):    '''    to get the inverse element for k2 % Z    '''    a = [Z, 1, 0]    b = [k2, 0, 1]    while(1):        if b[0] == 1:            break        temp = b        q = floor(a[0] / b[0])        b = [i * q for i in b]        b = [a[i] - b[i] for i in range(len(b))]        a = temp    return b[-1] % Zdef encrypted(m, k2, Z=26):    if m not in range(26):        return m    else:        return (k2 * m) % Zdef decrypted(c, k2, Z=26):    if c not in range(26):        return c    else:        return (inverseElement(k2, Z) * (c)) % Zif __name__ == '__main__':    # 加密部分    str0 = 'hello the cruel world!'    num0 = str2num(str0.lower())    num1 = [encrypted(i, 11) for i in num0]    str1 = num2str(num1)    print('密文 %s' % str1)    # 解密部分    str0 = str1    num0 = str2num(str0.lower())    num1 = [decrypted(i, 11) for i in num1]    str1 = num2str(num1)    print('明文 %s' % str1)

Python乘法密碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.