2012-01-27 2 views
3

문자열의 각 문자를 알파벳으로 옮겨서 다른 것으로 옮기고 싶습니다. 아래 예제에서 2 씩 이동합니다. 따라서 a -> c, b -> d 등파이썬에서 시프트 암호 : ord를 사용하는 오류

이 작업을 수행하기 위해 정규 표현식과 sub 함수를 사용하려고하는데, 오류. 변수 text는 입력 문자열입니다

p = re.compile(r'(\w)') 
test = p.sub(chr(ord('\\1') + 2), text) 
print test 

을 :

는 내가 가지고있는 코드입니다.

그리고이 오류 받고 있어요 :

TypeError: ord() expected a character, but string of length 2 found

을 나는 문제가 나는 ord 기능은 리터럴 문자열 "\ 1"과에 호출되는 것을 생각하지 정규으로 일치 \w 문자에 표현. 이 작업을 수행하는 올바른 방법은 무엇입니까?

+1

당신은 정규 표현식을 사용하는 이유가 없다; 정규 표현식은 하위 문자열 (특수 구조가있는 경우가 많음)을 검색하기위한 것이지만 이미 정규 표현식없이 한 문자 씩 하위 문자열을 추출 할 수 있습니다. 단지'[c for string in c] '입니다. 어쨌든 (regexes를 사용하지 않는) 솔루션을 제공했습니다. – ninjagecko

+0

정규 표현식에 들어간 이유는 "단어"문자 만 바꾸기를 원했기 때문이며, 이해하는 방법을 모르겠습니다. (난 단지 파이썬 배우고, 당신이 말할 수없는 경우) – Joe

+0

문자열에 공백과 구두점이 포함될 수 있습니다. 이러한 문자는 이동하지 않아야하지만 숫자 나 문자는 이동해야합니다. 애매한 점 죄송합니다. 원래 질문에 대한 여러 가지 좋은 대답이있었습니다. 내가 할 수 있으면 upvote 줄. – Joe

답변

4

이렇게 작동하지 않습니다. 파이썬은 먼저 chr(ord('\\') + 2을 실행 한 다음 그 결과를 p.sub에게 전달합니다.

p = re.compile(r'(\w)') 
test = p.sub(lambda m: chr(ord(m.group(1)) + 2), text) 
print test 

또는 더 나은 아직 대신 정규 표현식의 maketrans 사용 :

import string 

shift = 2 

t = string.maketrans(string.ascii_lowercase, string.ascii_lowercase[shift:] + 
              string.ascii_lowercase[:shift]) 
string.translate(text, t) 
+0

예를 들어 다음과 같이 바뀌지 않습니다. 'z'-> 'a'. OP도이 실수를 저지르기 때문에 downvote가 없습니다. – ninjagecko

+1

좋은 점 @ninjagecko, 나는 그것을'sub'와 콜백을 시연하기 위해 남겨 둘 것입니다. 그는'maketrans'를 어느쪽으로 든 사용해야합니다. –

2

는 별도의 기능에 넣어 또는 익명 함수 (람다)를 사용할 필요가 정식 버전

def shouldShift(char): 
    return char in string.lowercase 

def caesarShift(string, n): 
    def letterToNum(char): 
     return ord(char)-ord('a') 
    def numToLetter(num): 
     return chr(num+ord('a')) 

    def shiftByN(char): 
     return numToLetter((letterToNum(char)+n) % 26) 

    return ''.join((shiftByN(c) if shouldShift(c) else c) for c in string.lower()) 

한 - 라이너

당신이 정말 한 줄을 원하는 경우에, 그것은이 될 것입니다,하지만 난 그게 더 추악한 느꼈다 :

''.join(chr((ord(c)-ord('a')+n)%26 + ord('a')) for c in string) 

데모

>>> caesarShift(string.lowercase, 3) 
'defghijklmnopqrstuvwxyzabc' 
+0

문자를 올바르게 바꿀 것입니다. Z-> A. – ninjagecko

1

는 지능형리스트를 사용하여,이 시도 :

input = 'ABC' 
''.join(chr(ord(c)+2) for c in input) 
> 'CDE' 

그것은 정규 표현식을 사용하는 것보다 간단합니다.

+0

또는 HAL 9000에 사과 한 상태에서이 '' '.join (chr (ord (c) +1) for'HAL ')' –

0
def CaesarCipher(s1,num): 
new_str = '' 
for i in s1: 
    asc_V = ord(i) 

    if asc_V in range(65, 91): 
     if asc_V + num > 90: 
      asc_val = 65 + (num - 1 - (90 - asc_V)) 
     else: 
      asc_val = asc_V + num 

     new_str = new_str + chr(asc_val) 


    elif (asc_V in range(97, 123)): 
     if asc_V + num > 122: 
      asc_val = 97 + (num - 1 - (122 - asc_V)) 
     else: 
      asc_val = asc_V + num 

     new_str = new_str + chr(asc_val) 

    else: 
     new_str = new_str + i 

return new_str   

인쇄 (카이사르 암호 ("안녕하세요", 4))

인쇄 (카이사르 암호 ("xyzderBYTE", 2))