多级凯撒密码加密

1 投票
2 回答
1064 浏览
提问于 2025-04-17 21:22

我正在做麻省理工学院开放课程的第四个问题集。我试着参考他们的解决方案,但不知道为什么找不到。他们发布了错误的答案。所以,我的问题是这样的。

这个功能应该做的事情是这样的:“这个函数接收一个字符串文本和一个元组列表 shifts。shifts 中的元组表示移位的位置和移位的大小。例如,元组 (0,2) 意味着移位从字符串的第 0 个位置开始,并且是一个 2 的凯撒移位。此外,这些移位是分层的。这意味着一组移位 [(0,2), (5, 3)] 会先对整个字符串应用一个 2 的凯撒移位,然后从字符串的第 6 个字母开始应用一个 3 的凯撒移位。”

所以,这是我写的代码:

def apply_shifts(text, shifts):
    encryptedText = text
    for t in shifts:
        encryptedText = apply_shift(encryptedText[t[0]:len(encryptedText)], t[1])
        print encryptedText
    return encryptedText

我知道我在每次循环时都在替换我引用的变量。我只是不知道该怎么设置才能避免这个问题。这里是我的测试:

print apply_shifts("Do Androids Dream of Electric Sheep?", [(0,6), (3, 18), (12, 16)])
print 'JufYkaolfapxQdrnzmasmRyrpfdvpmEurrb?'

第一个打印语句是我的测试,第二个是应该得到的输出。有什么想法吗?

2 个回答

1

这是我可能会推荐使用递归函数来完成的少数几个功能之一!

import string

def apply_shift(text,shift):
    ciphertext = string.ascii_uppercase+string.ascii_lowercase
    cipherdict = {char:idx for idx,char in enumerate(string.ascii_uppercase+string.ascii_lowercase)}
    loop_amt = len(ciphertext)

    start,shift = shift
    text = list(text)
    for idx,char in enumerate(text[start:]):
        idx = start+idx
        if char not in cipherdict: continue
        else: text[idx] = ciphertext[(cipherdict[char]+shift)%loop_amt]
    return ''.join(text)

def apply_shifts(text,shifts):
    start,shift = shifts.pop(-1)
    if shifts:
        return apply_shifts(apply_shift(text,(start,shift)),shifts)
    else:
        return apply_shift(text,(start,shift))
0

在每次循环中,把 apply_shift 的结果和没有偏移的部分放在一起:

  • 加号(+)运算符可以把字符串连接起来
  • 你可以用切片的简写法来获取字符串的一部分,比如从开头开始的部分 s[:i],或者从某个位置到结尾的部分 s[i:]

    这段代码的意思是:encryptedText = encryptedText[:t[0]] + apply_shift(encryptedText[t[0]:], t[1])

撰写回答