ROT13은 카이사르 암호의 일종으로 영어 알파벳을 13글자씩 밀어서 만든다.
예를 들어, "Baekjoon Online Judge"를 ROT13으로 암호화하면 "Onrxwbba Bayvar Whqtr"가 된다. ROT13으로 암호화한 내용을 원래 내용으로 바꾸려면 암호화한 문자열을 다시 ROT13하면 된다. 앞에서 암호화한 문자열 "Onrxwbba Bayvar Whqtr"에 다시 ROT13을 적용하면 "Baekjoon Online Judge"가 된다.
ROT13은 알파벳 대문자와 소문자에만 적용할 수 있다. 알파벳이 아닌 글자는 원래 글자 그대로 남아 있어야 한다. 예를 들어, "One is 1"을 ROT13으로 암호화하면 "Bar vf 1"이 된다.
문자열이 주어졌을 때, "ROT13"으로 암호화한 다음 출력하는 프로그램을 작성하시오.
첫째 줄에 알파벳 대문자, 소문자, 공백, 숫자로만 이루어진 문자열 S가 주어진다. S의 길이는 100을 넘지 않는다.
첫째 줄에 S를 ROT13으로 암호화한 내용을 출력한다.
입력 예시
Baekjoon Online Judge
출력 예시
Onrxwbba Bayvar Whqtr
s = input()
output = ''
for i in s: #입력된 문자열 중 문자 하나씩 검사
if i.isupper(): #문자가 대문자이면
if chr(ord(i) + 13).isupper(): #ascii코드에서 13을 더해도 대문자이면
output += chr(ord(i) + 13) #ascii코드에서 13을 더하고 문자열로 변환시켜서 output에 붙이기
else:
output += chr(ord(i) - 13) #ascii코드에서 13을 빼고 문자열로 변환시켜서 output에 붙이기
elif i.islower():
if chr(ord(i) + 13).islower():
output += chr(ord(i) + 13)
else:
output += chr(ord(i) - 13)
else: # 문자가 대문자도 소문자도 아니면 (알파벳이 아니면)
output += i # 문자를 output에 붙이기
print(output)
.isupper() , .islower() 는 문자열이 대문자 혹은 소문자인지 판별하여 boolean값을 리턴한다.
ord()는 문자열을 ascii 코드로 변환한다.
chr()는 10진법 혹은 16진법의 ascii코드를 문자열로 변환한다.
처음 작성한 코드는 아래와 같다.(오답)
s = input()
output = ''
for i in s:
if i.isalpha():
if chr(ord(i) + 13).isalpha():
output += chr(ord(i) + 13)
else:
output += chr(ord(i) - 13)
else:
output += i
print(output)
단순히 문자가 알파벳이고 ascii 코드에서 13을 더해도 알파벳 ascii코드이면, 13을 더하고 아니면 13을 빼서 저장했다.
출력은 다음과 같았다.
입력 : Baekjoon Online Judge
출력 : Onrxwbba Bayvar Whqtr
의도대로 출력이 잘 되었다! ...?
한번 출력물을 입력에 다시 넣어보자, 알파벳이 26개이니 13번을 두번 이동하면 원래 자리로 돌아와야한다.
입력 : Onrxwbba Bayvar Whqtr
출력 : Baekjoon Online dudge
백준 온라인 듀지..?
문제는 내가 아스키코드를 몰랐던 것이다.
W(87)에서 13을 더하면 d(100)인데 얘도 알파벳이니 조건문에서 문제가 없이 작동했던 것이다.
나는 W를 대문자 안에서 13번 밀어서 J로 바꿔야했고, 코드를 수정했다.
cs50에서 문제와 같은 방법으로 비밀암호 만들기를 했던 기억이 난다 ㅋㅋ