我在Python中搜索一个简短而酷炫的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 )
有人能让它变得更好吗?例如,支持大写字符。
答案 0 :(得分:123)
这很简单:
>>> import codecs
>>> codecs.encode('foobar', 'rot_13')
'sbbone'
答案 1 :(得分:70)
这是一个maketrans / translate解决方案
import string
rot13 = string.maketrans(
"ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
"NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
string.translate("Hello World!", rot13)
# 'Uryyb Jbeyq!'
答案 2 :(得分:63)
这适用于Python 2(但不适用于Python 3):
>>> 'foobar'.encode('rot13')
'sbbone'
答案 3 :(得分:21)
string
模块中的maketrans
和translate
函数对于此类事物非常方便。当然,对于这种特殊情况,Amber响应中的encode
方法更为方便。
以下是一般解决方案:
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'
答案 4 :(得分:10)
来自模块this.py
(import 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])
答案 5 :(得分:8)
从Python 3.1开始,string.translate
和string.maketrans
不再存在。但是,这些方法可以与bytes
一起使用。
因此,最新的解决方案直接受到Paul Rubel的启发,是:
rot13 = bytes.maketrans(
b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
b"nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM")
b'Hello world!'.translate(rot13)
答案 6 :(得分:6)
试试这个:
import codecs
codecs.encode("text to be rot13()'ed", "rot_13")
答案 7 :(得分:5)
在python-3中,@ amber提到的str
- 编解码器已移至codecs
标准库:
> import codecs
> codecs.encode('foo', 'rot13')
sbb
答案 8 :(得分:3)
一个字符串rot13一个字符串S
:
S.translate({a : a + (lambda x: 1 if x>=0 else -1)(77 - a) * 13 for a in range(65, 91)})
答案 9 :(得分:2)
您可以通过交替使用大写和小写字母来支持Walter先生发布的原始代码上的大写字母。
chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
如果您注意到大写字母的索引都是偶数,而小写字母的索引是奇数。
这种奇偶模式允许我们安全地添加所需的金额而不必担心案件。
trans = chars[26:] + chars[:26]
你添加26的原因是由于大写字母,字符串的字母加倍。但是,班次仍然是字母表中的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)
OUTPUT(使用python 2.7测试):
print rot13("Hello World!") --> Uryyb Jbeyq!
答案 10 :(得分:2)
以下函数rot(s, n)
使用ROT - s
编码对任何整数n
进行编码的字符串n
,其中n
默认为13。支持小写字母。适当地处理n
超过26或负值的值,例如,移位27个位置等于移位一个位置。使用invrot(s, n)
进行解码。
import string
def rot(s, n=13):
'''Encode string s with ROT-n, i.e., 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))
答案 11 :(得分:2)
这适用于大写和小写。我不知道你认为它有多优雅。
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)
答案 12 :(得分:2)
对于任意值,这样的东西适用于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)
答案 13 :(得分:1)
def rot13(s):
lower_chars = ''.join(chr(c) for c in range (97,123)) #ASCII a-z
upper_chars = ''.join(chr(c) for c in range (65,91)) #ASCII A-Z
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
转移的另一个解决方案。也许这段代码可以帮助其他人更好地理解rot13。 没有完全测试过。
答案 14 :(得分:0)
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)
答案 15 :(得分:0)
有趣的运动;-)我认为我有最好的解决方案,因为:
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])
答案 16 :(得分:0)
当我开始想知道最简单的实施方法时,我发现了这篇文章
我自己rot13
加入Python。我的目标是:
这符合所有这三个要求。话虽如此,我确信它并没有赢得任何代码高尔夫比赛。
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
这可以通过创建查找表并简单地返回查找表中找不到的任何字符的原始字符来实现。
我担心有人想用它来加密一个任意大的文件(比如几千兆字节的文本)。我不知道他们为什么要这样做,但如果他们这样做了呢?所以我把它重写为发电机。同样,这已经在Python 2.7.6和3.3中进行了测试。
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
答案 17 :(得分:0)
你也可以使用它
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)
答案 18 :(得分:0)
我不能在这里使用模运算符留下一个语句。
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!
答案 19 :(得分:-2)
简短解决方案:
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])