Подтвердить что ты не робот

Функция Short rot13 - Python

Я ищу короткую и крутую функцию rot13 в Python;-) Я написал эту функцию:

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 ) 

Кто-нибудь может сделать это лучше? Например, поддержка символов верхнего регистра.

4b9b3361

Ответ 1

Здесь maketrans/translate solution

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

Ответ 2

Это очень просто:

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

Ответ 3

>>> 'foobar'.encode('rot13')
'sbbone'

(Я слышал слухи, что это не работает в Python 3.x.)

Ответ 4

maketrans и translate функции в модуле string удобны для этого типа вещей. Разумеется, метод 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'

Ответ 5

Из модуля 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])

Ответ 6

Как и в случае с Python 3.1, string.translate и string.maketrans больше не существует. Однако эти методы можно использовать вместо bytes.

Таким образом, современное решение, непосредственно вдохновленное Павлом Рубелем, заключается в следующем:

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

Конверсия с string в bytes и наоборот может быть выполнена с помощью encode и decode встроенные функции.

Ответ 7

Попробуйте следующее:

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

Ответ 8

В python-3 str -codec, упомянутый выше, указан в стандартной библиотеке codecs:

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

Ответ 9

Для произвольных значений, что-то вроде этого работает для 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)

Ответ 10

Это работает для прописных и строчных букв. Я не знаю, насколько вы элегантны.

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)

Ответ 11

Вы можете поддерживать заглавные буквы исходного кода, отправленного г-ном Вальтером, чередуя буквы верхнего регистра и строчных букв.

chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

Если вы заметили, что индекс прописных букв - это все четные числа, а индекс строчных букв - нечетный.

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

Этот нечетный шаблон позволяет нам безопасно добавлять необходимую сумму, не беспокоясь о случае.

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!

Ответ 12

Следующая функция rot(s, n) кодирует строку s с кодировкой ROT- 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))

Ответ 13

Однострочный к rot13 строка S:

S.translate({a : a + (lambda x: 1 if x>=0 else -1)(77 - a) * 13 for a in range(65, 91)})

Ответ 14

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. Не тестировали его полностью.

Ответ 15

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)

Ответ 16

Интересные упражнения;-) Я думаю, у меня есть лучшее решение, потому что:

  • не нужны модули, использует только встроенные функции → без устаревания
  • он может использоваться как один вкладыш
  • на основе ascii, никакого отображения dicts/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])

Ответ 17

Я нашел этот пост, когда начал интересоваться самым простым способом реализации 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

Это работает, создавая таблицу поиска и просто возвращая исходный символ для любого символа, не найденного в таблице поиска.

Update

Мне нужно беспокоиться о том, что кто-то хочет использовать это, чтобы зашифровать произвольно большой файл (скажем, несколько гигабайт текста). Я не знаю, почему они захотят это сделать, но что, если они это сделают? Поэтому я переписал его как генератор. Опять же, это было протестировано как в 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

Ответ 18

Вы также можете использовать это также

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)

Ответ 19

Я не мог оставить этот вопрос здесь без одного оператора, использующего оператор modulo.

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!

Ответ 20

Краткое решение:

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])