zoukankan      html  css  js  c++  java
  • 仿射加密

    仿射密码为单表加密的一种,字母系统中所有字母都藉一简单数学方程加密,对应至数值,或转回字母。  ——百度百科

    辗转相除法 与 寻找模逆:

     1 # Cryptomath Module
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 def gcd(a, b):
     5     # Return the GCD of a and b using Euclid's Algorithm
     6     while a != 0:
     7         a, b = b % a, a
     8     return b
     9 
    10 
    11 def findModInverse(a, m):
    12     # Returns the modular inverse of a % m, which is
    13     # the number x such that a*x % m = 1
    14 
    15     if gcd(a, m) != 1:
    16         return None # no mod inverse if a & m aren't relatively prime
    17 
    18     # Calculate using the Extended Euclidean Algorithm:
    19     u1, u2, u3 = 1, 0, a
    20     v1, v2, v3 = 0, 1, m
    21     while v3 != 0:
    22         q = u3 // v3 # // is the integer division operator
    23         v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
    24     return u1 % m
    cryptMath

    仿射密码是一种替换密码。它是一个字母对一个字母的。它的加密函数是 ,其中a和m互质,m是字母的数目。

    乘法加密的缺点是字母a总是加密到字母a,应为0乘以任何数都是0。可以再对其使用凯撒密码进行二次加密。

    注意: 在仿射加密里,密钥a数字与字符集大小必须互质。即 gcd(密钥, 符号集的大小)== 1.

    加解密步骤:

    1. 输入密钥并进行判断
    2. 得到字符在字符集里的位置,并对其计算得到密文
     1 # Affine Cipher
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 import sys, pyperclip, cryptomath, random
     5 SYMBOLS = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~""" # note the space at the front
     6 
     7 
     8 def main():
     9     myMessage = """"A computer would deserve to be called intelligent if it could deceive a human into believing that it was human." -Alan Turing"""
    10     myKey = 2023
    11     myMode = 'encrypt' # set to 'encrypt' or 'decrypt'
    12 
    13     if myMode == 'encrypt':
    14         translated = encryptMessage(myKey, myMessage)
    15     elif myMode == 'decrypt':
    16         translated = decryptMessage(myKey, myMessage)
    17     print('Key: %s' % (myKey))
    18     print('%sed text:' % (myMode.title()))
    19     print(translated)
    20     pyperclip.copy(translated)
    21     print('Full %sed text copied to clipboard.' % (myMode))
    22 
    23 
    24 def getKeyParts(key):
    25     keyA = key // len(SYMBOLS)
    26     keyB = key % len(SYMBOLS)
    27     return (keyA, keyB)
    28 
    29 
    30 def checkKeys(keyA, keyB, mode):
    31     if keyA == 1 and mode == 'encrypt':
    32         sys.exit('The affine cipher becomes incredibly weak when key A is set to 1. Choose a different key.')
    33     if keyB == 0 and mode == 'encrypt':
    34         sys.exit('The affine cipher becomes incredibly weak when key B is set to 0. Choose a different key.')
    35     if keyA < 0 or keyB < 0 or keyB > len(SYMBOLS) - 1:
    36         sys.exit('Key A must be greater than 0 and Key B must be between 0 and %s.' % (len(SYMBOLS) - 1))
    37     if cryptomath.gcd(keyA, len(SYMBOLS)) != 1:
    38         sys.exit('Key A (%s) and the symbol set size (%s) are not relatively prime. Choose a different key.' % (keyA, len(SYMBOLS)))
    39 
    40 
    41 def encryptMessage(key, message):
    42     keyA, keyB = getKeyParts(key)
    43     checkKeys(keyA, keyB, 'encrypt')
    44     ciphertext = ''
    45     for symbol in message:
    46         if symbol in SYMBOLS:
    47             # encrypt this symbol
    48             symIndex = SYMBOLS.find(symbol)
    49             ciphertext += SYMBOLS[(symIndex * keyA + keyB) % len(SYMBOLS)]
    50         else:
    51             ciphertext += symbol # just append this symbol unencrypted
    52     return ciphertext
    53 
    54 
    55 def decryptMessage(key, message):
    56     keyA, keyB = getKeyParts(key)
    57     checkKeys(keyA, keyB, 'decrypt')
    58     plaintext = ''
    59     modInverseOfKeyA = cryptomath.findModInverse(keyA, len(SYMBOLS))
    60 
    61     for symbol in message:
    62         if symbol in SYMBOLS:
    63             # decrypt this symbol
    64             symIndex = SYMBOLS.find(symbol)
    65             plaintext += SYMBOLS[(symIndex - keyB) * modInverseOfKeyA % len(SYMBOLS)]
    66         else:
    67             plaintext += symbol # just append this symbol undecrypted
    68     return plaintext
    69 
    70 
    71 def getRandomKey():
    72     while True:
    73         keyA = random.randint(2, len(SYMBOLS))
    74         keyB = random.randint(2, len(SYMBOLS))
    75         if cryptomath.gcd(keyA, len(SYMBOLS)) == 1:
    76             return keyA * len(SYMBOLS) + keyB
    77 
    78 
    79 # If affineCipher.py is run (instead of imported as a module) call
    80 # the main() function.
    81 if __name__ == '__main__':
    82     main()
    affineCipher

    测试其有多少密钥:

     1 # This program proves that the keyspace of the affine cipher is limited
     2 # to len(SYMBOLS) ^ 2.
     3 
     4 import affineCipher, cryptomath
     5 
     6 message = 'Make things as simple as possible, but not simpler.'
     7 for keyA in range(2, 100):
     8     key = keyA * len(affineCipher.SYMBOLS) + 1
     9 
    10     if cryptomath.gcd(keyA, len(affineCipher.SYMBOLS)) == 1:
    11         print(keyA, affineCipher.encryptMessage(key, message))
    affineKeyTest

    其大约有几千个密码,可暴力:

     1 # Affine Cipher Hacker
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 import pyperclip, affineCipher, detectEnglish, cryptomath
     5 
     6 SILENT_MODE = False
     7 
     8 def main():
     9     # You might want to copy & paste this text from the source code at
    10     # http://invpy.com/affineHacker.py
    11     myMessage = """U&'<3dJ^Gjx'-3^MS'Sj0jxuj'G3'%j'<mMMjS'g{GjMMg9j{G'g"'gG'<3^MS'Sj<jguj'm'P^dm{'g{G3'%jMgjug{9'GPmG'gG'-m0'P^dm{LU'5&Mm{'_^xg{9"""
    12 
    13     hackedMessage = hackAffine(myMessage)
    14 
    15     if hackedMessage != None:
    16         # The plaintext is displayed on the screen. For the convenience of
    17         # the user, we copy the text of the code to the clipboard.
    18         print('Copying hacked message to clipboard:')
    19         print(hackedMessage)
    20         pyperclip.copy(hackedMessage)
    21     else:
    22         print('Failed to hack encryption.')
    23 
    24 
    25 def hackAffine(message):
    26     print('Hacking...')
    27 
    28     # Python programs can be stopped at any time by pressing Ctrl-C (on
    29     # Windows) or Ctrl-D (on Mac and Linux)
    30     print('(Press Ctrl-C or Ctrl-D to quit at any time.)')
    31 
    32     # brute-force by looping through every possible key
    33     for key in range(len(affineCipher.SYMBOLS) ** 2):
    34         keyA = affineCipher.getKeyParts(key)[0]
    35         if cryptomath.gcd(keyA, len(affineCipher.SYMBOLS)) != 1:
    36             continue
    37 
    38         decryptedText = affineCipher.decryptMessage(key, message)
    39         if not SILENT_MODE:
    40             print('Tried Key %s... (%s)' % (key, decryptedText[:40]))
    41 
    42         if detectEnglish.isEnglish(decryptedText):
    43             # Check with the user if the decrypted key has been found.
    44             print()
    45             print('Possible encryption hack:')
    46             print('Key: %s' % (key))
    47             print('Decrypted message: ' + decryptedText[:200])
    48             print()
    49             print('Enter D for done, or just press Enter to continue hacking:')
    50             response = input('> ')
    51 
    52             if response.strip().upper().startswith('D'):
    53                 return decryptedText
    54     return None
    55 
    56 
    57 # If affineHacker.py is run (instead of imported as a module) call
    58 # the main() function.
    59 if __name__ == '__main__':
    60     main()
    affineHacker
  • 相关阅读:
    2020杭电HDU-6863多校第八场Isomorphic Strings(Hash+学到的新东西)
    CodeForces 1395C-Boboniu and Bit Operations(位运算-暴力)
    洛谷P2585&ZJOI 2006-三色二叉树(树的染色-树形DP)
    洛谷P2016-战略游戏(树的最小点覆盖-树形DP)
    洛谷P2015-二叉苹果树(树形DP)
    洛谷P1352-没有上司的舞会(树形DP)
    CSUSTOJ 4004-你真的会吃零食吗?(打表)
    在线支付--支付宝
    使用rabbitmq rpc 模式
    在kubernetes 集群运行 odoo
  • 原文地址:https://www.cnblogs.com/zhangzixian/p/10482828.html
Copyright © 2011-2022 走看看