Blog

[Java]33 시저암호 문제에서의 문자, 아스키 (ASCII), 아스키 코드 그리고 유니코드 UTF-8?

Category
Author
Tags
PinOnMain
1 more property

문제 설명

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

제한 조건

공백은 아무리 밀어도 공백입니다. s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다. s의 길이는 8000이하입니다. n은 1 이상, 25이하인 자연수입니다.
이런 문제가 나타났다. 나는 분명히 이전에 배웠던 아스키 코드가 떠올랐고, 기억이 남아있는 것은 “65라는 것이 A를 나타낸다.”라는 것을 기억하고 있었다. 조금 더 정확한 정보를 정리해두기 위해서 아스키에 대한 내용을 검색했다.
어제 경험했던 한글은 char[]에 들어가지 않던 문제가 이것과도 연관이 있다. char 타입으로 정해질 수 있는 것들은 아래 아스키 코드로 대체되는가에 대한 문제였다.
ASCII (American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)
아스키 코드는 1963년 미국 ANSI에서 표준화한 정보교환용 7비트 부호체계이다. 인쇄전신기(Teleprinter)[2]를 통한 전신(통신)에서 사용되기 시작했고, 8비트 컴퓨터에서도 활용되어 오늘날 문자 인코딩의 근간을 이루게 된다.
한글 인코딩은 2바이트 이상을 써야 가능했기 때문에 아스키 코드를 건드릴 수 밖에 없었고, 초창기에는 글자 깨짐 문제가 종종 발생하였다. 코드페이지(CP949 등)를 맞춰주지 못하면 역시 글자 깨짐이 발생했고, 해외게임을 할 때 특히 그러했다. 유니코드가 제정되면서 글자 깨짐은 끝날 줄 알았지만 멀티 바이트의 엔디안 문제로 글자는 또 깨졌고, ASCII가 호환되는 UTF-8이 널리 사용되면서 글자 깨짐은 막을 내리게 된다.
흔히 이 목록에 있는 문자들을 영숫자라 부른다. 좁은 의미로는 숫자 10개(0~9, 0x30 ~ 0x39), 대문자 26개(A~Z, 0x41 ~ 0x5A), 소문자 26개(a~z, 0x61 ~ 0x7A) 해서 총 62개의 문자를 영숫자라 부르고, 넓은 의미로는 이 목록의 문자들을 모두 포괄한다.
나는 조금 외워도 좋을만한 부분을 생각했다.
숫자가 시작되는 0부터 9까지인 (048~057)
대문자 A~Z (065~090)
소문자 a~z (097~122)
외우지 못하더라도 중요한것은 대문자가 소문자보다 작은 숫자에 있다는 것,
대문자 이후로 바로 소문자가 연속되는 것은 아니라는것 정도는 기억하면 좋을 것 같았다.
문제나 어떤 로직을 아스키를 이용하거나 활용해야 할 때, 단순히 대문자 Z다음이 소문자 a가 아니라어느 정도 거리가 있다는 것만이라도 기억해 낸다면 도움이 될 것 같았다.
10진수
부호
10진수
부호
10진수
부호
10진수
부호
032
[3]
056
8
080
P
104
h
033
!
057
9
081
Q
105
i
034
"
058
:
082
R
106
j
035
#
059
;
083
S
107
k
036
$
060
<
084
T
108
l
037
%
061
=
085
U
109
m
038
&
062
>
086
V
110
n
039
'
063
?
087
W
111
o
040
(
064
@
088
X
112
p
041
)
065
A
089
Y
113
q
042
*
066
B
090
Z
114
r
043
+
067
C
091
[
115
s
044
,
068
D
092
\
116
t
045
-
069
E
093
]
117
u
046
.
070
F
094
^
118
v
047
/
071
G
095
_
119
w
048
0
072
H
096
`
120
x
049
1
073
I
097
a
121
y
050
2
074
J
098
b
122
z
051
3
075
K
099
c
123
{
052
4
076
L
100
d
124
|
053
5
077
M
101
e
125
}
054
6
078
N
102
f
126
~
055
7
079
O
103
g
유니코드 중 UTF-8
IDE를 세팅하거나, 프로젝트 세팅을 할 때 UTF-8을 많이 본다. 이것은 무엇일까? 캐릭터 인코딩이라는 것을 설정하는 것은 알겠지만 무엇인지도 궁금했다. 이것과 아스키 코드는 무슨 연관이 있는 걸까.
UTF-8은 가장 많이 사용되는 가변 길이 유니코드 인코딩이다. UTF-8은 유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나로, 켄 톰프슨과 롭 파이크가 만들었다. UTF-8은 Universal Coded Character Set + Transformation Format – 8-bit의 약자이다.

일반적으로[편집]

장점
ASCII 인코딩은 UTF-8의 부분 집합이다. 일반적인 ASCII 문자열은 올바른 UTF-8 문자열이며, 따라서 하위 호환성이 보장된다.
UTF-8 문자열은 바이트 단위로 정렬을 수행하는 알고리즘으로도 코드 포인트 단위로 올바르게 정렬할 수 있다. (일반적인 목적으로는 재정렬이 필요하다)
UTF-8과 UTF-16은 XML 문서의 표준 인코딩으로, 다른 인코딩들을 사용하려면 외부에서, 또는 문서 안에서 명시적으로 인코딩을 정해야 한다. [1]
다른 인코딩과의 왕복 변환이 간단하다.
바이트 단위 문자열 검색 알고리즘들을 그대로 사용할 수 있다.
간단한 알고리즘을 통하여 UTF-8 문자열임을 확인할 수 있다. 즉, 다른 인코딩에서 나타나는 바이트들이 올바른 UTF-8 문자열일 가능성은 낮다.

기존의 인코딩들과 비교했을 때[편집]

장점
UTF-8은 모든 유니코드 문자를 표현할 수 있다. 예를 들어서, UCS-2는 BMP 안의 문자만을 표현할 수 있다.
바이트 경계를 순서대로 혹은 역순으로 찾기 쉽다. 만약 여러 바이트로 표시된 문자의 중간에서 찾기 시작한다면, 단지 해당 문자만 손실되고 나머지 문자들은 손상을 입지 않는다. 기존의 많은 다중바이트 인코딩들은 이러한 재동기화가 훨씬 힘들다.
한 문자를 표현하는 바이트 표현은 다른 문자를 표현하는 어떤 바이트 표현에도 포함되지 않는다. 따라서 ASCII 문자가 아닌 값들에 투명한 파일 시스템이나 다른 소프트웨어(예를 들어서 C의 printf() 함수)와 호환성을 가진다.
바이트 표현의 첫 바이트만 사용하여 해당 바이트 표현의 길이를 결정할 수 있다. 따라서 부분 문자열을 얻는 과정이 매우 쉽다.
인코딩에 간단한 비트 연산만 사용되므로 효과적이다. UTF-8은 곱셈이나 나눗셈과 같은 느린 연산들을 사용하지 않는다.
단점
대부분의 UTF-8 문자열은 일반적으로 적당한 기존 인코딩으로 표현한 문자열보다 더 크다. 판독 기호를 사용하는 대부분의 라틴 알파벳 문자는 적어도 2바이트를 사용하며, 한중일 문자들과 표의 문자들은 적어도 3바이트를 사용한다.
한중일 문자들과 표의 문자를 제외한 거의 모든 기존 인코딩들은 한 문자에 1바이트를 사용하므로 문자열 처리가 간편한 반면, UTF-8은 그렇지 않다.