【问题标题】:Encrypting and then decrypting same string in python在python中加密然后解密相同的字符串
【发布时间】:2020-06-03 02:40:32
【问题描述】:

问题来了:

在密码学中,简单替换密码是一种加密方法,其中短语的每个字母都被不同的字母或字母序列替换。然后可以通过执行替换的逆操作来解密该短语。

在这个问题中,我们将实现一个简单的替换密码,其中一个字符(字母、数字或特殊符号)被一个介于 00 和 99(含)之间的两位数替换。例如,字母“a”可以加密成为数字“06”,或者特殊符号“!”可以成为数字“57”。

我们将使用字典来存储每个字符与其对应的加密形式之间的映射。也就是说,字典的键将是常规字符(字母、数字和特殊符号),值将是字符的加密形式(0099 之间的两位数字)。

你的代码应该为这个问题实现以下五个函数。

  • 名称:创建密码字典

    • 参数:无参数。
    • 返回值:一个字典,其中每个键都是常规字符,每个值是 00 到 99 之间的随机两位数,包括 00 和 99。
    • 应该做什么: 在提供给您的代码的顶部,定义了字符串LETTERS。这个字符串包含所有应该在字典中作为键的字母、数字和特殊符号。您将不得不遍历这个字符串,并为每个字符生成一个介于0099 之间的两位随机数。两位数将是字典中的值;每个字符(键)都有一个两位数(值)。
    • 请注意,数字 0、1、2、...、9 不应是值;相反,它们应该是数字 00, 01, 02, ..., 09。此外,请注意每个字符都应该有一个唯一的随机数。也就是说,如果字符“a”映射到值“57”,则其他字符不应映射到值“57”。 (您需要使用某种循环来不断生成新的随机数,直到找到唯一的随机数。)
  • 名称:加密

    • 参数:字符串s
    • 返回值:字符串 s 的加密版本。原始字符串 s 的每个字符都应替换为密码字典中对应的两位数。
  • 名称:解密

    • 参数: 一个字符串s。 返回值:字符串 s 的解密版本。加密字符串 s 的每个两位数都应替换为密码字典中对应的字符。请注意,在这里,我们有加密形式(字典中的值),并且正在寻找常规字符(字典中的键 7)。为此,我们将需要使用在课堂上看到的反向查找功能。此功能已在随附的 encryption.py 文件中提供给您。

我们将编写另外两个函数来增加我们的加密强度。一个函数将多次重复加密字符串。另一个函数将尝试解密字符串,而不知道它被加密的次数(从而破坏了更强加密的要点)。

  • 名称:多次加密

    • 参数:字符串s和整数值n为字符串加密的次数。
    • 返回值:字符串s加密n次。即,字符串将第一次加密,每个字符都转换为其两位数表示。然后,加密的字符串将被重新加密,每个数字都变成它的两位数表示。 (因此,每次加密后,字符串的长度都会加倍。)(提示:您必须多次调用 encrypt 函数。)
  • 名称:多次解密

    • 参数:字符串s
    • 返回值:字符串s的解密版本。由于我们不知道要解密字符串多少次,我们将继续对字符串调用解密,直到字符串包含英语中的常用词。在 encryption.py 文件中为您提供了常用词列表 COMMON WORDS。如果在解密一次后,该字符串包含此列表中的任何单词,那么您应该立即返回解密后的字符串。否则,继续对字符串调用解密,直到它确实包含常用词之一。 (我们假设完全解密的字符串总是至少包含一个常用词。)

最后,在文件 encryption.py 的末尾,您会注意到一些已经为您编写的代码。此代码要求用户输入一个字符串,然后调用各种函数并打印它们返回的内容(以生成下面的示例)。您必须更改此代码,以便如果用户输入的字符串不包含 COMMON WORDS 列表中的任何单词,则程序应输出“无效输入”。并且不执行其余的代码。否则,程序应继续执行其余代码。 (提示:回想一下作业 1 和 if/else 分支。)

这是我尝试输入的内容:

def reverse_lookup(d,v):
    for key in d:
        if d[key]==v:
            return key
    return None

LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-=_+[]{}|;\':",./<>? '
def create_cypher_dictionary():
    random.seed(1337)
    cypher={}

    ar=[0]*100
    for c in LETTERS:
        n=random.randrange(0, 100, 1)
        while ar[n]!=0:
            n=random.randrange(0, 100, 1)
        ar[n]=1
        if n<10:
            cypher[c]=str('0')+str(n)
        else:
            cypher[c]=str(n)

    return cypher

def encrypt(s):
    cypher=create_cypher_dictionary()

    new_s=''
    for c in s:
        new_s=new_s+cypher[c]

    return new_s

def decrypt(s):
    cypher=create_cypher_dictionary()

    new_s=''
    for i in range(len(s)-1):
        c=s[i]+s[i+1]
        for cc in cypher:
            if cypher[cc]==c:
                new_s=new_s+cc

    return new_s

def encrypt_multiple_times(s,n):

    for i in range(n):
        s=encrypt(s)
    return s


COMMON_WORDS= ['the','be','to','of','and','a','in','that','have','I','it','for','not','on','with','he','as','you','do','at']

def check_common_words(s):
    for word in COMMON_WORDS:
        if word in s:
            return False
    return True

def decrypt_multiple_times(s):

    cypher=create_cypher_dictionary()
    while check_common_words(s):
        s=decrypt(s)

    return s


s=input('Enter text to encrypt:')

if check_common_words(s)==False:

    print("Encrypted string:", encrypt(s))
    print("Decrypted string:", decrypt(encrypt(s)))

    salted_s = encrypt_multiple_times(s, 2)

    print("Encrypted x2 string:", salted_s)
    print("Decrypted x2 string:", decrypt_multiple_times(salted_s))

else:
    print('Invalid input.')

这是它产生的输出:

Enter text to encrypt:The quick brown fox jumps over the lazy dog
Encrypted string:   36217337975199904937688489645037748985374251392613378908738437542173378179944437468993
Decrypted string: T0h-eK aq?u(iic,kg CbIr~o@wBn8 Jf~o>x[ fjLusm3p=sK Yocv<e/r" ?tjh-eK Yl-aizyy" fdboig
Encrypted x2 string: 9223712963929263666327296666666282669263230303820366238227629263638203660327926382712729926671232992926303666203639203829263278271296392926303296366668282829263822303666692
Decrypted x2 string: 36 21@7m313p7T997#5W1@9999990+4p9!3p7#6'8'8/4_8T906/45C013p7T7/4_8T9]8#5a3p7/4525W1i3p9N26#1i313p7'8T990_8T7m3_8/413p7#5Y4521@7m313p7'8#1@7T999b4+4+413p7/46'8T999!3

但是,它应该输出:

Enter text to encrypt: The quick brown fox jumps over the lazy dog.
Encrypted string: 0766546138001892056159999714256163973761640073940161973354996169665461919809956156975155
Decrypted string: The quick brown fox jumps over the lazy dog.
Encrypted x2 string: 3417626247536227487834342778713634476227477171717117275336 4762276248711748176227625334341748715334276227711748484753717162276271626247536227712771783471714762274762711747274747
Decrypted x2 string: The quick brown fox jumps over the lazy dog.

我真的没有想法,如果有人可以提供帮助,将不胜感激。

【问题讨论】:

  • 上面描述的不是替代密码,甚至不是密码。它是一种编码,其中字典是代码页。
  • @KlausD。我只是在转达我教授的指示。

标签: python string dictionary encryption


【解决方案1】:

你可以试试这个:

LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-=_+[]{}|;\':",./<>? '

def create_cypher_dictionary():
    numbers = [ '%02d' % i for i in range(100) ]
    random.shuffle( numbers )
    return { a : b for a,b in zip( LETTERS, numbers ) }

def encrypt( cypher, string ) :
    return ''.join( cypher[ch] for ch in string )

def decrypt( cypher, string ) :
    inverse_cypher = { b : a for a,b in cypher.items() }
    return ''.join( inverse_cypher[a+b] for a,b in zip(*[iter(string)]*2) )

检查:

>>> cypher = create_cypher_dictionary()
>>> encoded = encrypt( cypher, 'The quick brown fox jumps over the lazy dog' )
>>> encoded
'93684236886025540636378012826636001276363960074903361250428036306842367064856536261211'
>>> decrypt( cypher, encoded )
'The quick brown fox jumps over the lazy dog'
>>> 

是的,你不能每次都创建密码,你必须制作一个并重复使用它,否则你的结果会有点随机 =)

【讨论】:

    【解决方案2】:

    您一次只取一位数字而错误地转换了 ASCII,而您应该取两位数。只需在您的解密函数中更改 for 循环的步骤:

    def decrypt(s):
        cypher=create_cypher_dictionary()
    
        new_s=''
        for i in range(0,len(s)-1,2): # Make the for loop step 2 instead of 1 (default)
            c=s[i]+s[i+1]
            for cc in cypher:
                if cypher[cc]==c:
                    new_s=new_s+cc
    
        return new_s
    

    【讨论】:

      猜你喜欢
      • 2014-02-01
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      相关资源
      最近更新 更多