본문 바로가기
책/IT과학

호랑이 담배 피우던 시절 개발자 이야기 : 행복한 프로그래밍, 임백준

by Caferoman 2023. 7. 24.

아무래도 책의 초판이 쓰여신 해가 2003년이다 보니 참신하기보다는 옛날 이야기를 듣는 기분이다 : 행복한 프로그래밍, 임백준

20년 전에 쓰인 개발자 이야기

10년이면 강산이 바뀌고 특히나 IT산업 분야의 경우 한 해가 다르게 급변하는 마당에 20년 전에 쓰인 프로그래밍에 관련된 책을 읽는 것이 무슨 의미가 있을까 의심하는 분들이 많으실 것으로 예상됩니다. 물론 저 또한 그런 의구심을 가지고 2023년에 이 책을 접하게 되었습니다.

 

돌이켜보면 2003년은 제가 학부 전공 수업을 처음으로 듣기 시작한 해이네요. 당시 한국말로 쓰여있어도 알아들을까 말까 한 Data Structures(자료 구조론), 알고리즘, 객체지향프로그래밍, 이산 수학 등의 수업들의 원서를 보며 검은 콘솔창에 코딩을 하던 시절을 떠올려 보니 뭔가 옛 추억에 젖는 기분이었습니다. 

 

프로그램을 짠다는 것은 말하자면 얼굴을 두 손에 파묻고 머리를 벽에 찧어가면서 깨달은 어떤 아름다운 공식을 컴퓨터에게 다정하게 가르쳐주는 행위다. 프로그래머가 프로그래밍 언어를 통해서 컴퓨터에게 할 일을 가르쳐주면 컴퓨터는 이 세상에서 가장 성실한 일꾼의 모습으로 주어진 일을 묵묵히 수행한다. 이렇게 컴퓨터와 단둘이 남아서 대화를 나눌 때, 혹은 컴퓨터가 자신이 시킨 일을 성실하게 수행하는 모습을 지켜볼 때, 프로그래머는 이 세상에서 가장 행복한 사람이 된다.
- 책의 본문 중

 

결론부터 말씀드리면 이 책은 최신 프로그램 동향이라던가 기법을 다룬 책은 아닙니다. 그런 책이라면 더더욱 20년 전에 출판된 책을 읽을 이유가 없겠지요. 그것보다는 프로그래머라는 정체성은 단순히 코드를 작성하는 코더(Coder)를 넘어서는 무언가 이다라는 점을 이야기로 풀어내고 있습니다. 코더(Coder)이자 설계자(Architect)이자 수학자(Mathematician)이자 공학자(Engineer)가 바로 프로그래머의 정체성이라고 할까요?

 

라이프니츠의 통찰을 계승한 사람은 프로그래머들에게는 매우 낯익은 또 한 명의 천재 수학자인 조지 불(George Boole)이었다. 컴퓨터나 수학을 전공하지 않은 사람에게도 불 대수(Boole Algebra) 혹은 논리곱(AND), 논리합(OR), 부정(NOT)과 같은 표현들은 매우 친숙할 것이다. 불이 그 당시에 오늘날의 컴퓨터와 같은 장치를 염두에 두었던 것은 아니었겠지만, 현대 디지털 컴퓨터의 근본 원리를 구성하는 이진수 체계나 AND, OR, NOT과 같은 기본적인 논리 게이트(logical gate)들은 모두 불의 연구 결과에 기초하고 있다. 참 그리고 참(T∧T)은 참, 참 그리고 거짓(T∧F)은 거짓, 참 혹은 거짓(T∨F)은 참, 거짓 혹은 거짓(F∨F)은 거짓과 같이 간단하면서도 명쾌한 논리적 정의로부터 시작되는 불의 대수 시스템은 매우 복잡한 논리를 구성하기 위해서 쉽게 확장할 수 있다는 점에서 실로 혁명적인 의의를 가지고 있다.
- 책의 본문 중

 

프로그래머의 계산기

 

프로그래머들은 숫자를 보는 관점 또한 일반인과 조금 다릅니다. 똑같은 83이라는 숫자가 입/출력으로 주어진다고 해도 해당 값이 십진수의 83인지 16진수인 0x83 인지에 따라 다르고 해당 값이 unsigned char a = 0x83 일 때와 char a = 0x83일  때의 값이 모두 다릅니다. 그래서 저 역시 개발을 하다 보면 늘 새로운 입력값을 추가할 때에 위 화면과 같이 프로그래머용 계산기를 켜놓고 작업을 하는데요, 이와 같이 숫자를 바라보는 개발자들의 다른 정의를 저자 역시 짚고 넘어가고 있습니다.

 

여담이지만 누군가가 문과생인지 이과생인지를 구분하기 위해서는 정의가 영어로 무엇이냐고 물어보는 것이라죠?

십중팔구 이과생이라면 정의를 "definition"이라고, 문과생은 정의를 "justice"라고 말합니다.

 

수학자가 들으면 펄쩍 뛸지도 모르겠지만, 프로그래머는 이진수와 관련된 계산을 수행할 때 계산을 편리하게 하려고 다음과 같은 ‘이상한’ 등식을 사용하기도 한다. 2^10 = 103 210은 1,024고, 10^3은 1,000이므로 이 등식은 수학적으로 사실이 아니다. 그러나 커다란 수를 많이 다루는 프로그래머들은 이진수와 십진수 사이의 복잡한 계산을 피하려고 이 공식을 즐겨 사용한다. 이 공식이 사용되는 예를 들자면 이런 것이 있다. 한 번에 비트 32개로 이뤄진 메모리 주소 공간을 다루는 컴퓨터를 보통 32비트 컴퓨터라고 부른다. 그런데 사람들은 비트 32개로 이뤄진 이진수로 나타낼 수 있는 최댓값이 ‘40억’이기 때문에 메모리를 최대 4GB(기가바이트)까지만 지원할 수 있다고 말한다. 그러나 이것은 사실 정확한 표현이 아니다. 비트 한 개로 나타낼 수 있는 최댓값은 1이고, 비트 두 개로 나타낼 수 있는 최댓값은 11(십진수로 3)이며, 비트 세 개로 나타낼 수 있는 최댓값은 111(십진수로 7)이다. 이러한 결과를 가만히 들여다보면 비트의 수와 그것으로 나타낼 수 있는 이진수의 최댓값 사이에는 일정한 함수 관계가 존재한다는 사실을 알 수 있다. 즉, 비트의 수가 n이라고 했을 때, 그 수만큼의 비트를 이용해서 나타낼 수 있는 이진수의 최댓값은 2n-1이다. 그렇다고 한다면 비트 32개로 이뤄진 이진수로 나타낼 수 있는 최댓값은 다음과 같을 것이다. 11111111111111111111111111111111 = 232 - 1 = 4,294,967,295 다시 말해서 사람들이 사용하는 4G(기가)라는 표현은 40억을 의미하기 때문에 실제로는 뒤에 붙어 있는 294,967,295라는 엄청난 수를 생략하고 있는 것이다. 294,967,295가 거의 3억에 가까운 수라는 사실을 생각해 본다면 3억쯤을 우습게 알고 생략하는 프로그래머들의 배짱은 엄청난 것처럼 들린다.
- 책의 본문 중

 

프로그래밍 계의 엄친아 폰 노이만

이렇게 컴퓨터의 언어, 즉 기계어를 직접 이해하고 다룰 수 있는 사람에게는 어쩌면 C, C++, 자바와 같은 프로그래밍 언어가 무의미하게 보일지도 모른다. 실제로 그러한 일화가 있다. 폰 노이만(John von Neumann)의 제자인 도널드 길리스(Donald Gillies)의 회고에 따르면, 그는 이진수만으로 구성된 기계어 프로그램을 일일이 손으로 짜 맞추는(assemble) 작업이 너무나 고통스러워서 한때 스승 몰래 기계어 코드를 자동으로 맞춰주는 소프트웨어인 어셈블러(assembler)를 제작하려고 시도한 적이 있다고 한다. 하지만 그의 계획은 노이만에게 금방 들통났다. 불같이 화가 난 노이만은 길리스에게 이렇게 말하였다고 한다. “이렇게 값지고 소중한 과학적 도구(컴퓨터)를 그따위 사무적인(clerical) 일에 사용하는 것은 터무니없는 낭비가 아닌가!”
- 책의 본문 중

프로그래밍 계의 전설적인 존재 폰 노이만은 기계어에 너무 익숙한 나머지 기계어가 있는데 포트란(FORTRAN), C와 같은 프로그래밍 언어가 왜 필요하냐는 망언 발언을 한 것으로 유명한데요. 역시 천재가 동시에 훌륭한 교사가 되는 것은 어려운가 봅니다. (그에게 프로그래밍 언어를 배웠다면...)

 

프로그래밍이라는 것은 단순한 작성 기법이나 그 표현 방식을 넘어서 어떠한 구조로 설계하는가라는 Architecture 및 Algorithm의 영역이 핵심이라고 할 수 있습니다. <아메리칸 사이언티스트(American Scientist)>가 1999년에 선정한 20세기를 빛낸 논문 12개에 이름을 올린 도널드 커누스의 저서 「컴퓨터 프로그래밍의 기술(The Art of Computer Programming)」또한 프로그래밍 언어나 코딩기법보다 정교한 알고리즘을 어떻게 프로그램화 할 것인가에 초점을 맞추고 있습니다.

 

알고리즘이라는 언어의 기원

알고리즘이라는 용어는 8~9세기 아랍에서 유명한 수학자였던 아부 압둘라 무함마드 이븐 무사 알콰리즈미(Abu Abdullah Muhammad ibn Musa al-Khwarizmi)의 이름에서 유래한 말인데 그의 마지막 이름인 ‘알콰리즈미’가 변형되어 ‘알고리즘’이 되었다는 것이 정설입니다. 여기서 주목할 점은 이 알콰리즈미가 수학자였다는 사실과 위에서 언급한 커누스 교수의 책이 수학 공식으로 가득 차 있다는 사실입니다. 결국 알고리즘은 수학의 다른 표현 방식이라는 점입니다.

 

수학을 좋아하지 않는 사람에게는 별로 반가운 소식이 아니겠지만 프로그래밍과 수학은 서로 뗄 수 없는 밀접한 관련이 있다. 컴퓨터를 탄생시킨 비트의 법칙 자체가 사실은 수학의 일부이기 때문에 컴퓨터 역사에 이름을 올리고 있는 라이프니츠, 불, 튜링, 노이만과 같은 사람들을 봐도 컴퓨터학자기 이전에 우선 수학자였다.

 

아레시보 메시지 : 인류가 외계인에게 보내는 209자의 메시지

001 010 011 100 101 110 111 1000 1001 1011

 

인류는 1974년에 푸에르토리코 북부의 항구 도시인 아레시보(Arecibo)에서 M13 성단에 사는 (혹은 살 것으로 믿는) 벗들을 향해 메시지를 보낸 적이 있다. 항구 도시의 이름을 따서 아레시보 메시지(Arecibo message)라고 불리는 이 메시지는 비트 1,679개로 이뤄져 있다. 비트 8개가 모여서 1바이트를 구성하고 1바이트는 한 글자를 표현하는 데 사용되므로 이것은 209바이트, 혹은 글자 209개로 이뤄진 대단히 짧은 메시지였다. 짧은 메시지 안에는 아레시보 망원경, 태양계, 우리의 DNA 구조, 사람의 모습, 그리고 화학 성분에 대한 정보를 포함하는 풍부한 내용이 담겨 있다. 하지만 가장 중요한 메시지의 시작 부분에는 1부터 10까지의 수를 이진수로 헤아려 나가는 방법이 적혀 있다. 우리가 M13 성단의 벗들에게 건네게 될 첫마디는 다른 것이 아니라 바로 ‘이진수’인 것이다. M13 성단의 벗들이 수학을, 혹은 이진수를 이해하고 있다면 아레시보 메시지에 담긴 우리의 모습을 볼 수 있을 것이고 그렇지 않다면 그들은 머나먼 별 지구에서 날아온 절실한 신호를 한낱 시끄러운 잡음쯤으로 여기고 그냥 지나치게 될 것이다. 001 010 011 100 101 110 111 1000 1001 1011 이것이 인류가 M13 성단의 벗들에게 보내는 인사말이다.

 

프로그래머 세계에서 최고의 고수로 통하는 사람은 복잡하고 다양한 프로그래밍 기법과 기술을 현란하게 구사하는 사람이 아니라 오히려 어려운 문제를 쉽고 간결하게 풀어나가는 사람인 경우가 많다.

 

프로그래밍 역사상 최초의 Bug

이처럼 프로그램 안에 존재하는 논리적 결함이나 실수를 ‘결함’ 혹은 ‘실수’와 같이 따분한 말로 표현하지 않고 ‘버그’라는 생동감 넘치는 말로 표현하게 된 데에는 사연이 있다. 코볼(COBOL)이라는 프로그래밍 언어의 탄생에 결정적인 기여를 한 것으로 평가되는 컴퓨터학자인 그레이스 호퍼(Grace Murray Hopper)는 1945년 여름에 마크 II라는 컴퓨터 시스템을 붙들고 씨름하고 있었는데, 계속해서 틀린 결과를 얻게 되자 그 원인을 찾기 위해서 고심했다. 우습게도 그녀가 문제의 원인을 발견한 장소는 비트의 세계가 아니라 원자의 세계였다. 컴퓨터 내부의 부속 안에 진짜 나방이 끼어서 죽어 있던 것이다.

나방을 발견한 그레이스 호퍼는 죽은 나방을 조심스럽게 꺼내서 공책의 한 페이지에 스카치테이프로 붙여놓은 다음 그 밑에 이렇게 적어놓았다고 한다.

“버그가 발견된 첫 번째 사례(First actual case of bug being found)”

 

개발자 입장에서 오동작을 일으키는 오류(Bug)를 잡아내는 과정은 꽤나 고역스러운 과정입니다. 프로그램 내부 어딘가에 문제가 있어 예상치 못한 결과값이 출력되거나 빌드에러가 발생하는 경우 이를 찾다 보면 개발자들은 종종 매우 어이없는 실수 하나 때문에 전체 동작에 영향을 미치는 것을 발견하게 됩니다. 위의 사례처럼 실제 벌레가 컴퓨터에 들어가서일 수도 있고, 세미콜론이나 오타로 인한 버그일 수도 있고요.

 

비밀번호 유출과 에니그마 머신

우리가 로그인을 할 때 사용하는 비밀번호의 경우 128가지의 문자를 가지는 ASCII(아스키) 문자 집합을 사용합니다. 결국 키보드로 입력할 수 있는 이 문자 128개 중에서 선택된 문자 몇 개로 비밀번호가 이루어지는데 128개 문자 중에서 하나일 것이므로 문자 열 개로 이뤄진 비밀번호가 만들 수 있는 전체 경우의 수는 128을 열 번 곱한 값, 자그마치 1,180,591,620,717,411,303,424로 1초에 무려 비밀번호 10억 개를 검사할 수 있는 프로그램이 있더라도 이 많은 경우의 수를 전부 시도하려면 38,382년이라는 세월이 흐르는 조합임을 언급하며 암호 해독에 관한 이야기를 다루고 있습니다.

 

단 여기서 사람들이 비밀번호에 주로 사용하는 문자 95로 한정하면 전체 경우의 1초에 10억개를 검사했을 때 앞의 38,382년에서 1,646년으로 대폭 줄어들게 됩니다. 여기서 사람들이 비밀번호에 자주 사용하는 패턴을 중점적으로 공략하게 되면 그 시간은 놀랍도록 단축됩니다.

 

존더리퍼(John the Ripper)나 아울(Owl)과 같은 유명한 비밀번호 해킹 프로그램은 바로 사전식 공격에 기초를 두고 있다. 사전식 공격이란 사전에 수록된 단어, 약자, 시사용어, 유행어, 혹은 사람들이 비밀번호를 만들 때 흔히 사용하는 전형적인 패턴(‘hello123’이나 ‘1234’ 같은)을 분석해서 커다란 데이터베이스를 구축한 다음 비밀번호를 깨뜨리는 데 활용하는 것이다. 깨뜨리고자 하는 비밀번호가 그 일부라도 데이터베이스에 저장된 이러한 문자열과 일치하게 된다면 비밀번호를 깨뜨리는 시간은 상상을 초월할 정도로 단축된다. 때에 따라서 하루 이내가 될 수도 있고, 심지어 불과 한두 시간이 될 수도 있다.

 

DK-1(EK(P)) = P

 

키 생성 함수(key generation function)에 의해서 공개 키인 K와 개인 키인 K-1이 생성되었다고 하자. 암호화 알고리즘은 E라고 부르고 해독 알고리즘은 D라고 부르자. 보내려는 정보, 즉 암호화되기 전의 평범한 텍스트(plain text, 평문)는 P라고 부른다. 암호화 알고리즘 E와 공개 키 K를 이용해서 P를 암호화한 문서는 EK(P)라고 표기한다. 이것은 암호화된 문서를 의미한다. 만약 해독 알고리즘 D와 개인 키 K-1를 이용해서 암호화한 문서 EK(P)를 해독하면 그 결과가 원래 문서인 P가 되어야 한다. 이것을 수식으로 표현하면 다음과 같다. DK-1(EK(P)) = P 이런 조건을 ‘가역성(invertability)’이라고 한다. 비대칭형 암호화 기법은 가역성 이외에도 다음과 같은 ‘비밀성(secrecy)’이라는 조건도 만족해야 한다. "K-1을 모르면 EK(P)로부터 P를 알아내는 것이 실질적으로 불가능해야 한다."

 

2차 세계대전 때 독일군이 사용한 암호 생성기인 <에니그마(Enigma)>를 통해 암호해독에 필요한 키 값을 매일 바꿔서 사용했습니다. 연합군 쪽에서 독일군 암호 문서를 해독하기 위해서 키 값을 알아야 했는데, 그러기 위해서는 원래 문서의 일부, 즉 P가 필요한 상황이었고 그 P의 내용을 알기 위해서는 매일 변경되는 키 값이 필요한 상황이었습니다.

 

하지만 이러한 난공불락의 요새와도 같은 에니그마 머신 실로 매우 어처구니 없는 작은 허점에 의해 공략되었습니다.

 

하지만 연합군에는 뜻하지 않은 행운이 따라왔다. 노르웨이 전선에 있던 독일군 부대가 본부대에 매일 똑같은 내용을 전달하고 있다는 사실이 알려졌기 때문이다. 고지식한 독일군 부대가 자신들이 사용하는 암호화 알고리즘의 정체가 드러날 위험이 있다는 사실을 상상조차 하지 못하고 매일같이 전송했던 정보의 내용은 어이없게도 “보고할 것 없음”이었다. 연합군은 그 부대로부터 전송되는 EK(P)를 가로챈 다음 P의 내용이 “보고할 것 없음”이라고 가정하고 분석하여 키 값을 찾아냈다. 그렇게 발견된 키 값이 그날 가로챈 독일군의 정보를 해독하는 데 사용되었음은 물론이다(‘보고할 게 없다’는 사실마저 ‘보고’ 해야 하는 형식주의와 관료주의의 해악을 보는 듯하다).

 

내가 짠 프로그램으로 돌아가는 비행기에 탈 자신이 있는가?

프로그래머들이 즐겨 하는 질문이 하나 있다. “네가 만든 소프트웨어가 조종하는 비행기에 올라탈 자신이 있는가?” 진정한 프로그래머라면 “그렇다”라고 대답할 수 있어야 한다. 만약 올라탈 자신이 없다면 그런 소프트웨어를 팔아서 돈을 벌 생각을 하지 말아야 한다. 만약 그런 소프트웨어를 팔았다면 최소한 그 소프트웨어가 일으키는 문제에 끝까지 책임져야 한다. 그것은 프로그래머로서의 자존심을 떠나서 비즈니스를 하는 사람이라면 당연히 지켜야 하는 기본적인 도덕에 해당한다.

자동차 인포테인먼트 소프트웨어를 개발하는 1명의 개발자의 입장에서 내가 짠 프로그램의 무결성과 충실도에 대한 확신이 있는가에 대한 질문은 아래 질문 하나로 정리됩니다.

 

"내가 짠 프로그램이 들어간 차를 탈 자신이 있는가?, 혹은 그 차를 사고 싶은가?"

20년 전에 나온 프로그래밍에 관한 책이라 괜히 시간낭비하는 것 아닌가 하는 걱정이 없었던 것은 아니지만, 프로그래밍의 본질과 이 업의 특성상 웃지 못할 에피소드들을 읽어가는 과정은 꽤나 즐거웠습니다.

반응형

댓글