NFC의 장단점?

Security 2011. 10. 14. 12:50 Posted by 알 수 없는 사용자
다음의 짧은 논문을 읽고 떠오른 생각들 정리해본다. Vassils Kostakos, et al. "NFC on mobile phones: issues, lessons, and future research", 2007

NFC의 편의성

두 폰이 서로 데이터를 주고 받을 일이 있을 때, 블루투스나 NFC를 이용할 수 있다. 논문에서는 두 가지를 이용해서 전화번호를 교환하는 프로그램을 각각 작성한 후에 사람들에게 얼마나 편리한지 질문했다. (실험 결과에 대한 구체적인 이야기가 없었지만!) 전반적으로 NFC가 편리하다는 평이었다고 한다. 그 첫 번째 이유는 사용자가 별로 할 일이 없다는 것. 블루투스는 기기 간의 페어링(pairing)을 해야 한다. 반면 NFC는 접촉만으로 바로 데이터 교환이 가능하다. 단, NFC는 읽고 쓰기 중 하나를 선택하여 단방향(one-way) 통신만 가능하기 때문에 사용자가 개입하여 내가 데이터를 받을 것인지 줄 것인지를 선택해야 하는 문제가 있는데, 여기서는 두 장치가 서로 번갈아가며 주고 받기를 서로 알아서 하도록 프로그래밍했기 때문에 사용자가 할 일이 거의 없었다. 사용자 입장에서는 폰을 서로 갖다대는 것만으로 데이터 교환이 되는 것이 신기하고 편리했을 것이다. 그리고 이것이 두 번째 이유로 연결되는데, 터치로 데이터를 교환하는 것은 블루투스를 이용한 원격(물론 멀지 않은 거리지만) 교환보다 더 원시적인 방법처럼 보이지만 오히려 '중간에 다른 디바이스가 끼어들어 내 정보가 세어나가진 않을까?' 하는 우려를 줄여준다. 내가 보고 있는 상대방과 정확히 정보를 교환하고 있다는 느낌을 사용자에게 주는 것이다. NFC가 근거리 통신 방식이기 때문에 보안 측면에서 유리하다는 것은 이미 많이 언급된 내용이다.

QR code와의 비교

NFC를 사용하면 태그를 폰에 접촉하는 것만으로 바로 데이터를 가져올 수 있다. 반면 QR code를 읽기 위해선 카메라를 이용하는 리더 앱을 가동해야 하는 번거로움이 있다. 얼마전에 코엑스에 갔을 때 재밌게 본 시연이 있었는데, TV에서 나오는 아이유의 음악에 폰이 가까이 두니 관련 링크를 열어 보여주는 것이었다. 물론 여기에 사용된 아이유의 음악은 사람이 듣지 못하는 주파수 영역에 데이터를 주입해서 보내는 것이었고 폰은 그것을 듣고 데이터를 뽑아내는 것이었다.  아이디어는 재밌으나 폰에서는 데이터를 해석할 수 있는 앱을 역시 가동하고 있어야 한다. 이 앱은 카메라 대신에 마이크를 켜두고 있어야 한다는 것이 차이점일 뿐이다. 결국 사용자 편의성 면에서는 QR code와 별다른 차이가 없다고 볼 수 있다.

NFC의 단점? 1. 화면과 멀어지는 사용자

태그를 읽기 위해 - 혹은 다른 NFC 장치에게 데이터를 전송하기 위해 - 서는 접촉을 해야 하므로, 내 폰을 내 눈과 먼 거리에 두어야 할 경우가 발생할 수 있다. 데이터 교환 상황이나 완료 여부, 에러 발생 여부 등을 알아보기가 다소 힘들 수 있다. 물론 예로 든 수준의 알림은 화면에 큰 글자를 출력하거나 깜빡임을 이용하거나 소리를 내거나 진동을 발생시킴으로써 해결할 수 있다. 그러나 화면을 터치함으로써 어떤 interaction을 이어나가야 하는 경우라면 작업을 진행하기에 까다로워질 수 있다.  선택 버튼을 눌러야 한다거나 패스워드를 입력해야 한다거나 따위가 예가 될 수 있다. 결론적으로 interaction이 많은 작업보다는 접촉만으로 바로 데이터가 교환되고 바로 통신이 종료되는 어플리케이션이 적합하다.

NFC의 단점? 2. 악성 데이터

이 문제는 사실 NFC 만의 문제는 아니다. NFC를 이용할 때도 역시 조심해야 한다 정도가 좋겠다. 태그로부터 읽히는 정보에는 스팸이나 악성 페이지로의 링크가 있을 수 있어 주의해야 한다. 조금 더 주의를 기울여야 하는 부분은 태그로부터 정보를 읽어오는 것뿐만 아니라 어떤 명령을 받아들일 수도 있다는 점이다. 어떤 사람의 명함에 폰을 대면 바로 그 사람에게 전화가 걸리거나 이메일을 보내거나 문자를 보낼 수 있도록 폰이 동작하는 것이 그 예가 되겠다. 접촉을 하는 즉시 폰이 어떤 행위를 하게 되는 것은 편리할 때도 많지만 악성 행위를 동작시키는 태그가 이용될 수도 있기 때문에 주의해야 한다

'Security' 카테고리의 다른 글

Cloud Computing  (0) 2011.12.19
NFC 어플리케이션  (0) 2011.10.14
물건 분실을 파악하는 좋은 방법?  (0) 2011.10.14
RFID Tag Coupling  (0) 2011.10.14
가장 비싼 1바이트의 실수  (0) 2011.10.14

텍스트 파일에서 한글 글자만 뽑아내기 by Clojure

Language/Clojure 2011. 10. 14. 12:47 Posted by 알 수 없는 사용자
해결하고자 하는 문제는 텍스트 파일에서 한글 글자만 뽑아내는 것이다. 문서에 "한글은 영어로 Korean이라 합니다."라는 내용이 있다면 (한 글 은 영 어 로 이 라 합 니 다) 라고 뽑아내고 싶다는 것. 그리고 글자의 중복이 있으면 제거한다.  위 예제에는 중복이 없다. 코드는 아주 간단하다.
(ns korean-word-extractor.core
  (:gen-class))

(defn -main [& args]
  (let [file-name (first args)
        file-contents (slurp file-name)
        korean-chars (distinct (filter #(<= 0xAC00 (int %) 0xD7AF) (seq file-contents)))] ;; 0xAC00 ~ 0xD7AF: Hangul Range
    (println korean-chars)))
파일명은 argument로 받기로 하고, slurp을 이용해 모든 내용을 일단 얻어온다. 그 다음 한 줄의 코드가 사실 모든 일을 다 하게 되는데, 과정은 다음과 같다.
  • 우선 clojure에서는 문자열에 seq 함수를 적용하면 바로 개별 문자를 list로 활용할 수 있다.
  • 그 다음 한글을 필터링 해야 되는데 filter 함수를 사용할 수 있다. 0xAC00 ~ 0XD7AF는 Unicode의 한글 음절 범위이다. Unicode.org의 Hangul Syllables 문서를 보면 잘 나와있다.
  • 한글 문자만 뽑아내는데 성공했으니 중복된 문자를 제거하면 된다. distinct 함수를 활용하자.
문제가 해결되었다.
한글과 English가 섞여 있을 경우
한글만 extract할 수 있을까?
라는 내용을 담고 있는 test.txt 파일을 만들고 실행해보면,
>lein run test.txt
(한 글 과 가 섞 여 있 을 경 우 만 할 수 까)
와 같이 원하던 결과를 얻게 된다.

NFC 어플리케이션

Security 2011. 10. 14. 12:42 Posted by 알 수 없는 사용자
다음 논문을 읽고 남기는 생각.
Csapodi, M.; Nagy, A.; , "New Applications for NFC Devices," Mobile and Wireless Communications Summit, 2007. 16th IST , vol., no., pp.1-5, 1-5 July 2007
doi: 10.1109/ISTMWC.2007.4299077
URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4299077&isnumber=4299029
NFC의 장점으로 매번 이야기하는 것은
  • 네트워크를 따로 구성하지 않아도 된다는 것
  • 비교적 빠르다는 것
  • 아주 근접한 상태에서만 통신이 되기 때문에 안전하다는 것
정도이다. 간단히 줄이면 "Simple and Secure". 이러한 장점으로 기기 간의 상호 인증을 할 때 NFC는 좋은 수단이 된다. 직접 터치하는 방식이기 때문에 man in the middle attack, eavesdropping에 다른 방법론보다 비교적 강하다. 기기 간 상호 인증 (키 교환)을 자연스럽게 사람이 개입하여 인증해주게 되는 것이다.

NFC는 2002년 가을 Sony와 Phillips, 두 회사가 협정한 기술이라 한다. 둘은 ECMA Internation에 표준 초안을 제출하는 것을 시작으로 표준화를 진행했고 두 개의 프로토콜 NFCIP-1, NFCIP-2가 각각 ISO/IEC 18092, ISO/IEC 21481로 제정되었다. NFC 포럼이 2004년 3월 설립되어 HP, NXP (Phillips), Sony, Texas Instruments, Nokia, NEC, Samsung, Motorola, MasterCard, VISA, Panasonic, Microsoft, Gemalto, Vodafone, Siemens 등이 참여하고 있다고. 모바일 통신 업체 그리고 통신 기기를 만드는 업체가 포함되어 있다. 개인적으로 재밌는 건 MasterCard, VISA가 참여하고 있는 것인데, 모바일 결제를 할 때 비교적 안전하고 신속하게 통신 과정을 진행 할 수 있다는 점에서 NFC가 모바일 결제 분야에서 핵심 기술로 인정받고 있다는 것을 알 수 있다.

NFCIP-1 프로토콜은 Philips의 Mifare 기술과 Sony의 FeliCa contactless IC card 기술과 호환된다고 한다. 각자 기술을 개발하다가 둘을 아우르는 프로토콜을 만들게 된 것 같다. 두 기술은 이미 교통 카드나 출입 보안 카드 등에 사용되고 있었다고 한다.

NFC의 접촉 범위는 20cm 정도.

많은 양의 통신이 필요하거나 빠른 통신이 필요한 경우 블루투스나 와이파이 등 기존 기술을 사용하는 것이 좋은데, 이런 설정을 두 기기가 빠르게 공유하기 위해서 NFC가 역시 좋은 수단이 된다.

NFC가 passive mode를 제공한다는 것도 장점이다. 모바일 기기는 배터리에 민감하기 때문에 one party의 파워로 양쪽이 통신할 수 있는 것은 큰 장점이다. NFC 통신을 할 때 한 쪽이 모바일, 한 쪽이 전원을 공급 받는 고정된 기기인 경우 이 성질은 큰 장점으로 작용할 것이다.

NFC가 탑재된 두 기기 간의 데이터 교환이 NFC를 이용한 주된 어플리케이션이지만 조금 구체적으로 응용한 예가 논문에 몇 가지 언급된다. 그 중 하나 재밌는 것은, PC와 연동하여 내 패스워드 정보 - 를 비롯한 웹 폼을 채울 수 있는 정보 - 를 내가 폰을 PC와 접촉시켜 둔 동안에만 해당 PC에서 적용되게 하는 것이다. 도서관 등의 공공 컴퓨터에 갔을 때 웹 서핑을 하게 되면 모든 웹 사이트에서 로그인을 다시 해야 한다. 귀찮지만 당연히 해야 하는 작업이다. 내 폰을 PC 옆에 마련된 NFC reader 위에 올려둠으로써 모든 로그인 절차가 자동으로 된다면 편리하지 않겠는가? 물론 폰을 분실했을 경우, 도난 당했을 경우가 아주 위험해진다.

위의 예처럼 터치를 통한 사용자 또는 기기 인증의 개념이 도입되면 폰이 일종의 보안 토큰이 되는 것이다. 클라우드 컴퓨팅이 발전하고 점차 컴퓨팅 기기는 네트워크가 가능한 더미 터미널이 되어가는 추세(크롬북이 얼마나 성공할 지는 모르지만) 라고 봤을 때, NFC 덕분에 거의 모든 사람이 소지하고 있는 스마트폰을 보안 토큰으로 활용할 수 있게 된 점은 확실히 사용자 편의성을 높이는데 한 몫을 할 수 있을 것이라 생각한다.

'Security' 카테고리의 다른 글

Cloud Computing  (0) 2011.12.19
NFC의 장단점?  (0) 2011.10.14
물건 분실을 파악하는 좋은 방법?  (0) 2011.10.14
RFID Tag Coupling  (0) 2011.10.14
가장 비싼 1바이트의 실수  (0) 2011.10.14

Common Lisp (SBCL) on Windows 7

Language/Common LISP 2011. 10. 14. 12:26 Posted by 알 수 없는 사용자
Common Lisp를 사용하기에 최적의 환경은 역시 리눅스. 최근 우분투가 참 많이 좋아졌고 많은 프로그램들이 리눅스를 지원하니 사용에 심각한 불편함은 없으나 역시 대한민국에서는 윈도우가 편하다.

윈도우 환경에서 리스프를 즐기기 위해서 clojure를 써보는 방법도 있지만 common lisp는 아니기 때문에 좀 애매하다. 돈을 주고 쓸 수 있는 것들은 윈도우용을 제공하지만 무료로 사용할 수 있는 것들 중 쓸만한 것인 clisp나 sbcl은 아직 공식적인 윈도우 버전을 제공하지 않는다. 뭐, 아직 공부 단계이니 돈 주고 사기는 아깝고, 원래 쓰던 sbcl을 사용하기로 했다.

sbcl은 아직까지는 윈도우 환경에서 "Available and Supported" 단계가 아니다. 포팅 중으로 표시되어 있다. 그럼에도 불구하고 설치는 간편하게 할 수 있도록 설치 파일을 제공한다. 인터넷 상의 여러 글에서, 아직은 불안정하다는 이야기를 많이 봤지만 얼마나 불안정한가는 더 사용해봐야 알 수 있겠다. 개인적으로는 간단한 코드를 돌려보는 수준이기 때문에 특별한 버그를 만나진 못했다.

우선 emacs windows 버전은 여기서 다운로드 받을 수 있다. 가장 최근의 bin 버전을 받는 것이 좋다. emacs는 설치파일을 제공하지는 않으며, zip으로 압축되어 있다. 받은 후에는 bin 폴더에 있는 바이너리를 직접 실행하여 사용하면 된다.

SLIME은 이 곳에서 받을 수 있으며 cvs snapshot을 받을 수 있다. SLIME을 다운 받은 후에는 최대한 path 설정이 간편한 곳에 두는 것이 좋다.

SBCL은 여기에서 받을 수 있다. windows 용을 클릭하여 다운로드 후 실행하면 설치된다. 설치할 때 주의할 점은 역시 설치될 경로 설정이다. 최대한 단순하게 하자.

경로를 단순하게 해야 하는 이유는 후에 emacs에서 경로를 설정할 때 공백이 들어간 경로나 긴 이름의 경로를 잘 해석하지 못하는 경우가 발생하기 때문이다.

리눅스에서는 홈 디렉토리에 .emacs에 설정 파일을 두면 되지만 윈도우의 경우에는 어디에 .emacs가 위치할까? 이것을 알 수 있는 간단한 방법은, 이멕스를 실행한 후 Options에서 아무 옵션이나 변경한 후 Save Options를 하면 어느 파일에 저장했는지가 아래 미니 버퍼에 나온다. 보통은 자신의 홈 디렉토리의 AppData/Roaming/.emacs 에 위치한다. 예를 들면 C:/Users/kju/AppData/Roaming/.emacs

.emacs의 위치를 찾았으니 이 파일을 수정하면 된다. 여기에 추가할 코드는 다음과 같다.
(setq inferior-lisp-program ""C:/Users/kju/SBCL/sbcl.exe")
(add-to-list 'load-path "C:/Users/kju/slime-2011-10-13")
(require 'slime)
(slime-setup '(slime-repl))
SBCL과 SLIME의 위치를 지정하는 것이다. 경로가 간단하면 좋은 이유가 여기에 있다. 그리고 경로에 공백이 있을 경우 실행되지 않는 경우가 많다. 경로를 설정할 때 한 가지 주의할 점은 폴더 구분자를 \이 아니라 /를 사용해야 한다는 점이다. 역슬래시를 사용할 경우 escape 문자로 인식하여 오류가 발생한다.

설정 후 M-x slime 해보고 REPL이 정상적으로 실행되면 끝.

ps. 리스프 코딩을 할 때 괄호가 조금 연하게 출력되면 소스코드를 보기에 편하다.
(defface paren-face
  '((((class color) (background dark))
     (:foreground "grey30"))
    (((class color) (background light))
     (:foreground "grey60")))
  "Face used to dim parentheses.")
(add-hook 'emacs-lisp-mode-hook
       (lambda ()
         (font-lock-add-keywords nil
                     '(("(\\|)" . 'paren-face)))))
(add-hook 'slime-mode-hook
       (lambda ()
         (font-lock-add-keywords nil
                     '(("(\\|)" . 'paren-face)))))
를 .emacs에 추가해서 괄호를 연한 회색으로 만들 수 있다. grey뒤의 숫자를 조정하여 입맛에 맞게 설정하자.

[Common Lisp code example] Euclid algorithm: GCD 찾기

Language/Common LISP 2011. 10. 14. 12:05 Posted by 알 수 없는 사용자
두 수의 최대공약수(GCD)를 찾는 유클리드 알고리즘은 널리 알려져있다. 이 알고리즘을 리스프로 옮겨보자. 우선 코드를 보자.
(defun euclid (a b)
  (labels
      ((euclid-gcd (a b)
(if (zerop b)
    a
    (euclid-gcd b (mod a b)))))
  (let* ((gcd (euclid-gcd a b))
  (lcm (/ (* a b) gcd)))
      (values gcd lcm))))
이 코드는 최대공약수 뿐만 아니라 최소공배수까지 얻어내는 함수다. 실행 결과는 다음과 같다.
CL-USER> (euclid 462 1071)
21
23562
두 수를 받아야 하기 때문에 파라미터를 a, b로 둔다. labels는 함수 내에서 이용할 로컬 함수를 다시 정의할 수 있도록 해준다. euclid 함수 내에서 euclid-gcd를 다시 정의한 이유는 GCD를 우선적으로 얻어낸 후 이를 이용해 LCM값까지 출력해주기 위함이다.

euclid-gcd는 두 파라미터 a, b를 그대로 이용해서 recursive 호출을 이용해서 GCD를 얻어낸다. labels로 함수를 정의한 후에는 let* 함수가 나오는데, let*는 로컬 변수를 선언하는 역할을 한다. 위에서 정의한 euclid-gcd를 이용해서 얻는 GCD값을 gcd라는 변수에 넣고, 이 gcd를 이용해서 최소공약수를 얻은 후에 lcm 변수에 할당한다. 얻어낸 gcd값을 바로 아래 라인에서 lcm을 얻는데 사용하기 때문에 let* 함수를 사용한다. 그렇지 않은 경우엔 let을 사용하면 된다.

gcd와 lcm 변수에 각각 최대공약수와 최소공약수를 할당한 후에 이 값을 돌려줘야 되는데 리스프에서는 여러 개의 값을 돌려줄 수 있다. 그 방법이 가장 마지막 줄에 있는 values 함수를 이용하는 것이다.

실제 실행했을 때 21, 23562 두 수가 연속으로 리턴되는 것을 볼 수 있는데, values가 두 값을 넘겨주기 때문이다.

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에서도 모두 잘 동작한다.

Common Lisp에서 패키지 다시 컴파일하기.

Language/Common LISP 2011. 10. 14. 11:58 Posted by 알 수 없는 사용자
아. 리스프는 정말 쉽지가 않다. 언어 자체는 너무 마음에 들지만 패키지를 사용하는 것에서 상당히 혼란스럽다. 리스프의 패키지 시스템이 나빠서라고 말하기는 힘들다. ASDF라는 좋은 시스템을 가지고 있다.

단, 문제가 되는 것처럼 보이는 건 common lisp에 대한 구현이 많다는 점이다. Lispworks, Allego CL, SBCL, CLISP, CMUCL 등등. 이들은 물론 표준을 따르고 있지만 모든 구현들이 동일하게 동작하지는 않는다. 그럴 수도 없다. 구현물마다 다른 추가 구현도 가지고 있기도 하고. 이 때문에 다른 사람의 코드를 받아서 사용하려하면 오류가 발생하는 경우가 꽤 있다. 해커들에게는 또 하나의 즐거움일 수도 있지만, 입문자인 나에겐 참 힘든 일이다.

Perl, Python 등의 알려진 언어들은 보통 가장 널리 사용되는 하나의 구현을 가지고 있다. 또한 패키지 관리 시스템도 가지고 있으니 이런 점에서는 매우 편리하다. 괜히 이런 언어들이 많이 사용되는 것이 아니라는 것을 다시 한 번 느꼈다. 많이 사용되니 그만큼 잘 되어 있는 것일 수도 있겠지만.

서론이 길었다. 오늘 여기에 남기려고 하는 팁은 패키지를 다시 컴파일 하는 방법이다. 이걸 찾아보게 된 이유는 bordeaux-threads라는 패키지 때문이다. (이름도 어렵다. 사실 '보르도'라는 지명이야 잘 알고 있지만 불어다보니 참 단어의 철자가 안 외워진다.) 이 패키지를 컴파일 하고 잘 사용하고 있었는데, 무슨 문제가 있었는지, 다른 패키지가 이 패키지를 건드린 것인지, 갑자기 함수 하나가 동작하지 않았다. bordeaux-threads:make-thread 라는 함수이다. 이 함수가 갑자기 undefined라는 것이다. 정의되어 있다고 search는 되는데 실행하면 없는 함수라니.

이 함수를 로드하면 이미 컴파일이 되어 있기 때문에 컴파일된 fasl을 로드하게 되고 문제는 반복되었다. 그렇다면 다시 컴파일 하면 해결되지 않을까 생각했다. 방법은 다음과 같다.
(asdf:operate 'asdf:load-op 'bordeaux-threads :force t)
ASDF를 이용해서 피키지를 로드하는 코드와 거의 같은 코드다. :force라는 키워드를 추가하는 것 뿐이다. 이렇게 하면 처음 패키지를 가져올 때 하는 것처럼 컴파일을 다시 하게 된다.

우분투에서 리스프 패키지 직접 설치하기

Language/Common LISP 2011. 10. 14. 11:54 Posted by 알 수 없는 사용자
이 글이 쓰여지는 현재의 환경은 SBCL, 우분투 10.04이다.

우분투의 시넵틱 패키지 관리자를 이용하면 slime이나 emacs, sbcl 등을 쉽게 설치할 수 있다. cmucl은 현재 - 왜 그러한지 모르겠지만 - 존재하지 않지만 clisp도 제공하고 있다.

우분투의 패키지 관리 시스템에서 common-lisp 관련 라이브러리들은 cl- 로 시작된다. 예를 들면 cl-md5와 같은 패키지가 있으며 이를 설치하면 /usr/share/common-lisp/ 하에 설치되어 활용할 수 있게 된다. 여기에 설치되는 패키지들은 모두 common-lisp-controller가 관리하는데, sbcl을 설치하면 자동으로 이 패키지가 설치될 것이다. 이 패키지의 기능은 어떤 lisp implementation을 사용하든 상관없이 라이브러리를 활용할 수 있도록 하기 위함이다.

sbcl에서는 (require 'package-name)을 하면 사용할 수 있고 clisp와 같은 경우에는 (clc:clc-require 'package-name)을 사용하면 된다. sbcl은 아마 clc-require를 기본으로 hook하고 있는 듯 하다.

문제는 우분투에서 모든 lisp 관련 패키지를 제공하지 않는다는 것에 있다. 누군가가 패키지를 만들어주기를 하릴없이 기다릴 수는 없는 법. 직접 패키지를 다운 받아 설치하는 수밖에. 예를 들면 cl-fad나 hunchentoot와 같은 패키지는 제공되지 않는다.

조금 의외인 것은 직접 설치하는, 이 과정이 생각외로 매우 간단하다는 것이다. SBCL을 사용하기 때문인지는 잘 모르겠으나 아직까지 동작하지 않는 패키지를 만나지 못했다. 이렇게 간단히 문제가 해결되는 이유는 이전에도 이야기한 바 있는 ASDF라는 시스템 때문이다. 대부분의 리스프 라이브러리가 ASDF를 지원하고 있기 때문에 이를 이용하면 쉽게 사용할 수 있게 된다.

방법은
  1. 필요한 라이브러리를 다운로드 한다. 대부분은 .tar.gz으로 묶여있지만 가끔은 cvs로 제공하거나 git을 사용하기도 한다. 어떤 경로든 무관하며 다운로드한 소스코드를 내가 두고 싶은 어느 디렉토리든 두면 된다. 내 경우에는 ~/asdf/ 에 모든 라이브러리 소스코드를 둔다.
  2. 홈 디렉토리에 .clc나 .sbcl이라는 디렉토리를 만든다. clc는 앞서 말한 common-lisp-controller의 약자다. 가능하면 .clc로 만드는 것이 좋을 듯 하다. 그러면 다른 lisp implementation에서도 사용할 수 있기 때문이다.
  3. (.clc로 만들었다고 가정하고) .clc내에 systems라는 디렉토리를 하나 만든다. 결론적으로 ~/.clc/systems/ 를 만드는 것. .sbcl을 만들어도 동일하다. systems라는 디렉토리를 그 안에 만든다.
  4. 이 systems/ 디렉토리 안에서 다운로드한 소스코드 중 한 파일로 심볼릭 링크를 건다. 링크를 걸 파일은 아까 풀어둔 소스코드의 .asd 파일이다. 사실 1번 과정에서 .asd 파일이 있는지 확인하는 것이 좋지만 대부분의 패키지는 .asd를 패키지 이름으로 만들어 두었기 때문에 꼭 확인하지 않아도 된다. 내 경우라면 md5 패키지를 다운로드 했을 경우, ln -s ~/asdf/md5-1.8.5/md5.asd 라고 하면 된다.
  5. 그러면 systems/ 내에 md5.asd 라는 심볼릭 링크가 생겼을 것이다. 이러면 설치가 완료된 것이다. 어떠한 컴파일 작업이나 다른 것이 필요없다. 압축을 풀고, 심볼릭 링크를 걸면 끝이다. 후에 패키지를 제거하고 싶으면 다운 받았던 패키지 디렉토리를 지워버리고 systems/ 에서 심볼릭 링크를 제거하면 된다.
  6. sbcl이 실행된 상태에서 (require 'md5) 라고 하면 첫 로드시에 알아서 패키지를 컴파일 한다. 다음부터는 컴파일 없이 바로 로드된다.
이와 같은 방법으로 어떤 패키지든 쉽게 사용할 수 있다.

clsql을 통해 sqlite3 DB 이용하기

Language/Common LISP 2011. 10. 14. 11:49 Posted by 알 수 없는 사용자
Common Lisp를 이용해서 DB 접속을 하기에 아주 좋은 패키지가 있다. CLSQL이다.

CLSQL을 다운받아 압축을 풀어보면 많은 수의 asd파일이 있음을 알 수 있다. clsql.asd, clsql-uffi.asd는 기본으로 심볼릭 링크를 걸고, 자신이 사용하고자 하는 데이터베이스에 해당되는 asd 파일을 링크걸면 된다.

db2, mysql, odbc, oracle, postgresql, sqlite 등 널리 사용되는 DB는 거의 지원한다. 이 글에서는 sqlite v3를 이용하는 방법을 살펴본다.
(require 'clsql-sqlite3)
명령어를 입력하여 패키지를 로드한다. 문제없이 로드가 되어야 CLSQL을 이용할 수 있다. asdf를 이용해서 로드할 경우에는
(asdf:oos 'asdf:load-op 'clsql-sqlite3)
로 로드할 수 있다.

sqlite3를 이용해서 우선 테스트할 테이블을 하나 만들어보자. 도시들의 온도를 저장하는 간단한 것.
j0nguk@netbook:~$ sqlite3 tem.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table cities (id integer primary key, name text, temp real);
sqlite> .tables
cities
sqlite> insert into cities values (null, "seoul", 25.8);
sqlite> insert into cities values (null, "suwon", 26.3);
sqlite> insert into cities values (null, "busan", 23.7);
sqlite> select * from cities;
1|seoul|25.8
2|suwon|26.3
3|busan|23.7
sqlite>
테스트할 데이터베이스를 만들었으니 리스프에서 접근해보자.
CL-USER> (clsql:connect '("/home/j0nguk/tem.db") :database-type :sqlite3)
#<CLSQL-SQLITE3:SQLITE3-DATABASE /home/j0nguk/tem.db OPEN {C5464B9}>
connect 함수는 이름 그대로 데이터베이스에 연결하는 함수다. tem.db라는 파일을 이용해서 sqlite3 DB를 만들었으니 경로를 정확히 지정해준다. 그리고 DB type이 sqlite3라는 것도 명시해준다. 오류없이 위와 유사한 결과가 나오면 연결이 된 것이다.
CL-USER> (clsql:query "select * from cities")
((1 "seoul" 25.8d0) (2 "suwon" 26.3d0) (3 "busan" 23.7d0))
("id" "name" "temp")
바로 쿼리를 보내보자. query라는 함수를 이용하면 된다. 결과는 리스프답게 리스트로 돌아온다. 첫 번째 리턴값은 쿼리에 대한 결과이고 두 번째 리턴값은 column의 이름이다.
CL-USER> (clsql:print-query "select * from cities")
1 seoul 25.8
2 suwon 26.3
3 busan 23.7
; No value
리스트로 돌아오지 않고 스트링으로 보고 싶을 때는 print-query라는 함수를 이용하면 된다.
CL-USER> (clsql:select '* :from 'cities)
((1 "seoul" 25.8d0) (2 "suwon" 26.3d0) (3 "busan" 23.7d0))
("id" "name" "temp")
query 함수는 스트링을 매개변수로 받기 때문에 변수를 쿼리에 이용하거나 할 때는 조금 불편하다. 이때는 select 함수를 이용하면 된다. select외에 SQL 명령어들을 다양한 함수로 지원한다.
CL-USER> (clsql:query "insert into cities values (null, 'daegu', 29.4)")
NIL
NIL
CL-USER> (clsql:select '* :from 'cities)
((1 "seoul" 25.8d0) (2 "suwon" 26.3d0) (3 "busan" 23.7d0) (4 "daegu" 29.4d0))
("id" "name" "temp")
insert 쿼리도 잘 적용되는 것을 볼 수 있다. insert가 실제로 잘 적용되었는지 sqlite3 인터페이스를 통해 확인해보자.
j0nguk@netbook:~$ sqlite3 tem.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from cities;
1|seoul|25.8
2|suwon|26.3
3|busan|23.7
4|daegu|29.4
sqlite>
모든 작업이 끝나면 disconnect 함수로 접속을 끊을 수 있다. 연결된 데이터베이스를 확인하는 함수는 connected-databases이다. 연결이 끊어졌기 때문에 NIL이 리턴되는 것을 알 수 있다.
CL-USER> (clsql:disconnect)
T
CL-USER> (clsql:connected-databases)
NIL

Ubuntu, Android, and Galaxy S

Android 2011. 10. 14. 11:42 Posted by 알 수 없는 사용자
우선 환경설정 -> 응용프로그램 -> 개발에 가서 "USB 디버깅"이 체크되어 있는지 본다. 설정을 바꾸지 않았다면 기본값이 체크다.

연결 후에 adb devices를 해보면 다음과 같이 나온다. 갤럭시 S를 우분투가 인식하긴 했으나 어떤 디바이스인지 잘 모르고 있다.
$ adb devices
List of devices attached
????????????    no permissions
/etc/udev/rules.d/51-android.rules 파일을 만든다. 당연히 root 권한으로 해야 한다.
$ sudo emacs /etc/udev/rules.d/51-android.rules
이 파일에 넣어야 할 내용은 다음과 같다.
SUBSYSTEM=="usb", SYSFS{idVendor}=="04e8", MODE="0666"
갤럭시S가 컴퓨터와 연결되어 있었다면 뽑은 후에 다시 연결하자. 다시 adb를 통해 확인하면 잘 인식됨을 볼 수 있다.
$ adb devices
List of devices attached
M110d3d33415    device