Short rot13 function - Python
121,827
Solution 1
maketrans()
/translate()
solutions…
Python 2.x
import string
rot13 = string.maketrans(
"ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
"NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
string.translate("Hello World!", rot13)
# 'Uryyb Jbeyq!'
Python 3.x
rot13 = str.maketrans(
'ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz',
'NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm')
'Hello World!'.translate(rot13)
# 'Uryyb Jbeyq!'
Solution 2
It's very simple:
>>> import codecs
>>> codecs.encode('foobar', 'rot_13')
'sbbone'
Solution 3
This works on Python 2 (but not Python 3):
>>> 'foobar'.encode('rot13')
'sbbone'
Solution 4
The maketrans
and translate
methods of str
are handy for this type of thing.
Here's a general solution:
import string
def make_rot_n(n):
lc = string.ascii_lowercase
uc = string.ascii_uppercase
trans = str.maketrans(lc + uc,
lc[n:] + lc[:n] + uc[n:] + uc[:n])
return lambda s: str.translate(s, trans)
rot13 = make_rot_n(13)
rot13('foobar')
# 'sbbone'
Solution 5
From the builtin module this.py
(import this
):
s = "foobar"
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])) # sbbone
Comments
-
svenwltr almost 2 years
I am searching for a short and cool rot13 function in Python ;-) I've written this function:
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 )
Can anyone make it better? E.g supporting uppercase characters.
-
Amber almost 14 yearsThe
.encode
method is included as part of string objects and doesn't need to be specifically imported. -
svenwltr almost 14 yearsThis is the shortest and its available under 3.0 :-)
-
Youarefunny about 13 yearsThis appears to be the new proper way to do it. They moved it out of the string object for modularity. Now the string object
str.encode()
raises errors about not returning a byte array or bytes object. -
Admin almost 11 yearsBut in Python 3, you need to spell it "rot_13" or "rot-13", not "rot13". I edited the answer.
-
Wooble over 10 yearsThis no longer works on Python3.2+;
maketrans
was removed from thestring
module. Use Nazmul Hasan'scodecs
answer instead. -
Milo P about 10 yearsNote also that this causes problems if you're trying to make Unicode text into rot13 and it contains any character larger than one byte (e.g., a non-breaking space).
-
Jonathan Potter over 8 yearsThis doesn't work in Python 3, but @Nazmul's similar method does.
-
kkessell over 8 yearsRumor: that's possibly just rot13 reading of a file as python source. See stackoverflow.com/a/1024693/26494
-
Muposat almost 8 yearsfor Python3.x: change to
rot13 = str.maketrans(...)
and then"Hello World!".translate(rot13)
-
ankostis over 7 years@steven-rumbalski Strange! In py3.5 I get this error:
LookupError: 'rot13' is not a text encoding; use codecs.encode() to handle arbitrary codecs
-
Brent Knox over 7 yearsfor
Python3.x
import string rot13 = str.maketrans( "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") print(str.translate("Hello World!", rot13))
-
wjandrea about 7 yearsDoug's answer has a cleaner way of making a dict.
-
김민준 almost 7 yearsYou can also directly import this.
import this;rot13 = lambda s:''.join(this.d.get(c, c) for c in s)
. Just saying. -
Martijn Pieters over 6 years@poke: it is definitely an available codec in Python 3. Just not as a str-to-bytes or bytes-to-str codec.
-
Martijn Pieters over 6 years@Amber:
str.encode()
can only produce bytes in Python 3. The rot13 codec is a str-to-str codec and is only available viacodecs.encode()
andcodecs.decode()
. -
Martijn Pieters over 6 years@user1220978:
rot13
is available in 3.6 at the very least. -
Martijn Pieters over 6 years@StevenRumbalski: if
str.encode('rot13')
ever worked in older 3.x releases then that was a mistake, asstr.encode()
is strict about producingbytes
results only, while ROT13 is a text-to-text codec. -
Orsiris de Jong over 4 yearsYour solution is elegant, but won't handle scenarios with accents (ie éêèö and alike) because str.isalpha() returns True for those characters. Here's a lightly modified version that does not use str.isalpha():
def rot13(s): return ''.join([chr(ord(n) + (13 if 'Z' < n < 'n' or n < 'N' else -13)) if ('a' <= n <= 'z' or 'A' <= n <= 'Z') else n for n in string])
-
Boris Verkhovskiy about 3 years@Ensemble the documentation says "New in version 3.2: Restoration of the
rot_13
text transform." and "Changed in version 3.4: Restoration of therot13
alias." So neither work on 3.0 and 3.1, thenrot_13
works on 3.2 and 3.3 and then bothrot_13
androt13
work on 3.4+ (as well as Python 2). -
pat almost 3 yearsSame idea with basic python:
def rot13(s): m = {a:b for a,b in zip("ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")} return ''.join(m.setdefault(c, c) for c in s)
-
MadMad666 over 2 yearsI liked it, very interesting way to do.