短rot13函数 – Python

我在Python中search一个简短而酷的rot13函数;-)我写了这个函数:

def rot13(s): chars = "abcdefghijklmnopqrstuvwxyz" trans = chars[13:]+chars[:13] rot_char = lambda c: trans[chars.find(c)] if chars.find(c)>-1 else c return ''.join( rot_char(c) for c in s ) 

任何人都可以做得更好吗? 例如支持大写字符。

这是一个maketrans / translate解决scheme

 import string rot13 = string.maketrans( "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") string.translate("Hello World!", rot13) # 'Uryyb Jbeyq!' 

其非常简单

 import codecs codecs.encode('foobar', 'rot_13') >> 'sbbone' 
 >>> 'foobar'.encode('rot13') 'sbbone' 

(我听说传言这在Python 3.x中不起作用。)

string模块中的maketranstranslate函数对于这种types的东西是很方便的。 当然,在这个特定的情况下,Amber响应中的encode方法更加方便。

这是一个通用的解决scheme:

 import string def make_rot_n(n): lc = string.ascii_lowercase uc = string.ascii_uppercase trans = string.maketrans(lc + uc, lc[n:] + lc[:n] + uc[n:] + uc[:n]) return lambda s: string.translate(s, trans) rot13 = make_rot_n(13) rot13('foobar') # 'sbbone' 

从模块this.pyimport this )。

 d = {} for c in (65, 97): for i in range(26): d[chr(i+c)] = chr((i+13) % 26 + c) print "".join([d.get(c, c) for c in s]) 

从Python 3.1开始, string.translatestring.maketrans不再存在。 但是,这些方法可以用bytes来代替。

因此,Paul Rubel的一个直接启发的最新解决scheme是:

 rot13 = bytes.maketrans( b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", b"nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM") b'Hello world!'.translate(rot13) 

stringbytes转换,反之亦然可以通过encodedecode内置函数完成。

尝试这个:

 import codecs codecs.encode("text to be rot13()'ed", "rot_13") 

在python-3中,@amber提到的str -codec已经转移到了codecs标准库:

 > import codecs > codecs.encode('foo', 'rot13') sbb 

对于任意值,像这样的东西适用于2.x

 from string import ascii_uppercase as uc, ascii_lowercase as lc, maketrans rotate = 13 # ROT13 rot = "".join([(x[:rotate][::-1] + x[rotate:][::-1])[::-1] for x in (uc,lc)]) def rot_func(text, encode=True): ascii = uc + lc src, trg = (ascii, rot) if encode else (rot, ascii) trans = maketrans(src, trg) return text.translate(trans) text = "Text to ROT{}".format(rotate) encode = rot_func(text) decode = rot_func(encode, False) 

这适用于大写和小写。 我不知道你觉得它有多优雅。

 def rot13(s): rot=lambda x:chr(ord(x)+13) if chr(ord(x.lower())+13).isalpha()==True else chr(ord(x)-13) s=[rot(i) for i in filter(lambda x:x!=',',map(str,s))] return ''.join(s) 

您可以通过交替使用大写字母和小写字母来支持沃尔特先生发布的原始代码的大写字母。

 chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" 

如果您注意到大写字母的索引都是偶数,而小写字母的索引是奇数。

  • A = 0 a = 1,
  • B = 2,b = 3,
  • C = 4,c = 4,

这种奇偶模式使我们能够安全地添加所需的数量而不必担心这种情况。

 trans = chars[26:] + chars[:26] 

您添加26的原因是由于大写字母,string在字母中翻了一番。 不过,字母表上的这个转换还有13个空格。

完整的代码:

 def rot13(s): chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" trans = chars[26:]+chars[:26] rot_char = lambda c: trans[chars.find(c)] if chars.find(c) > -1 else c return ''.join(rot_char(c) for c in s) 

输出(用python 2.7testing):

 print rot13("Hello World!") --> Uryyb Jbeyq! 

下面的函数rot(s, n)使用ROT- n编码strings来编码任何整数nn默认为13.支持大写和小写字母。 超过26或负值的n值被适当地处理,例如,移位27个位置等于移位一个位置。 解码是用invrot(s, n)

 import string def rot(s, n=13): '''Encode string s with ROT-n, ie, by shifting all letters n positions. When n is not supplied, ROT-13 encoding is assumed. ''' upper = string.ascii_uppercase lower = string.ascii_lowercase upper_start = ord(upper[0]) lower_start = ord(lower[0]) out = '' for letter in s: if letter in upper: out += chr(upper_start + (ord(letter) - upper_start + n) % 26) elif letter in lower: out += chr(lower_start + (ord(letter) - lower_start + n) % 26) else: out += letter return(out) def invrot(s, n=13): '''Decode a string s encoded with ROT-n-encoding When n is not supplied, ROT-13 is assumed. ''' return(rot(s, -n)) 

一行一行rot13一串S

 S.translate({a : a + (lambda x: 1 if x>=0 else -1)(77 - a) * 13 for a in range(65, 91)}) 
 def rot13(s): lower_chars = ''.join(chr(c) for c in range (97,123)) #ASCII az upper_chars = ''.join(chr(c) for c in range (65,91)) #ASCII AZ lower_encode = lower_chars[13:] + lower_chars[:13] #shift 13 bytes upper_encode = upper_chars[13:] + upper_chars[:13] #shift 13 bytes output = "" #outputstring for c in s: if c in lower_chars: output = output + lower_encode[lower_chars.find(c)] elif c in upper_chars: output = output + upper_encode[upper_chars.find(c)] else: output = output + c return output 

另一种解决scheme 也许这个代码可以帮助其他人更好地理解rot13。 还没有完全testing。

 from string import maketrans, lowercase, uppercase def rot13(message): lower = maketrans(lowercase, lowercase[13:] + lowercase[:13]) upper = maketrans(uppercase, uppercase[13:] + uppercase[:13]) return message.translate(lower).translate(upper) 

有趣的锻炼;-)我想我有最好的解决scheme,因为:

  1. 不需要模块,只使用内置函数 – > 不要弃用
  2. 它可以作为一个class轮使用
  3. 基于ascii,没有映射字典/string等

Python 2&3(可能是Python 1):

 def rot13(s): return ''.join([chr(ord(n) + (13 if 'Z' < n < 'n' or n < 'N' else -13)) if n.isalpha() else n for n in s]) def rot13_verbose(s): x = [] for n in s: if n.isalpha(): # 'n' is the 14th character in the alphabet so if a character is bigger we can subtract 13 to get rot13 ort = 13 if 'Z' < n < 'n' or n < 'N' else -13 x.append(chr(ord(n) + ort)) else: x.append(n) return ''.join(x) # crazy .min version (99 characters) disclaimer: not pep8 compatible^ def r(s):return''.join([chr(ord(n)+(13if'Z'<n<'n'or'N'>n else-13))if n.isalpha()else n for n in s]) 

当我开始想知道最简单的方法来实现rot13到Python自己的时候,我发现这篇文章。 我的目标是:

  • 适用于Python 2.7.6和3.3。
  • 处理大小写。
  • 不使用任何外部库。

这符合所有这三个要求。 这就是说,我敢肯定,这不是赢得任何代码高尔夫比赛。

 def rot13(string): CLEAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ROT13 = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm' TABLE = {x: y for x, y in zip(CLEAR, ROT13)} return ''.join(map(lambda x: TABLE.get(x, x), string)) if __name__ == '__main__': CLEAR = 'Hello, World!' R13 = 'Uryyb, Jbeyq!' r13 = rot13(CLEAR) assert r13 == R13 clear = rot13(r13) assert clear == CLEAR 

这是通过创build一个查找表,并简单地返回查找表中找不到的任何字符的原始字符。

更新

我不得不担心有人想用这个来encryption一个任意大的文件(比如几十亿字节的文本)。 我不知道他们为什么要这样做,但如果他们这样做呢? 所以我重写了它作为一个发电机。 同样,这已经在Python 2.7.6和3.3中进行了testing。

 def rot13(clear): CLEAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ROT13 = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm' TABLE = {x: y for x, y in zip(CLEAR, ROT13)} for c in clear: yield TABLE.get(c, c) if __name__ == '__main__': CLEAR = 'Hello, World!' R13 = 'Uryyb, Jbeyq!' r13 = ''.join(rot13(CLEAR)) assert r13 == R13 clear = ''.join(rot13(r13)) assert clear == CLEAR 

我不能在这里留下这个问题,用模运算符进行单一的陈述。

 def rot13(s): return ''.join([chr(x.islower() and ((ord(x) - 84) % 26) + 97 or x.isupper() and ((ord(x) - 52) % 26) + 65 or ord(x)) for x in s]) 

不是pythonic,也不是很好的做法,但它的工作原理!

 >> rot13("Hello World!") Uryyb Jbeyq! 

你也可以使用这个

 def n3bu1A(n): o="" key = { 'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', 'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', 'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k', 'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', 'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', 'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', 'W':'J', 'X':'K', 'Y':'L', 'Z':'M'} for x in n: v = x in key.keys() if v == True: o += (key[x]) else: o += x return o Yes = n3bu1A("N zhpu fvzcyre jnl gb fnl Guvf vf zl Zragbe!!") print(Yes) 

简而言之:

 def rot13(text): return "".join([x if ord(x) not in range(65, 91)+range(97, 123) else chr(((ord(x)-97+13)%26)+97) if x.islower() else chr(((ord(x)-65+13)%26)+65) for x in text])