티스토리 뷰

이번에 Bash에서 히스토리 전방 증분검색 단축키 (Ctrl-S)가 왜 안 먹는지 이유를 알아보고 나서, 아스키 제어코드를 좀  알아보다가 삼천포로 빠져서 아스키 코드표를 만들게 됨...


원본 SVG파일은 여기에서 받을 수 있다.


그냥 눈치챌 수 있겠지만

붉은 바탕 - 제어문자

노란 바탕 - 공백

초록 바탕 - 기호

보라 바탕 - 숫자

파란 바탕 - 알파벳

이다. C라이브러리 기준.

출력 가능한 문자는 32번 ~ 126번까지다.


이제 아 아스키 표에 관한 썰을 풀어나가자 ~_~


가장 많이 사용할 것 같은 원리는 숫자와 알파벳 순서와 대소문자 전환이다. 이 아스키 표를 보는 당신은 이미 프로그래밍을 배우고 있을 확률이 매우 높다고 생각한다.

아스키에서 숫자를 순서대로 할당해 놓아서 생기는 이점이 '5' - '0' = 5가 된다는 것. 그러고 grade = 'A' + 5; 같은 C언어 연산이 친숙한 사람이 꽤 될 거라고 생각한다. (C언어 뿐만이 아니라 C계열 언어 - C++, Java, C#, D 등등 전부 이런 식이다)

대소문자 전환도 'a'가 있다면 32를 빼면 97 - 32 = 65 = 'A', 대문자는 반대로 더하기 연산으로 손쉽게 해결할 수 있다.

근데 재밌는 것은, 32는 2의 승수고, 때문에 위 표에서 알파벳 대소문자 각각이 옆으로 2칸 차이가 난다는 것이다..

일단 32에 해당하는 비트가 여섯째 비트, b6이다. 이 b6만 바꿔주면 알파벳 대소문자 변환은 저절로 된다. 예를 들자면

'C' = 1000011(2)

'c' = 1100011(2)

이런 식이다. 즉 대소문자 변환 연산은 덧셈뺄셈 뿐만 아니라 비트 연산으로도 구현할 수 있다.

대소문자를 바꾸는 연산은 ch ^= 0x20; 이 한 줄 만으로도 가능할 것이라고 생각한다.


한국어 위키에보면 1967년에 제정된 표준이라고 나온다. 그 당시엔 컴퓨터보다 타자기가 더 흔했을 것 같다. 그래서인지 제어코드는 역사적인 의미만 있고 사장되었다고 하는데, 알게 모르게 쓰고있는 것도 꽤 되는 것 같다.


어떻게 확인할 수 있냐면, 위에서 본 대소문자 변환 원리같이 제어문자도 비슷하게 대응이 되기 때문이다.

영문 위키에서도 나왔다시피, 컨트롤 키를 눌러서 제어문자를 표현할 수 있다. 이 컨트롤 키가 하는 역할이 뭔가 살펴보면, 맨 위 비트 b7을 0으로 바꿔주는 것이다. 대문자 알파벳에서 4칸 왼쪽으로 이동과 동일하다.

예를 들자면 Ctrl-I (^I로 표기할 수도 있다)의 경우

'I' = 1001001(2) = 73

^I = 0001001(2) = 9 = Horizontal Tab

이 된다. 당장 메모장열고 Ctrl-I를 눌러도 탭이 눌리는 걸 확인할 수 있다.


이런 제어문자들의 활용 예를 기록해보기로 한다. 아마 원래 아스키코드의 의미하곤 차이가 있을 수 있겠지만 (시대가 달라졌으니...) 비슷하게 사용하려고 한 예를 찾을 수 있다.


0 = 0x0: NULl character (^@)

의미는 알겠지만, 실제로 타이핑할 일은 없었다.


1 = 0x1: Start Of Header (^A)

2 = 0x2: Start Of Text (^B)


3 = 0x3: End Of Text (^C)

윈도우즈 명령프롬프트(이하 cmd)나 리눅스 터미널에서 누르면 프로그램 강제 종료 효과가 있다.

원래 그런용도였는지는 모르겠지만, 나중에 보면 의미가 살짝 달라도 비슷한 걸 끼워맞추는 경우가 왕왕 있다.


4 = 0x4: End Of Transmission (^D)

리눅스 터미널에서 입력 중일 때 입력하면 입력 종료로 인식한다. cmd는 ^Z를 쓴다.


5 = 0x5: Enquiry (^E)

6 = 0x6: Acknowledgment (^F)


7 = 0x7: BELl (^G)

cmd에서 echo ^G를 입력하면 소리가 정말 들린다. 아마 터미널도 마찬가지일 거라고 생각.


8 = 0x8: BackSpace (^H)

역시 cmd하고 터미널에서 백스페이스로 동작한다. (설정에 따라서 달라질 순 있겠지만 대개는)

vi에디터에서 커서를 왼쪽으로 옮기는 키로 쓰는데, 이 제어문자의 의미가 반영된 듯 하다[각주:1].

(마찬가지로 J, K도 그런 듯. L은 그냥 위치상 선정된 듯?)


9 = 0x9: Horizontal Tab[f] (^I)

위에서 설명함 ㅇㅅㅇ


10 = 0x0A: Line feed (^J)

1965년도 표준... 이라고 위에서 언급했었다. 그만큼 타자기의 영향도 무시할 수 없는데, 이 문자가 바로 그런 영향을 받았다고 볼 수 있다.

 manual typewriter 

출처: Penguin Pete's Blog


이 사진이 아주 잘 설명하고 있다고 생각하는데, 타자기에서 타이핑을 하면 왼쪽에서부터 캐리지가 이동하면서 순서대로 문자를 쓴다. 그러다가 종이 오른쪽 맨 끝에 도달하면 다시 캐리지를 맨 왼쪽으로 돌려놔야 한다. 이걸 캐리지 리턴Carriage Return이라고 한다. 근데 CR만하고 다시 치면 쳤던 줄에 또 치게 되므로, 왼쪽에 Line-feed 레버로 (미는 걸까 당기는 걸까 누르는 걸까...) 종이를 한 줄 위로 올려준다. 이 개행 작업을 CR/LF로 표현할 수 있다.


하지만 굳이 개행이 2문자가 필요한 게 아니라서... 맥은 CR, 윈도는 CR/LF, 리눅스는 LF를 쓰는 파국이 도래했다.


11 = 0x0B: Vertical Tab (^K)

사실상의 표준으로 탭 키는 8글자, 이 수직 탭 키는 6줄 이동이라고 하는 것 같다.

Bash에서는 커서 뒤 문자들을 없애주는 역할을 하던데, 연관이 있는 걸까 ㅡㅡ?


12 = 0x0C: Form Feed (^L)

프린터에 이 문자를 입력하면 종이를 그냥 내보낸다고 영문 위키에 나와있다. 역할은 이게 맞을테고.

Bash에서 ^L을 입력하면 화면을 비워준다. 비슷하게 단축키를 배정했다고 볼 수 있겠다.


13 = 0x0D: Carriage Return (^M)

이미 10. LF에서 설명을 다 한 것 같다.

cmd에선 ^J가 아니라 ^M을 입력해야 개행이 되더라.


14 = 0x0E: Shift Out (^N)

15 = 0x0F: Shift In (^O)

사용자가 지정한 확장 인코딩이 시작된다는 의미.. Shift Out과 함께 HTML태그처럼 쓴다.


16 = 0x10: Data Link Escape (^P)

뭐지..


17 = 0x11: Device Control 1 (^Q)

XOFF. 설명은 19번에.


18 = 0x12: Device Control 2 (^R)


19 = 0x13: Device Control 3 (^S)

내가 이 포스팅을 쓰게 한 참 장한(?)문자.

XON으로 쓰기도 한다고 위키에 설명이 있는데, 리눅스 터미널에서 이 DC3을 '버퍼가 꽉 찼으니 나중에 결과를 보내 주세요'라는 의미로 이미 쓴다고 한다. putty에서 가끔 입력이 안 되는 경우가 이 ^S를 눌렀을 때가 다반사다.

이 키가 Bash단축키도 막고 있어서 문제가 됐었다.


20 = 0x14: Device Control 4 (^T)


21 = 0x15: Negative AcKnowledgement (^U)



22 = 0x16: SYN (^V)

TCP를 배우면 알 수 있을까...?


23 = 0x17: End of Transmission Block (^W)



24 = 0x18: CANcel (^X)


25 = 0x19: End of Medium (^Y)


26 = 0x1A: SUBstitute (^Z)

치환이라는 의미를 가지곤 있지만, 실제 의미는 이 장치에서 표현 불가능한 문자(즉 에러)라는 뜻이라고 한다.

흔히 쓰는 실행 취소는 의미하고 완전히 동떨어진 것 같고, 그나마 가까운게 cmd에서 이걸 End Of File로 사용한다.

리눅스에선 '현재 작업을 백그라운드로 전환'하는 역할을 가지고 있다.


27 = 0x1B: ESCape (^[)

뒤에 있는 문자를 확장해주는 역할. 터미널에서 추가적인 단축키로 쓸 수 있다.

Putty에서 Alt-B와 ^[B가 같은 역할을 하더라. 설정인지는 모르겠지만.

이 키에 관한 내 기억은, vim에서 매우 유용하다는 것이다.


28 = 0x1C: File Separator (^\)

29 = 0x1D: Group Separator (^])

30 = 0x1E: Record Separator (^^)

31 = 0x1F: Unit Separator (^_)

데이터를 구분할 때 쓰는 용도 같다.

어쩌다가 제어문자를 만나게 되면 여기에 더 기록할 생각이다.


안 적힌 부분이나 잘못된 부분은 댓글 환영~


  1. https://news.ycombinator.com/item?id=3684515 [본문으로]
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함