原子地替换多个字符

时间:2015-08-02 10:35:54

标签: python encryption substitution

我正在使用频率分析解密替换密码( Caesar / ROT)而没有专门的工具。假设我想使用这个密码字典,这个字典在分析后看起来很好:

key = {
'S':'E',
'Q':'A',
'J':'T',
'U':'O',
'B':'I',
'N':'N',
'C':'L',
'G':'R',
'D':'H',
'V':'S',
'Z':'D',
'W':'C',
'M':'U',
'Y':'M',
'T':'F',
'X':'P',
'K':'G',
'E':'W',
'L':'Y',
'A':'B',
'F':'V',
'I':'K',
'O':'X',
'H':'J',
'R':'Q',
'P':'Z'
}

我的代码有一个明显的问题:

 with open(filename) as f:
     out = f.read()
     for k in key:
         out = out.replace(k,key[k])
     print out

因为它一个接一个地替换每个字符,所以在算法完成之前,某个位置的字符会被替换几次而不是一次。 (即:首次迭代算法将用S替换所有E,但随后它会到达字典中的E并替换所有 E s与W

Python是否有方便一次性执行此操作?或者我会被迫跟踪自己已经改变的位置吗?

1 个答案:

答案 0 :(得分:3)

对于Python 3.x,您可以使用str.maketrans()(或string.maketrans()用于Python 2.x)和str.translate()用于此目的 -

In [27]: key = {
   ....: 'S':'E',
   ....: 'Q':'A',
   ....: 'J':'T',
   ....: 'U':'O',
   ....: 'B':'I',
   ....: 'N':'N',
   ....: 'C':'L',
   ....: 'G':'R',
   ....: 'D':'H',
   ....: 'V':'S',
   ....: 'Z':'D',
   ....: 'W':'C',
   ....: 'M':'U',
   ....: 'Y':'M',
   ....: 'T':'F',
   ....: 'X':'P',
   ....: 'K':'G',
   ....: 'E':'W',
   ....: 'L':'Y',
   ....: 'A':'B',
   ....: 'F':'V',
   ....: 'I':'K',
   ....: 'O':'X',
   ....: 'H':'J',
   ....: 'R':'Q',
   ....: 'P':'Z'
   ....: }

In [28]: t = str.maketrans(key)

In [29]: "ABCDEFGZYXW".translate(t)
Out[29]: 'BILHWVRDMPC'

对于Python 2.x,

>>> from string import maketrans
>>> t = maketrans(''.join(key.keys()) , ''.join(key.values()))
>>> "ABCDEFGZYXW".translate(t)
'BILHWVRDMPC'