【问题标题】:Python: decrypt caesar cipherPython:解密凯撒密码
【发布时间】:2020-06-02 11:24:18
【问题描述】:

作业:

编写一个脚本,输入一行加密文本和一个距离值,并使用凯撒密码输出明文。

我的问题:

它正在打印 hello^3 world^2

我不完全确定为什么。我将不胜感激任何和所有帮助修复或理解我的代码中的错误。 (这不是为成绩分配的,即没有截止日期为了我自己的利益

它希望我能够使用的输入及其各自的:

Lipps${svph%4

Jhss'tl'Pzothls57

Zu&hk2&ux&tuz&zu&hk2

khoor#zruog$3

我的代码:

code = input("enter coded text: ") 
distance = int(input("enter value: ")) 
plainText = "" 
for ch in code: 
  ordvalue = ord(ch) 
  ciphervalue = ordvalue - distance 
  if ciphervalue < ord('a'): 
    ciphervalue = ord('z') - \
      (distance - (ord('a')-ordvalue - 1))
  plainText += chr(ciphervalue) 
print(plainText)

【问题讨论】:

  • code = input("输入编码文本:") distance = int(input("输入值:")) plainText = "" for ch in code:ordvalue = ord(ch) ciphervalue = ordvalue - 距离如果密码值
  • edit您的问题包含您的代码。您可以使用我评论中的链接或您问题下的链接。在评论中,调试你的 python 代码几乎是不可能的。
  • 另外,我会把它留给更多专家,但我认为encryption 标签应该用于真正的加密。凯撒密码太原始了,不符合这个条件。它让我想起了关于 IBM 最常用的加密方法的老笑话:EBCDIC :-)

标签: python encryption caesar-cipher


【解决方案1】:

首先,您应该将输入/输出与处理分离,因为您的代码将更容易测试:

def cipher(code, distance):
    plainText = ""
    for ch in code:
        ordvalue = ord(ch)
        ciphervalue = ordvalue - distance
        if ciphervalue < ord('a'):
            ciphervalue = ord('z') - (distance - (ord('a')-ordvalue - 1))
        plainText += chr(ciphervalue)
    return plainText

code = input("enter coded text: ")
distance = int(input("enter value: "))
print(cipher(code, distance))

现在,你有:

>>> cipher("Lipps${svph%", 4)
'\x8aello²world±'

我猜你期待像“Hello world!”这样的东西。如果您删除这两行,就会得到这样的结果:

if ciphervalue < ord('a'):
    ciphervalue = ord('z') - (distance - (ord('a')-ordvalue - 1))

看:

def cipher2(code, distance):
    plainText = ""
    for ch in code:
        ordvalue = ord(ch)
        ciphervalue = ordvalue - distance
        plainText += chr(ciphervalue)
    return plainText

>>> cipher2("Lipps${svph%", 4)
'Hello world!'
>>> cipher2("Jhss'tl'Pzothls5", 7)
'Call me Ishmael.'
>>> cipher2("Zu&hk2&ux&tuz&zu&hk", 6) # was 2, but I guess it's 6
'To be, or not to be'
>>> cipher2("khoor#zruog$", 3)
'hello world!'

这是问题的有趣部分。但我认为您的直觉是正确的:当生成的 ordvalue 值不在预期范围内(即负数或大)时会发生什么?

>>> cipher2("hello", 103)
Traceback (most recent call last):
...
ValueError: chr() arg not in range(0x110000)

函数ord 产生一个介于 0 和 1114111 之间的 unicode 代码点,但我认为对于练习,您可以将范围限制为 0 - 127(ASCII 字符):

def cipher3(code, distance):
    assert abs(distance) < 128
    plainText = ""
    for ch in code:
        ordvalue = ord(ch)
        ciphervalue = ordvalue - distance
        if ciphervalue < 0:
            ciphervalue += 128
        elif ciphervalue >= 128: # don't forget distance can be negative
            ciphervalue -= 128
        plainText += chr(ciphervalue)
    return plainText

>>> cipher3("hello", 103)
'\\x01~\\x05\\x05\\x08'
>>> cipher3('\x01~\x05\x05\x08', -103)
'hello'

请注意:

        if ciphervalue < 0:
            ciphervalue += 128
        elif ciphervalue >= 128: # don't forget distance can be negative
            ciphervalue -= 128

相当于:

        ciphervalue = ciphervalue % 128

如果你只想有可打印的字符,你可以使用string 模块:

import string
# string.printable is '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

def cipher4(code, distance):
    assert abs(distance) < len(string.printable)
    plainText = ""
    for ch in code:
        ordvalue = string.printable.index(ch) # this is clearly suboptimal
        ciphervalue = (ordvalue - distance) % len(string.printable)
        plainText += string.printable[ciphervalue]
    return plainText

>>> cipher4("hello", 80)
'ByFFI'
>>> cipher4('ByFFI', -80)
'hello'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-03
    • 2013-02-26
    • 1970-01-01
    • 2013-03-13
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多