Search

'String'에 해당되는 글 2건

  1. 2011.10.14 Common Lisp는 Unicode를 처리할 수 있을까?
  2. 2011.10.14 가장 비싼 1바이트의 실수

Common Lisp는 Unicode를 처리할 수 있을까?

Language/Common LISP 2011. 10. 14. 12:02 Posted by 알 수 없는 사용자
리스프 관련 책을 읽다가 문자열에 대한 이야기가 나왔다. 문득, 리스프가 유니코드를 처리할 수 있을까 하는 의문이 들었다. 그리고 몇 가지 실험을 해보니 전혀 한글을 해석하지 못한다는 것을 알게 되었다.

하지만 분명 설정의 문제이리라.

"SBCL unicode"로 구글링을 해보니 SBCL은 이미 유니코드에 대한 지원을 하고 있다는 것을 알 수 있었다. 컴파일 때 옵션을 줄 수 있고 하는데 나는 우분투에서 패키지로 깔았으니 옵션을 켜고 컴파일 한 것인지 아닌지 알 수가 없다. 그냥 실험을 해보면 알게 되겠지.

모든 정보는 이 곳에서 얻었다. 결론은 간단하다. 우선 emacs가 기본적으로 유니코드(UTF-8)를 사용하게 하고, SLIME도 유니코드를 사용하게 설정하면 된다는 것.

Emacs의 메뉴바에서
Options -> MULE(Multilingual Environment) -> Set Language Environment -> UTF-8을 선택하고,
Options -> Save Options를 선택해서 저장
이렇게 하면 .emacs의 custom-set-variables에 '(current-language-environment "UTF-8")라는 것이 자동 추가된다. 이멕스의 언어 환경을 UTF-8로 바꿔주는 것이다.

다음으로 SLIME을 설정해야 하는데, .emacs에 다음 한 줄만 추가해주면 된다.
(setq slime-net-coding-system 'utf-8-unix)
이멕스를 다시 실행시켜 환경 변수가 적용되게 한 후, SLIME을 띄우자.
CL-USER> #\한
#\UD55C

CL-USER> "한글"
"한글"
오. 한글을 인식한다.
CL-USER> (char-code #\한)
54620
'한'이라는 글자에 대한 코드를 얻어낼 수 있다.
CL-USER> (code-char 54620)
#\UD55C
역으로 글자로 변환. 이렇게 character code를 보면 재미가 없으니 확실히 확인해보자.
CL-USER> (coerce '(#\UD55C) 'string)
"한"
모든 것이 잘 동작한다. 그렇다면 함수 이름으로 활용해보자.
CL-USER> (defun 안녕 ()
       (format t "안녕하세요.~%"))
안녕
CL-USER> (안녕)
안녕하세요.
NIL
완벽하다.

ps. CLISP를 가지고 실험해보니 CLISP에서도 모두 잘 동작한다.

가장 비싼 1바이트의 실수

Security 2011. 10. 14. 11:18 Posted by 알 수 없는 사용자
The Most Expensive One-byte Mistake라는 글을 읽었다. acmqueue에 실린 글이고 Poul-Henning Kamp가 쓴 글이다. Kamp씨는 FreeBSD 커뮤니티에서 활동하는 사람이라 괜히 정감이 간다. 각설하고.

글쓴이는 역사상 가장 큰 비용의 실수는 뭔가? 하는 질문을 던진다. IT와 CS의 역사에서 잘못된 선택으로 인해 고생했던 몇 가지 예를 서두에 언급하지만 결국 하고자 하는 이야기는 NUL-terminated text string이다.

텍스트 스트링은 상당히 자주 사용되는 자료형이다. 자바 프로그램에서 가장 많이 생성되는 객체는 String이라는 글을 읽은 적이 있다. 초기에 C를 만든 세 명은 스트링을 표현하기 위해 다음 두 가지의 선택사항을 가지고 있었다. 물론 현재에도 누군가가 언어를 설계한다면 둘 중에 하나를 선택해야 할 것이다.
  1. address + length
  2. address + magic_marker (NULL)
그들은 2번을 선택했다. 최적화라는 취지에서 2번이 좋아보였을 것이다. 길이를 저장하기 위한 별도의 공간을 마련하지 않아도 되니까.

의외로, 그 당시 많은 언어들이 1번을 채택하고 있었다고 한다. 2번을 택했던 언어는 어셈블리였다고. 앞서 언급한대로 1번은 길이를 매번 따로 저장해야 하니 비효율적일 것이다라는 느낌을 준다. 하지만 유리한 점도 있다. 데이터 복사나 이동을 할 때 대상 데이터의 크기를 즉시 알 수가 있다는 점. Cache를 활용할 때도 유리할 수 있다. 2번과 같이 매직 마커를 쓰면 마커를 찾아야 하는 비용이 높다. 크기를 미리 안다면 블록 단위의 복사를 바로 실행할 수가 있는데, 마커를 사용하면 마커를 우선 찾고 복사를 시작해야 한다. memcpy와 strcpy가 다를 수밖에 없는 이유가 되는 것이다. Constant string의 경우 컴파일러가 그 크기를 알고 있기 때문에 사용자가 strcpy를 요청해도 memcpy로 대체하여 스피드면에서 이득을 얻기도 한다고 한다.

앞서 언급한 효율의 문제를 떠나 보안의 입장에서 바라보자. 2번을 택한 것이 훗날 버퍼 오버플로우가 일어날 수 있는 여지를 주었다. 이것은 정말 큰 문제고, 저자가 이 글을 쓴 이유다. gets()의 절망적인 보안 수준은 다들 공감할 것이다.

하지만 C를 만든 Ken, Dennis, Brian을 마냥 욕할 수는 없다. 그들이 C를 만들고 15년이 지나서야 사람들은 이게 보안적인 측면에서 나쁘다는 걸 알았다고 한다. 그러니 잘못된 선택을 했다고 비난하기는 힘들지 않은가.

현재 C로 직접 프로그래밍하는 사람이 예전만큼 많지는 않다. 그러나 대부분의 언어가 C로 구현되어있다. 다른 언어로 프로그래밍을 해도 결국엔 libc가 호출되고 여전히 NUL-terminated string은 쓰인다.

그럼 이제와서라도 2번을 버리고 1번을 선택해볼 것인가? 지금까지 만들어둔 프로그램이 아깝기 때문에, 당장 모든 대체 프로그램을 만들 수가 없기 때문에 바꿀 수는 없을 것이다. 이미 만들어진 프로그램의 수보다 앞으로 만들어질 프로그램의 수가 훨씬 많음에도 바꿀 수가 없는 것이다.

ps. 처음 이 글을 쓸 때는 살아있던 Dennis가 티스토리로 글을 옮기는 현재 세상에 있지 않다. 고인의 명복을 빈다.

'Security' 카테고리의 다른 글

물건 분실을 파악하는 좋은 방법?  (0) 2011.10.14
RFID Tag Coupling  (0) 2011.10.14
HSTS: HTTP Strict Transport Security  (0) 2011.10.14
DigiNotar의 구라 인증서에 대한 대처  (0) 2011.10.14
가짜 구글 인증서  (0) 2011.10.13