简体   繁体   中英

How would I reverse this? Python 3.8

So I've created a very... odd little caesar cipher using python. Very simple. Except, I'm not really all that great at math and am wondering how I'd reverse this?

def encrypt(text,s): 
    result = "" 
    for i in range(len(text)): 
        char = text[i] 
        if (char.isupper()): 
            result += chr((ord(char) + s - 23+213**3) % 26 + 713) 
        else: 
            result += chr((ord(char) + s - 23+213**3) % 26 + 715) 
    return result 

text = input("Message: ")
s = 964

print ("Text: " + text) 
print ("Shift: " + str(s)) 
print ("Cipher: " + encrypt(text,s))

Any form of help would be appreciated.

Edit:

I'M SO CLOSE: I did that math as to how the shift works:

if the letter is a capital: 1. 964 - 23+213^3, which ends up as -9662656 2. Get the remainder of that divided by 26 (modulo operator) -9662656 % 26 = 10 3. 10 + 714 = 724 4. 724-63 I got the 63 just through trial and error...

ONLY PROBLEM, It all works up until the letter M. in which case the last 13 letters shift backward 26 characters? How would I solve this?

def decrypt(text,s): 
    result = "" 
    for i in range(len(text)): 
        char = text[i] 
        result += chr((ord(char) - s))
    return result 

text = input("Message: ")
s = 724-63

print ("Text: " + text) 
print ("Shift: " + str(s)) 
print ("Cipher: " + decrypt(text,s))
Text: ˖˗˘˙˚˛˜˝˞˟ˠˡˢˉˊˋˌˍˎˏːˑ˒˓˔˕
Shift: 661
Cipher: ABCDEFGHIJKLM456789:;<=>?@

I rewrote your encrypt function to show the individual piece of the calculation. Then I wrote the decrypt function to show how to "undo" them.

Note that -23+213 3 is equivalent to 24 when working mod 26.

def encrypt(text, s):
    cipher = ""
    for pt_char in text:
        val = ord(pt_char)          # 65 <= val < 91
        t0 = val % 26               # 0 <= t0 < 26, with A=>13, B=>14, ... N=>0 etc.
        t1 = (t0 + s + 24) % 26     # 0 <= t1 < 26
        t2 = t1 + 715               # 715 <= t2 < 741
        cipher += chr(t2)
    return cipher


def decrypt(ct, s):
    plain = ""
    for ct_char in ct:
        t2 = ord(ct_char)           # 715 <= t2 < 741
        t1 = t2 - 715               # 0 <= t1 < 26
        t0 = (t1 - s - 24 + 13) % 26     # 0 <= t0 < 26
        val = t0 + 65               # 65 <= val < 91
        plain += chr(val)
    return plain

Again, this only works for upper case ASCII letters. Pay attention to the comments, they are telling you something.

Here are shorter one-liner just to show you something about how generators can produce compact code.

def encrypt_one_liner(text, s):
    return ''.join(chr((ord(x) + s + 24) % 26 + 715) for x in text)


def decrypt_one_liner(text, s):
    return ''.join(chr((ord(x) + 2 - s) % 26 + 65) for x in text)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM