簡體   English   中英

Python:解密凱撒密碼

[英]Python: decrypt caesar cipher

任務:

編寫一個腳本,輸入一行加密文本和一個距離值,並使用凱撒密碼輸出明文。

我的問題:

它正在打印 hello^3 world^2

我不完全確定為什么。 我將不勝感激任何和所有幫助修復或理解我的代碼中的錯誤。 (這不是為等級分配的,即沒有截止日期是為了我自己的利益

它希望我能夠使用的輸入及其各自的:

Lipps${svph% 4

Jhss'tl'Pzothls5 7

Zu&hk2&ux&tuz&zu&hk 2

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)

首先,您應該將輸入/輸出與處理分離,因為您的代碼將更易於測試:

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生成一個 unicode 代碼點,介於 0 和 1114111 之間,但我認為對於練習,您可以將范圍限制為 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'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM