'Perl/Cpan 모듈 분석'에 해당되는 글 9건

  1. 2010.11.10 perl URI::Escape 모듈 (3)
  2. 2010.03.21 Acme::EyeDrops (2)
  3. 2009.04.22 차트를 만들어 보자. [ SWF::Chart ] (2)
  4. 2009.02.08 perl을 사용한 자신의 IP 주소 얻기 (6)
  5. 2009.01.29 Morse (모스 부호) (9)
  6. 2008.12.11 Goo::Canvas
  7. 2008.12.01 한글 문자열을 키보드 자판의 영문자로 변환 (4)
  8. 2008.11.28 Win32::Process::Memory (6)
  9. 2008.11.17 Win32::GuiTest - Perl GUI Test Utilities. (2)

Naver Perl Community & Study Cafe


2010.11.10 19:30

perl URI::Escape 모듈


얼마전 친구의 요청으로 지오코딩 API 를 사용해서
주소의 좌표를 얻어야 하는 코드를 작성할 일이  생겼습니다.

지오코딩 API 의 링크 : http://code.google.com/intl/ko/apis/maps/documentation/geocoding/

저는 모바일 프로그래밍은 관심이 별로 없는데 들리는 이야기로는
대부분 이 API 를 사용해서 좌표를 얻어 모바일에서 처리한다고 하네요 ^^;

그래서 친구한테 이 API 를 사용하면 쉽게 되겠네~ 해서
코드를 바로 짰습니다.

2바이트의 문자가 url에 그대로 들어가면 브라우저에 따라
인식못하고 글자가 깨지는 현상이 일어나기 때문에
url 을 변환해주는 코드를 작성해야 합니다.

기본적으로 많이 사용하는 Perl 코드는 아래와 같습니다.


Perl URL Encode & Decode String

Here's an excellent way to encode strings that are going to be placed in a URL:

$str =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;

Likely, "page_given_string.php" will want to decode $str back into something useful:

$str =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;


원문 Link : http://support.internetconnection.net/CODE_LIBRARY/Perl_URL_Encode_and_Decode.shtml

코드상으로 처리해도 상관은 없지만,
Perl 에서는 이것을 쉽게 처리할 수 있도록 모듈을 제공하고 있습니다.



URI::Escape

Escape and unescape unsafe characters
URI-1.56***** (2 Reviews) - 06 Oct 2010 - Gisle Aas





이 모듈을 쓰면 예를들어 "부산 부산진구 부암3동 441-3" 문자열이

%BA%CE%BB%EA%20%BA%CE%BB%EA%C1%F8%B1%B8%20%BA%CE%BE%CF3%B5%BF%20441-3



이런 형식으로 변환되게 됩니다.
그런데 이 주소로 지오코딩 API를 사용하여 쿼리를 날리니 값을 받을 수 없는 겁니다.

이상하다 싶어 실제 API 값을 살펴보니
"부산 부산진구 부암3동 441-3"  주소가 아래와 같이 변환이 되었습니다.

%EB%B6%80%EC%82%B0%20%EB%B6%80%EC%82%B0%EC%A7%84%EA%B5%AC%20%EB%B6%80%EC%95%943%EB%8F%99%20441-3

자세히 살펴보다보니
아.. URL 주소가 UTF-8로 되어 있어서 이것을 인코딩 시키면 되구나..
생각이 들더군요.

URI::Escape 모듈에는 uri_escape_utf8 이라는
함수도 존재하기 때문에 간단히 이 함수를 쓰면
해결이 되겠구나 라고 생각했는데...

%C2%BA%C3%8E%C2%BB%C3%AA%20%C2%BA%C3%8E%C2%BB%C3%AA%C3%81%C3%B8%C2%B1%C2%B8%20%C2%BA%C3%8E%C2%BE%C3%8F3%C2%B5%C2%BF%20441-3

두둥;; 전혀 다른값이 나오는 겁니다..
고민고민을 하다가 Perl 커뮤니티에 들어가서 물어보니
인코딩이 utf-8인 터미널에서 잘 돌아간다는 것을 알게 되었습니다. ㅠ_ㅠ

즉 펄내부유니코드 포멧을 utf8인코딩 바이트시퀀스로 바꾸어서
 uri_escape 를 사용해야 한다는 정리!

이 단순한 문제때문에 야후 거기 API 로 바꿀 생각까지 했습니다 ㅎㅎ;

혹시나 지오코딩 API 를 사용할때
문제를 격을지도 모를 분들을 위해 코드 정리!!  :-)


1
2
3
4
5
6
7
8
9
10
use strict;
use Encode qw/encode decode/;
use URI::Escape;
use LWP::Simple;
sub _e{ decode('cp-949',shift)  };
sub _e1{ encode('cp-949',shift); }
my $address = uri_escape_utf8( _e("부산 부산진구 부암3동 441-3"));
my $url = "http://maps.google.com/maps/geo?output=xml&q=$address";
my $location = _e1(get($url));
print $location;

원본 Link : http://codepad.org/ePUDSmgm


도움을 주신 a3r0님과 am0c 님 감사합니다
JEEN님은 별로.. ㅋㅋㅋ
신고
Trackback 2 Comment 3
2010.03.21 02:33

Acme::EyeDrops


CPAN 에서 한번씩 모듈을 검색하다 보면


별 5개가 가득 찬 모듈은 보기가 힘듭니다.

그런데 이 모듈은 별 5개를 받아도 모자라다는 느낌이 드네요^^

지금부터 소개할 모듈은 Acme::EyeDrops 라는 모듈로

예전에 Naver Perl 카페에서 Raymundo님이 한번 언급해 주셨습니다.


얼마전 읽었던 별찍기 에서 perl 스페셜 버전으로도 소개가 되었던 Acme::EyeDrops

저도 궁금해서 한번 사용해 보았는데 

아래 예제를 보도록 하겠습니다.


Acme::EyeDrops

Visual Programming in Perl 
Acme-EyeDrops-1.55***** (2 Reviews) - 01 Dec 2008 - Andrew J. Savige 





Perl
                              ''=~('('.
                            '?'.'{'.('`'|
                           '%').('['^'-').                        ('`'|'!')
                          .('`'|',')."\"".(                     '['^'+').('['
                          ^')').('`'|')').( '`'|'.').          ('['^'/').('{'^
                '[').'\\'.'"'.('`'^')').('{'^'[').('`'|',').( '`'|'/').('['^'-'
            ).('`'|'%').('{'^'[').(('`')^                 '"').('`'|'!').("\`"|
         '.').           ('{'^"\[").(                           '{'^'"').("\`"|
       '/')            .("\["^                                     '.').("\`"|
      '.')           .(('`')|                                        "'").(
    "\{"^           ('[')).(                                          '`'
   |'(')           .(('`')|                                            '%'
  ).''.           ('`'|'%'                                              ).(
  '{'^           '[').'^'.            '^'                                .((
 '\\')           ).('"').          ';'."\"".              '}'.            ')'
 );$:           ='.'^'~';         $~='@'|'(';           $^="\)"^           ((
'['))           ;$/="\`"|        '.';$,="\("^          '}';$\='`'           |+
"\!";           $:=(')')^       '}';$~=('*')|          '`';$^='+'^          ((
'_'))           ;$/="\&"|       '@';$,="\["&           '~';$\="\,"^        '|'
;($:)=          '.'^'~';$~      ='@'|"\(";             $^=')'^"\[";        ($/)
=('`')|         '.';$,="\("^      '}';$\                ='`'|'!';$:       =')'^
"\}";$~=         '*'|('`');$^=                           '+'^'_';        $/='&'
 |'@';$,=       '['&'~';$\=','^'|'          ;$:='.'        ^'~'        ;$~='@'|
 '(';$^=')'    ^'[';$/='`'|'.';$,='('^     '}';$\='`'               |'!';$:=')'
 ^'}';$~='*'|  '`';$^='+'^'_';$/='&'|'@'    ;$,="\["&      '~';$\=','^('|');$:=
  '.'^'~';$~='@'|'(';$^=')'^'[';$/='`'|'.'     ;(      $,)='('^'}';$\='`'|"\!";
  $:=')'^'}';$~='*'|'`';$^='+'^'_';$/='&'|'@';$,='['&'~';$\=','^'|';$:='.'^'~'
  ;$~='@'|'(';$^=')'^'[';$/='`'|'.';$,='('^'}';$\= '`'|'!';$:=')'^'}';$~="\*"|
  '`';$^='+'^'_';$/='&'|'@';$,='['&'~';$\=','^'|';$:='.'^'~';$~='@'|'(';$^=')'
  ^'[';$/='`'|'.';$,='('^'}';$\='`'|'!';$:=')'^'}';$~='*'|'`';$^='+'^"\_";$/=
  '&'|'@';$,='['&'~';$\=','^'|';$:='.'^'~';$~='@'|  '(';$^=')'^'[';$/='`'|'.'
  ;$,='('^'}';$\='`'|'!';$:=')'^'}';$~='*'|'`';$^     ='+'^'_';$/='&'|'@';$,
   ='['&'~';$\=(',')^ '|';$:='.'^'~';$~='@'|'(';       $^=')'^'[';$/='`'|'.'
    ;$,='('^('}');$\=  '`'|'!';$:=')'^'}';$~='*'|     '`';$^='+'^'_';$/='&'
     |'@';$,='['&"\~";  $\=','^'|';$:='.'^'~';$~=     '@'|'(';$^=')'^"\[";
       $/='`'|('.');$,=  '('^'}';$\='`'|('!');$:=     ')'^'}';$~='*'|'`';
         $^='+'^'_';$/=   '&'|'@';$,='['&"\~";$\=     ','^'|';$:='.'^'~'
            ;$~=('@')|     '(';$^=')'^'[';$/="\`"|    '.';$,='('^'}';$\
                             ='`'|'!';$:=')'^'}';$~   ='*'|'`';$^='+'
                              ^'_';$/='&'|('@');$,=   '['&"\~";$\=
                                ','^'|';$:='.'^'~';     $~='@'
                                  |'(';$^=')'^"\[";


Output:
1
I love Ban Young hee ^^




위와 같이 perl 코드를 실행시키면 아래와 같은 출력물이 나타납니다.

파일은 총 3개가 필요합니다.

프로그램을 돌리기 위한 파일, 옵션을 지정할 파일

이 두 파일을 통해 새로운 코드 파일이 생성이 됩니다.




Perl, 
''=~('(?{'.('`'|'%').('['^'-').('`'|'!').('`'|"\,").'"\\$-=!\\$%<<('.(
 '['^'+').('`'|'/').('['^'+').'||'.('^'^('`'|'*')).');'.('['^'+').('['^
 ((                                                                  ((
 ((                                ((                                ((
 ((                               ')')                               ))
 ))                              ))  ))                              ))
 ))                             .(('`')|                             ((
 ((                            ((      ((                            ((
 ((                           ')')    ))))                           ))
 ))                          ))  ))  .(  ((                          ((
 ((                         '`'))))))|'.').(                         ((
 ((                        ((              ((                        ((
 ((                       '[')            ))))                       ))
 ))                      ))  )^          ((  ((                      ((
 ((                     '/')))))        )))).''.                     ((
 ((                    ((      ((      ((      ((                    ((
 ((                   '\\'    ))))    ))))    ))))                   ))
 ))                  .+  ((  ((  ((  ((  ((  ((  ((                  ((
 ((                 '$')))))))))))))))))).'\\"'.('['                 ^+
 ((                ((                              ((                ((
 ((               '#')                            ))))               ))
 ))              ))  .+                          ((  ((              ((
 ((             '\\'))))                        )))).'$'             .+
 ((            ((      ((                      ((      ((            ((
 ((           '-')    ))))                    ))))    ))))           ).
 ((          ((  ((  ((  ((                  ((  ((  ((  ((          ((
 ((         ',')))))))))))))                ))))))))).("\`"|         ((
 ((        ((              ((              ((              ((        ((
 ((       '-')            ))))            ))))            ))))       ))
 ))      .(  ((          ((  ((          ((  ((          ((  ((      ((
 ((     '`')))))        ))))))))        )))))|((        '!'))).(     ((
 ((    ((      ((      ((      ((      ((      ((      ((      ((    ((
 ((   '[')    ))))    ))))    ))))    ))))    ))))    )))^    '+')   .+
 ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((
 (( '(')))))))))))))))))))))))))))))))))))))).'\\$-&\\$_?'."'".('{'^ ((
 ((                                                                  ((
 '['))))))).('{'^'[')."'".':'."'".'/\\\\\\\\'."'".',\\$%..\\$.++),\\$/'
 .('['^',').('`'|'(').('`'|')').('`'|',').('`'|'%').'\\$---"})');$:='.'


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
               /\
              /\/\
             /\  /\
            /\/\/\/\
           /\      /\
          /\/\    /\/\
         /\  /\  /\  /\
        /\/\/\/\/\/\/\/\
       /\              /\
      /\/\            /\/\
     /\  /\          /\  /\
    /\/\/\/\        /\/\/\/\
   /\      /\      /\      /\
  /\/\    /\/\    /\/\    /\/\
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\





perl Hacker 들이 만든 Acme:::EyeDrops 모듈...

사용법이 어렵지 않으니

여자친구 있으신 분들은 어서 예쁜 메세지와 함께 마음을 전달 하시길^^


Perl, 
1
2
3
map(($r=$_,map(($y=$r-$_/3,$l[24-$r]
.=(' ','@')[$y**2-20*$y+($_**2)/3<0]),(0..30)),),(0..24)),
print join("\n", map(reverse($_).$_, @l)), "\n";


Output:
                                                              
                                                              
                                                              
                  @@@@@@@@@        @@@@@@@@@                  
                @@@@@@@@@@@@@@  @@@@@@@@@@@@@@                
              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
               @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@               
                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                
                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                
                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@                 
                  @@@@@@@@@@@@@@@@@@@@@@@@@@                  
                   @@@@@@@@@@@@@@@@@@@@@@@@                   
                     @@@@@@@@@@@@@@@@@@@@                     
                      @@@@@@@@@@@@@@@@@@                      
                        @@@@@@@@@@@@@@                        
                          @@@@@@@@@@                          
                            @@@@@@                            
                                                              



신고
Trackback 1 Comment 2
2009.04.22 20:18

차트를 만들어 보자. [ SWF::Chart ]





로그파일을 분석할 때 가끔 차트가 필요 할 때가 있는데...

JEEN님이 내놓은 떡밥이라 포스팅을...

flash로 만든 오픈소스중 XML/SWF Chart 라는 프로그램이 있는데

xml로 데이터만 가공하면 이 자료를 바탕으로 차트를 생성해 준다.



디자인도 이쁘고 노력만 조금 들이면 움직이는 차트도 만들수 있어 많은곳에 두루 사용될듯한 이 차트는

CPAN에 등록되어 있다.

SWF::Chart

Perl interface to the SWF Chart generation tool
SWF-Chart-1.4 - 11 Jul 2006 - Garth Winter Webb 

아쉬운것은 2006 7월 11일을 마지막으로 더이상 업데이트가 이루어지지 않았으며,

XMLSWF-Charts는 지속적으로 업데이트가 되었다는 사실...

CPAN을 통하여 SWF::Chart를 설치한 뒤

SYNOPSIS 를 실행시키면 xml 형식으로 출력이 가능하며 파일에 저장시켜 차트를 생성하면 된다.

  
  use SWF::Chart;
  my $g = SWF::Chart->new;
  $g->set_titles(qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec));
  # Add a single data set
  $g->add_dataset(1, 3, 5, 7, 2, 4, 6);
  # Add multiple datasets
  $g->add_dataset([qw(1 3 5 7 11 13 17 23 29 31 37 41)],
                  [qw(1 1 2 3 5 8 13 21 34 55 89 144)]);
  # Add multiple datasets with labels
  $g->add_dataset('Label 1' => \@set1,
                  'Label 2' => \@set2);  $g->text_properties(bold  => 0,
                      size  => 10,
                      color => '333333');

  $g->chart_rect(positive_color => '555555',
                 positive_alpha => 100);
  $g->series_color('DEADBE');

  print $g->xml;



위의 코드를 실행하여 출력된 값을 저장하여 차트를 생성하면 아래와 같은 차트가 생성된다.


 

사실 SWF::Chart는 모듈의 업데이트가 이루어지지 않아 

Chart의 세밀한 부분 처리하기가 쉽지 않았다.

만든 사람이 왜 더이상 업데이트를 하지 않는지.. 애착이 떨어진건가? -ㅁ-;

http://www.maani.us/xml_charts/index.php?menu=Reference 를 참고하여,

필요한 부분을 치환해가며 간단한 차트를 하나 만들어 보았다.



irc-log를 이용하여 누가 얼마나 이야기를 하였는지 체크해주는 차트인데

가장 많이 이야기 한사람에게는 색다른 표시를 해보았다.

동적으로 처리하기 위해 cgi로 date값을 입력받으면 그 값에 따라서 바로 통계를 내어주게끔

만들어 보았다.

http://honey.myemy.com/cgi-bin/chart.cgi?date=2009-04-22


모듈이 더이상 업데이트가 되지 않아

효과적으로 사용하기는 힘들겠지만

차트 자체는 지속적으로 업데이트 되고 있으며,

발전가능성도 많아 보인다.



필요한분들은 예쁘게 사용하세요  :)
신고
Trackback 1 Comment 2
2009.02.08 23:49

perl을 사용한 자신의 IP 주소 얻기

 

작업을 하다보면 자신의 IP를 참고 해야 할 부분이 생긴다.

perl을 사용하여 자신의 공인IP 또는 사설IP를 얻는 방법은 다양한데

이를 정리해 보았다.


- 사설 IP

perl을 사용하여 사설 IP를 얻기 위해서는 일반적으로 두가지 방법이 있다.

첫번째로 ifconfig 명령(리눅스 운영체제)의 결과값을 정규표현식으로 파싱하는 방법이다. (Luz님 코드)


원본코드 : http://perlkr.codepad.org/hkhQi5Zi


JEEN님께 솔깃한 정보를 얻었는데...

그럴듯한 그림 하나정도는 있어야 올블로그에서 간지나게 출력 준다고 하여... 낚아봤...

간만에 backtrack3... 흠흠...( 전체적으로 vi 색이 이쁜 듯)



이와같이 리눅스는 인터페이스를 옵션으로 설정할 수 있지만



윈도우는 ipconfig 명령으로 인터페이스를 설정할 수 없으므로

네트워크 인터페이스가 여러개라면 파싱하기가 까다로울 것이다.

ipconfig 명령 이외에 netsh interface dump 명령으로 사설 ip 주소를 파싱해도 좋다.


두번째 방법으로 Perl 모듈을 사용하는 방법이다.

Net::Address::IP::Local

A class for discovering the local system's IP address 
Net-Address-IP-Local-0.1.2 - 14 Jan 2009 - Julian Mehnle 



이 모듈을 사용하면 손쉽게 사설IP를 얻을 수 있다.

1
2
use Net::Address::IP::Local;
my $address = Net::Address::IP::Local->public;



- 공인 IP

NAT환경이고 public으로 나가는 IP의 주소를 알고 싶을 때 가장 좋은 방법은

REMOTE_ADDRESS를 찍어주는 사이트에서 결과를 파싱하는 방법이 가장 좋다.

리눅스 환경에서는 lynx 명령을 사용하여 사이트를 덤프한뒤 정규식으로 처리한다. (뽀빠이님 코드)


1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl

my $external_ip = `lynx -dump "http://checkip.dyndns.org"`;

$external_ip =~ s/\r//g;
$external_ip =~ s/\n//g;
$external_ip =~ s/
//g;
$external_ip =~ s/   Current IP Address: //;

print("$external_ip\n");

윈도우에는 lynx명령이 존재하지 않으므로,

LWP::Simple 모듈을 사용하여 처리한다.


1
2
use LWP::Simple;
print get('http://www.whatismyip.org/');


위의 사이트는 IP를 정규식으로 추출할 필요가 없어 사이트라 매우 편리했다.



- REMOTE_ADDRESS 정리

Simple한 Site (파싱이 필요없음)

http://checkip.dyndns.org/ 

http://www.whatismyip.org/

볼꺼리가 있는 Site

http://www.whatismyip.com/ 

http://www.mywanip.com/ 

IP를 통해 접속 위치를 알려주는 Site (대략적인 위치만 나오는 듯)

http://whatismyipaddress.com/ 

Remote port 및 Browser를 알려주는 Site

http://ipchicken.com/




... 패킷을 덤프하여 헤더부분을 까는 방법은 패스 -_-;





- 참고 Site

http://keir.net/ip2.html (자신의 IP를 알려주는 프로그램)

http://search.cpan.org/~jmehnle/Net-Address-IP-Local-0.1.2/lib/Net/Address/IP/Local.pm (CPAN 모듈)



신고
Trackback 1 Comment 6
2009.01.29 03:34

Morse (모스 부호)




군생활에서 나의 보직은 다른 사람들에 비해 조금 특화된 보직이었다.

군대에서 여러 능력을 배우는 중, 모스부호도 익히게 되었는데

처음에는 듣는것을 바로바로 해석하기에 급급했던 모스 부호였지만

익숙해 지고 나서는 모스부호로 동기들과 서로 대화도 하고 재밌게 지냈던 기억이 난다.



그때의 추억을 되살려 프로그래밍에서는 모스부호를 어떻게 다룰 수 있는지,

모스 부호에 대해서 간단한 포스팅을 해 보겠다.



- 모스부호란?

짧은 전류(.)과 발신 전류(-)을 적절히 조합하여 알파벳과 숫자를 표기한 것으로,

미국의 발명가 새무얼 필리 브리즈 모스가 고안했다.


- 모스부호 코드 (Alphabet)



한글도 있지만 일단 로마자만...



- 모스부호의 사용

모스부호를 사용한 대중적인 작품들이 상당히 많지만 최근에 나온 영화 몇가지만 소개하겠다.




영화 이글아이에서 주인공의 쌍둥이 동생인 이든은 핸드폰의 깜빡임을 이용하여

모스부호를 보내 메모리 칩의 숨겨진 장소를 전달하는 장면이 나왔다.

모르스부호는 깜박임으로 신호를 보내는것이 가능하기 때문에,

우리가 생활하는 일상 속 어딘가에서도 모스부호가 나오고 있지 않을까?





그리고 "벼랑위의 포뇨" 라는 애니매이션에서는

배를 타고 항해하는 아버지가 사정상 집에 들르지 못하자 

벼랑 위의 집을 향해 모스 부호를 주고 받으며 서로의 마음을 전달하는 모습이 나왔는데...

모스 부호를 통해 사랑도 고백하고 서로 싸움도 하였다.

딱딱한 모스부호를 일반사람들에게 쉽고 재미있게 다가간 애니매이션.





영화 렛미인에서는 두 소녀가 벽을 사이에 두고 톡, 톡톡, 스르륵 톡, 하며 모스 부호를 사용하여 대화를 한다.

둘이 영원히 하나가 될 수 없는 것처럼 톡, 톡, 끊어지면서 이어지는 소리가 슬프다.

많은 사람들이 렛미인을 시청한 뒤 모스부호를 배우고 싶다는 후기를 남겼다.



- 개인적인 사용

처음 모스부호를 배울 때, 한글과 영문이 모두 가능하다는것을 알고,

맘에 드는 여자분의 미니홈피에 모르스부호로 애정표현을 했었다.

그때의 마음으로는 어떻게든 좋아한다는 것을 전달하고는 싶지만 표현력이 부족하고

부끄러움이 많은 탓에 이러한 방법을 택했다.

웬 미친 소리야 라는 소리를들으며 그 글은 삭제 되었지만

나의 마음을 전달했기에 뿌듯했던 기억이 든다.



- Perl 을 사용한 모스 부호 구현

CPAN 에서 morse를 검색시 여러가지 모듈이 검색이 되는데 그중에서 2가지 모듈을 소개하겠다.

 

Convert::Morse

Convert between ASCII text and MORSE alphabet 
Convert-Morse-0.06 - 26 Feb 2008 - Tels


최근에 만들어진 모듈인 만큼 성능도 좋을것이라 생각되는 Convert::Morse 모듈


Text::Morse

Perl totally useless extension for Morse code
Text-Morse-0.01 - 19 Jul 2001 - Ariel Brosh (PAUSE Custodial Account)



2001년도에 만들어진 Text::Morse 모듈

두 모듈을 설치 한뒤 테스트를 해보니 잘 실행이 되는것을 확인 할 수 있었다.



1
2
3
4
5
6
7
8
9
10
11
use Text::Morse;

my $morse = new Text::Morse;
print scalar($morse->Decode("... --- ...")),"\n";
print scalar($morse->Encode("Adam Bertil")),"\n";

use Convert::Morse qw(as_ascii as_morse is_morsable);
print as_ascii('.... . .-.. .-.. ---  -- --- .-. ... .'),"\n"; # 'Helo Morse'
print as_morse('Perl?'),"\n";                # '.--. . .-. .-.. ..--..'
print "Yes!\n" if is_morsable('Helo Perl.'); # print "Yes!"
print map{ s/\./돈/g;s/-/쯔/g;$_; } as_morse('Perl?');



Output:

1
2
3
4
5
6
7
SOS
.- -.. .- --
-... . .-. - .. .-..
HELLO MORSE
.--. . .-. .-.. ..--..
Yes!
돈쯔쯔돈 돈 돈쯔돈 돈쯔돈돈 돈돈쯔쯔돈돈

http://perlkr.codepad.org/v99N9guf

보기에도 Convert::Morse 모듈이 훨신 변환이 편한것을 알 수 있다.

마지막에는 .을 돈으로 -를 쯔로 표현하여 한글로 읽는 표기법으로 바꿔보았다.

마찬가지로 돈과 쯔를 다시 .과 -로 표현하는 방법도 간단하다.



당연하겠지만 한글 Morse부호 변환 모듈은 존재하지 않았다.


이 부분은 예전에 내가 만들었던 모듈로 간단하게 해결을 할 수가 있는데

이전에 포스팅했던 글 중 한글 문자열이 영문타자로 변환 코드글에 있는

Lingua::KO::Hangul::Util 모듈을 사용하여 조금만 수정하면 한글을 일단 영문으로 변환한 뒤

영문을 다시 모스 부호로 변환하면 되는 것이다.


1
2
3
4
5
6
7
8
9
use strict;
use warnings;    
use Hangle qw/transformation/;
use Convert::Morse qw(as_morse);
my $key = "민영씨사랑해요";
print "Text  : $key\n";
$key = transformation($key);
print "Trans : $key\n";
print "Morse : ".as_morse($key),"\n";


Output:

1
2
3
Text  : 민영씨사랑해요
Trans : MUFKSKGGUGEVEKJEUKN
Morse : -- ..- ..-. -.- ... -.- --. --. ..- --. . ...- . -.- .--- . ..- -.- -.


http://perlkr.codepad.org/YGsEykat


모르스부호를 다시 한글로 변환하기는 짜기가 귀찮아서 패스~ 흠흠;;



- 후기

업무상으로 모스 부호를 사용했기에

그때 당시에 이런 모듈을 알고 썼다면 상당히 많은 도움이 되었을 것이며,

고참들에게 사랑을 듬뿍 받을 수 있었을텐데... 라는 아쉬움이 든다.


모스 부호에 관심이 있다면 마지막으로 이 메세지를 한번 해석해 보라!


.... .- .--. .--. -.--  -. . .--  -.-- . .- .-. -.-.--


Good Job~!

참고 :

- 모스부호

http://ko.wikipedia.org/wiki/모스_부호

http://www.wrvmuseum.org/morsecode/morsecodehistory.htm

- 모듈

http://search.cpan.org/~schop/Text-Morse-0.01/Morse.pm

http://search.cpan.org/~tels/Convert-Morse-0.06/lib/Convert/Morse.pm

http://search.cpan.org/~sadahiro/Lingua-KO-Hangul-Util-0.23/Util.pm

- 매개체

http://blog.naver.com/overgold?Redirect=Log&logNo=110039857425

http://skyelove.tistory.com/86
신고
Trackback 2 Comment 9
2008.12.11 11:06

Goo::Canvas


얼마전 cpan에서 테트리스게임을 구현한 코드를 발견하였다.

yewenbin이란 중국사람이 만들었는데 멋지다.



소스 코드를 다운받아서 분석하던 중 ( perl은 소스코드를 바로 확인할 수 있어 좋은듯 )

Goo::Canvas 라는 모듈을 발견하고 이게 뭘까?? cpan에서 검색해 보았다.

Goo::Canvas

Perl interface to the GooCanvas
Goo-Canvas-0.05 - 29 Mar 2008 - 叶文彬 


오옷!! Gtk+ 를 사용하여 자동으로 그림을 그려주는 모듈인데

재밌는 기능이 많은듯 +_+ 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my $canvas = Goo::Canvas->new();
$canvas->set_size_request(450, 280); #Windows 크기와 동일하게 지정
$canvas->set_bounds(0, 0, 450, 280); #출력범위 설정

my $root = $canvas->get_root_item();
my $rect = Goo::Canvas::Rect->new(
$root, 20, 20, 180, 180, #처음 x(가로 좌표) , 처음 y (세로자표) , 가로넓이 , 세로 넓이 
        'line-width' => 2, # 테두리 두께
        'radius-x' => 0, #끝을 뭉퉁하게~
        'radius-y' => 0,
        'stroke-color' => 'blue', #테두리 색
        'fill-color' => 'skyblue' # rect를  채울 색 
);
rect->signal_connect('button-press-event', # 버튼이 눌러졌을때 이벤트
                          \&on_rect_button_press);


4각의 틀을 그려주고 그 틀에 이벤트를 넣는것,

글자 출력 및 회전(rotate) 기능까지 있어

yewenbin이 테트리스 및 지뢰찾기까지 

이 모듈을 사용하여 구현한 것을 확인 할 수 있었다.



테스트를 코드를 작성하던 중

좀 재밌게 응용할 수 없을까? 해서 

사각틀을 클릭하면 문자열이 프로펠러처럼

슝슝~ 돌아가는 프로그램을 작성해 보았다.

Glib::Timeout을 사용하면 알아서 작동을 후욱후욱...



신고
Trackback 1 Comment 0
2008.12.01 00:55

한글 문자열을 키보드 자판의 영문자로 변환


예전 WIn32::GuiTest 모듈을 사용한 예제에서

영문만 지원이 되고 한글은 지원되지 않기에

한글문자열이 직접 영문타자로 변환되는 모듈을 만들어 볼까 생각했었다.


오늘 시간이 남아 일단 여러 자료들을 다 펼쳐놓고 작업에 들어갔는데...


크게 정리하자면

1. 한글 문자열을 각 문자단위로 조각조각 낸다.
2. 조각조각 낸 단위의 문자들을 각각 영문키로 바꾼다.
3. 끝(?)....


응?? 어떻게 보면 간단하다... 

하지만 세부적으로 들어가야하는 코딩은 까다롭기 때문에

잘 생각해보자.


가장먼저 한글을 쪼개어서 각 문자코드로 변환시켜주는 모듈을 소개한다.

Lingua::KO::Hangul::Util

utility functions for Hangul in Unicode 
Lingua-KO-Hangul-Util-0.23 - 05 Jun 2007 - SADAHIRO Tomoyuki 

이 유익한 모듈은... 일본사람이 만들었다.. 쳇...

모듈을 통해 간단한 테스트 코드를 만들어 테스트를 해보았다.

각 모듈을 조각조각 내는것은 어렵지 않게

decomposeSyllable 함수를 쓰면 조각 내어진다.




이 모듈을 가지고 얼마전 a3r0님이 

이름을 서로 매칭시켜 궁합을 보는 프로그램을 만든 적이 있었다.


그래서 이 모듈을 조금만 수정하면 각각의 문자값에 영문자를 넣어

변형할 수 있을 것이란 생각이 들었다.




이 모듈은 decomposeJamo 라는 함수를 제공하는데

이 함수는 ㄲ(&#x1101) 을 ㄱ(&#x1100)ㄱ(&#x1100) 으로 나누어준다.

ㄲ을 자판의 키로 옮길때는 대문자 R이 되어야 하는데...

rr(소문자r2개) 으로 바꿔서 처리하니 변환하기가 곤란했다.

그렇다고 decomposeJamo 함수를 안쓰려니...

종성에서 ㄳ 을 ㄱ 과 ㅅ으로 ㄺ 을 ㄹ 과 ㄱ으로

나누어주는 편리함때문에 이 모듈을 안 쓸 수도 없었다.


진퇴양난...


일단 나만의 함수를 만들기에 아직 실력이 출중하지 않고...

결국 이 모듈을 내가 편하게 고쳐서 사용하기로 하였다.

decomposeJamo 함수를 사용하되

쌍자음과 ㅐ,ㅒ,ㅖ ,ㅔ 같은 모음들은 변환이 안되게 변환되는 부분에서

주석처리를 해버리는 방법이었다.

나중에야 발견했지만

종성에서 ㄲ 과 ㅆ 도 변환되지 않게 처리해야 한다는 것을 알았다.

그래서 이렇게 변환해주는 모듈을 완성을 해보았다.



Hangle.pm

package Hangle;

use strict;
use warnings;
use Lingua::KO::Hangul::Util qw(:all);
use base qw/Exporter/;
use Encode qw/decode encode/;

our @EXPORT_OK = qw/transformation/;

sub transformation{
	my $arg = shift;
	my $str = decode('cp-949', $arg);
	binmode STDOUT, ':encoding(cp-949)';
	my %hangle = (
			#초성
			"\x{1100}" => 'r', "\x{1102}" => 's', "\x{1103}" => 'e', "\x{1105}" => 'f',  # ㄱㄴㄷㄹ
			"\x{1106}" => 'a', "\x{1107}" => 'q', "\x{1109}" => 't', "\x{110B}" => 'd',  # ㅁㅂㅅㅇ
			"\x{110C}" => 'w', "\x{110E}" => 'c', "\x{110F}" => 'z', "\x{1110}" => 'x',  # ㅈㅊㅋㅌ
			"\x{1111}" => 'v', "\x{1112}" => 'g', "\x{1101}" => 'R', "\x{1104}" => 'E',  # ㅍㅎㄲ ㄸ
			"\x{1108}" => 'Q', "\x{110A}" => 'T', "\x{110D}" => 'W',                     # ㅃ ㅆ ㅉ		  
			#중성
			"\x{1161}" => 'k', "\x{1163}" => 'i', "\x{1165}" => 'j', "\x{1167}" => 'u',  # ㅏㅑㅓㅕ
			"\x{1169}" => 'h', "\x{116D}" => 'y', "\x{116E}" => 'n', "\x{1172}" => 'b',  # ㅗㅛㅜㅠ
			"\x{1173}" => 'm', "\x{1175}" => 'l',                                        # ㅡㅣ
			"\x{1162}" => 'o', "\x{1164}" => 'O', "\x{1166}" => 'p', "\x{1168}" => 'P',  # ㅐㅒㅔㅖ
			#종성
			"\x{11A8}" => 'r', "\x{11AB}" => 's', "\x{11AE}" => 'e', "\x{11AF}" => 'f',  # ㄱㄴㄷㄹ
			"\x{11B7}" => 'a', "\x{11B8}" => 'q', "\x{11BA}" => 't', "\x{11BC}" => 'd',  # ㅁㅂㅅㅇ
			"\x{11BD}" => 'w', "\x{11BE}" => 'c', "\x{11BF}" => 'z', "\x{11C0}" => 'x',  # ㅈㅊㅋㅌ
			"\x{11C1}" => 'v', "\x{11C2}" => 'g',                                        # ㅍㅎ
			"\x{11A9}" => 'R', "\x{11BB}" => 'T',                                        # ㄲ ㅆ
			#특수문자
			"\x{20}" => ' ' , "\x{A}" => "\n" , "\x{2E}" => '.' , "\x{2C}" => ',' ,      #Space Enter . ,
			"\x{2D}" => '-' , 
			#Number
			"\x{30}" => '0' , "\x{31}" => '1' , "\x{32}" => '2' , "\x{33}" => '3' ,
			"\x{34}" => '4' , "\x{35}" => '5' , "\x{36}" => '6' , "\x{37}" => '7' ,
			"\x{38}" => '8' , "\x{39}" => '9' ,
	);
	my @jamos =  map { split //, decomposeJamo($_) }split //, decomposeSyllable($str);
	my $keys = '{HAN}';
	foreach (@jamos) { $keys .= $hangle{$_} }
	# print "$strokes";
	return $keys;
}

http://codepad.org/Wa3a4asO


특수문자는 필요한 문자들은 더 추가할 계획이다.

어렵게 한글변환을 끝내고 GuiTest 모듈에 적용시켜 테스트 하려고 하니...

한/영 키의 코드를 모르는 것이다.................




처음에 생각했을 때 외국사람들이 한영키를 배려해놨을리가 없지... 생각하고

키 테스트 프로그램을 몇개 켜놓고 한영키를 꾹꾹 눌러가면서 한영키 값을 찾아보고 있었다.

그렇게 삽질을 하다가 혹시나 해서 GuiTest 모듈을 다시 세부적으로 분석해 보았는데,

GuiTest.pc 파일을 보니 이러한 코드를 확인할 수 있었는데....

1
2
3
4
5
6
7
sub VK_KANA           { 0x15; }
sub VK_HANGEUL        { 0x15; }
sub VK_HANGUL         { 0x15; }
sub VK_JUNJA          { 0x17; }
sub VK_FINAL          { 0x18; }
sub VK_HANJA          { 0x19; }
sub VK_KANJI          { 0x19; }

오.. 이럴수가... 한글에 대해서... 배려를 해 놓았다..

다른나라 사람들도 활용 할 수 있도록 모듈을 설계한

그들의 이식성에 감탄할 수 밖에 없다.


이제 키가 정의된 코드에서 한글 키만 추가하면 한영키를 사용할 수 있다.
 

my %vk = ( 

    ..... 

HAN    => VK_HANGUL(),

 

);


해쉬를 추가한 뒤 간단한 테스트 프로그램을 짜봤다.

Han_Trans.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use strict;
use warnings;    
use Win32::GuiTest;
use Hangle qw/transformation/;
my $key = "글쓰기는 근육과 같습니다.\n".
"더 많이 쓸수록 더 잘 쓸 수 있게 됩니다.\n".
"글을 잘 못쓴다면 간단한 일기를 쓰고, \n".
"블로그도 만들어보고, 창조적인 쓰기 수업을 수강하고, \n".
"4년동안 티격태격 싸워왔던 대학동기나 룸메이트에게 보내는 \n".
"멋진 편지를 써보세요 \n".
"어떤 글이라도 종이에 적기 시작하면 글쓰는 기술이 향상될 겁니다.\n\n".
" - 조엘 온 소프트웨어 \n";
$key = transformation($key);
# print $key;
system("start notepad.exe");
sleep 1;
Win32::GuiTest::SendKeys($key);
sleep 5;
Win32::GuiTest::SendKeys("%{F4}{TAB}{ENTER}");

http://codepad.org/HoxMNqeY


컴파일해서 실행파일까지 만들었으나

이 실행파일은 컴파일 당시 환경과  윈도우 버전이 틀리면 실행되지 않는다.

그리고 3MB 정도로 꾀 큰 용량을 차지하며

패킹을 해봤더니 콘솔창에서 오류가 뜬다. ( 그러면서 실행은 되었다는...)

코드안에 한글이 들어가 있을 경우 컴파일도 안되는 어이없는 일도 생겨...

PAR::Packer 모듈도 조금 더 발전했으면 한다.




- 참고

The Korean Writing System
신고
Trackback 2 Comment 4
2008.11.28 15:52

Win32::Process::Memory


이번에는 프로세스에서 메모리를 읽고 쓸수도 있는 Win32::Process::Memory 에 대해서 알아보자.

이 모듈을 찾게 된 계기는

다른 프로세서에 있는 메모리를 읽어오기 위한 방법이 없을까 

해서 cpan에서 찾는 도중 발견~!


Win32::Process::Memory

read and write memory of other windows process
Win32-Process-Memory-0.20 - 01 May 2004 - Qing-Jie Zhou 


만든지 꾀 오래 된 모듈이다 

2004년 쯤이니.. 벌써 4년이 훨신 지났다.

기본적인 예제를 한번 실행해 보자.

 # 프로세스를 오픈한다.
  my $proc = Win32::Process::Memory->new({ name=>'cmd.exe' });
  # 디버그
  printf "\nTotal Memory = 0x%X\n", $proc->get_memtotal;
  print "\nMemory block list:\n";
  my %memlist = $proc->get_memlist;
  printf "  %08X -> %08X : Len=0x%X\n", $_, $_+$memlist{$_}, $memlist{$_}
      foreach (sort {$a <=> $b} keys %memlist);
  print "\nContent of 0x10004 -> 0x10103\n";
  print $proc->hexdump(0x10004, 0x100);

  # search a sequence of unsigned int16
  print "\nFind a sequence of unsinged int16:\n";
  my @results = $proc->search_u16(92, 87, 105, 110, 51, 50);
  print $proc->hexdump($_, 0x32)."\n" foreach @results;
  # 값을 읽어와서 바꾼다.
  printf "\n0x%X [unsigned int16] : %d\n", 0x10004, $proc->get_u16(0x10004);
  printf "0x%X [unsigned int32] : %d\n", 0x10004, $proc->get_u32(0x10004);
  #$proc->set_u32(0x10004, 55); # 값을 바꾸는것은 위험하다. 시스템이 손상될 수 있다.

  #프로세스를 종료한다.
  undef $proc;
 
이 모듈은 굉장히 유용한 기능이 많은데..

전체 메모리의 양, hex코드로 덤프, 메모리를 검색, 메모리를 변경까지 해준다.


실행화면

D:\Documents and Settings\honey>perl Memory_test.pl

Total Memory = 0x196C000

Memory block list:
  00010000 -> 00011000 : Len=0x1000
  00020000 -> 00021000 : Len=0x1000
  00030000 -> 00035000 : Len=0x5000
  00040000 -> 00140000 : Len=0x100000
  00140000 -> 00143000 : Len=0x3000
  00150000 -> 00163000 : Len=0x13000
  00250000 -> 00256000 : Len=0x6000
  00260000 -> 00268000 : Len=0x8000
  00270000 -> 00286000 : Len=0x16000
  00290000 -> 002D1000 : Len=0x41000
  002E0000 -> 00321000 : Len=0x41000
  00330000 -> 00336000 : Len=0x6000
  00340000 -> 00381000 : Len=0x41000
  00390000 -> 0039B000 : Len=0xB000
  00450000 -> 00452000 : Len=0x2000
  00460000 -> 00468000 : Len=0x8000
  00470000 -> 00471000 : Len=0x1000
  00480000 -> 00481000 : Len=0x1000
  00490000 -> 00492000 : Len=0x2000
  004A0000 -> 004A4000 : Len=0x4000
  004B0000 -> 004B2000 : Len=0x2000
  004C0000 -> 004C8000 : Len=0x8000
  004D0000 -> 004D4000 : Len=0x4000
  004E0000 -> 004E3000 : Len=0x3000
  004F0000 -> 004F3000 : Len=0x3000
  00530000 -> 00633000 : Len=0x103000
  00640000 -> 007B3000 : Len=0x173000
  00940000 -> 00941000 : Len=0x1000
  009C0000 -> 009C1000 : Len=0x1000
  009D0000 -> 009DE000 : Len=0xE000
  009E0000 -> 009E1000 : Len=0x1000
  00A60000 -> 00A62000 : Len=0x2000
  4AD00000 -> 4AD01000 : Len=0x1000
  4AD01000 -> 4AD21000 : Len=0x20000
  4AD21000 -> 4AD22000 : Len=0x1000
  4AD22000 -> 4AD25000 : Len=0x3000
  4AD25000 -> 4AD26000 : Len=0x1000
  4AD26000 -> 4AD29000 : Len=0x3000
  4AD29000 -> 4AD2C000 : Len=0x3000
  4AD2C000 -> 4AD2F000 : Len=0x3000
  4AD2F000 -> 4AD30000 : Len=0x1000
  4AD30000 -> 4AD33000 : Len=0x3000
  4AD33000 -> 4AD39000 : Len=0x6000
  4AD39000 -> 4AD3C000 : Len=0x3000
  4AD3C000 -> 4AD3D000 : Len=0x1000
  4AD3D000 -> 4AD3E000 : Len=0x1000
  4AD3E000 -> 4AD78000 : Len=0x3A000
  5A480000 -> 5A481000 : Len=0x1000
  5A481000 -> 5A4B1000 : Len=0x30000
  5A4B1000 -> 5A4B2000 : Len=0x1000
  5A4B2000 -> 5A4B8000 : Len=0x6000
  5C2E0000 -> 5C2E1000 : Len=0x1000
  5C2E1000 -> 5C2EF000 : Len=0xE000
  5C2EF000 -> 5C2F2000 : Len=0x3000
  5C2F2000 -> 5C303000 : Len=0x11000
  5C303000 -> 5C306000 : Len=0x3000
  5C820000 -> 5C821000 : Len=0x1000
  5C821000 -> 5C892000 : Len=0x71000
  5C892000 -> 5C895000 : Len=0x3000
  5C895000 -> 5C8BA000 : Len=0x25000
  62340000 -> 62341000 : Len=0x1000
  62341000 -> 62346000 : Len=0x5000
  62346000 -> 62347000 : Len=0x1000
  62347000 -> 62349000 : Len=0x2000
  6FD60000 -> 6FD61000 : Len=0x1000
  6FD61000 -> 6FD93000 : Len=0x32000
  6FD93000 -> 6FD94000 : Len=0x1000
  6FD94000 -> 6FD98000 : Len=0x4000
  6FD98000 -> 6FD9C000 : Len=0x4000
  6FD9C000 -> 6FF2A000 : Len=0x18E000
  73F80000 -> 73F81000 : Len=0x1000
  73F81000 -> 73FC5000 : Len=0x44000
  73FC5000 -> 73FCF000 : Len=0xA000
  73FCF000 -> 73FD1000 : Len=0x2000
  73FD1000 -> 73FD4000 : Len=0x3000
  73FD4000 -> 73FD5000 : Len=0x1000
  73FD5000 -> 73FEB000 : Len=0x16000
  762E0000 -> 762E1000 : Len=0x1000
  762E1000 -> 762F6000 : Len=0x15000
  762F6000 -> 762F7000 : Len=0x1000
  762F7000 -> 762FD000 : Len=0x6000
  76970000 -> 76971000 : Len=0x1000
  76971000 -> 76A96000 : Len=0x125000
  76A96000 -> 76A97000 : Len=0x1000
  76A97000 -> 76A9D000 : Len=0x6000
  76A9D000 -> 76AAD000 : Len=0x10000
  76AF0000 -> 76AF1000 : Len=0x1000
  76AF1000 -> 76B10000 : Len=0x1F000
  76B10000 -> 76B11000 : Len=0x1000
  76B11000 -> 76B12000 : Len=0x1000
  76B12000 -> 76B1B000 : Len=0x9000
  76D90000 -> 76D91000 : Len=0x1000
  76D91000 -> 76DAE000 : Len=0x1D000
  76DAE000 -> 76DAF000 : Len=0x1000
  76DAF000 -> 76DB2000 : Len=0x3000
  770D0000 -> 770D1000 : Len=0x1000
  770D1000 -> 77151000 : Len=0x80000
  77151000 -> 77152000 : Len=0x1000
  77152000 -> 77154000 : Len=0x2000
  77154000 -> 7715B000 : Len=0x7000
  77160000 -> 77161000 : Len=0x1000
  77161000 -> 771F2000 : Len=0x91000
  771F2000 -> 771F3000 : Len=0x1000
  771F3000 -> 77263000 : Len=0x70000
  77B90000 -> 77B91000 : Len=0x1000
  77B91000 -> 77BA1000 : Len=0x10000
  77BA1000 -> 77BA2000 : Len=0x1000
  77BA2000 -> 77BA5000 : Len=0x3000
  77BB0000 -> 77BB1000 : Len=0x1000
  77BB1000 -> 77BB5000 : Len=0x4000
  77BB5000 -> 77BB6000 : Len=0x1000
  77BB6000 -> 77BB8000 : Len=0x2000
  77BC0000 -> 77BC1000 : Len=0x1000
  77BC1000 -> 77C0D000 : Len=0x4C000
  77C0D000 -> 77C0F000 : Len=0x2000
  77C0F000 -> 77C10000 : Len=0x1000
  77C10000 -> 77C11000 : Len=0x1000
  77C11000 -> 77C14000 : Len=0x3000
  77C14000 -> 77C18000 : Len=0x4000
  77CF0000 -> 77CF1000 : Len=0x1000
  77CF1000 -> 77D51000 : Len=0x60000
  77D51000 -> 77D52000 : Len=0x1000
  77D52000 -> 77D53000 : Len=0x1000
  77D53000 -> 77D80000 : Len=0x2D000
  77D80000 -> 77D81000 : Len=0x1000
  77D81000 -> 77E0B000 : Len=0x8A000
  77E0B000 -> 77E0C000 : Len=0x1000
  77E0C000 -> 77E12000 : Len=0x6000
  77E20000 -> 77E21000 : Len=0x1000
  77E21000 -> 77E64000 : Len=0x43000
  77E64000 -> 77E66000 : Len=0x2000
  77E66000 -> 77E69000 : Len=0x3000
  77E70000 -> 77E71000 : Len=0x1000
  77E71000 -> 77EDD000 : Len=0x6C000
  77EDD000 -> 77EDE000 : Len=0x1000
  77EDE000 -> 77EE6000 : Len=0x8000
  77EF0000 -> 77EF1000 : Len=0x1000
  77EF1000 -> 77EFE000 : Len=0xD000
  77EFE000 -> 77EFF000 : Len=0x1000
  77EFF000 -> 77F01000 : Len=0x2000
  77F50000 -> 77F51000 : Len=0x1000
  77F51000 -> 77FC6000 : Len=0x75000
  77FC6000 -> 77FC7000 : Len=0x1000
  77FC7000 -> 77FCB000 : Len=0x4000
  77FCB000 -> 77FF8000 : Len=0x2D000
  7C800000 -> 7C801000 : Len=0x1000
  7C801000 -> 7C885000 : Len=0x84000
  7C885000 -> 7C888000 : Len=0x3000
  7C888000 -> 7C88A000 : Len=0x2000
  7C88A000 -> 7C930000 : Len=0xA6000
  7C930000 -> 7C931000 : Len=0x1000
  7C931000 -> 7C9AB000 : Len=0x7A000
  7C9AB000 -> 7C9AE000 : Len=0x3000
  7C9AE000 -> 7C9AF000 : Len=0x1000
  7C9AF000 -> 7C9B0000 : Len=0x1000
  7C9B0000 -> 7C9CB000 : Len=0x1B000
  7D5A0000 -> 7D5A1000 : Len=0x1000
  7D5A1000 -> 7D79F000 : Len=0x1FE000
  7D79F000 -> 7D7AF000 : Len=0x10000
  7D7AF000 -> 7D7B5000 : Len=0x6000
  7D7B5000 -> 7D7BC000 : Len=0x7000
  7D7BC000 -> 7DD9D000 : Len=0x5E1000
  7E8C0000 -> 7E8C1000 : Len=0x1000
  7E8C1000 -> 7E961000 : Len=0xA0000
  7E961000 -> 7E963000 : Len=0x2000
  7E963000 -> 7E971000 : Len=0xE000
  7F6F0000 -> 7F6F7000 : Len=0x7000
  7FFA0000 -> 7FFD3000 : Len=0x33000
  7FFD4000 -> 7FFD5000 : Len=0x1000
  7FFDF000 -> 7FFE0000 : Len=0x1000
  7FFE0000 -> 7FFE1000 : Len=0x1000

Content of 0x10004 -> 0x10103
00010000 :             3A 00 3D 00 3A 00 3A 00 5C 00 00 00 :     :.=.:.:.\...
00010010 : 3D 00 44 00 3A 00 3D 00 44 00 3A 00 5C 00 44 00 : =.D.:.=.D.:.\.D.
00010020 : 6F 00 63 00 75 00 6D 00 65 00 6E 00 74 00 73 00 : o.c.u.m.e.n.t.s.
00010030 : 20 00 61 00 6E 00 64 00 20 00 53 00 65 00 74 00 :  .a.n.d. .S.e.t.
00010040 : 74 00 69 00 6E 00 67 00 73 00 5C 00 68 00 6F 00 : t.i.n.g.s.\.h.o.
00010050 : 6E 00 65 00 79 00 00 00 3D 00 45 00 78 00 69 00 : n.e.y...=.E.x.i.
00010060 : 74 00 43 00 6F 00 64 00 65 00 3D 00 30 00 30 00 : t.C.o.d.e.=.0.0.
00010070 : 30 00 30 00 30 00 30 00 30 00 30 00 00 00 41 00 : 0.0.0.0.0.0...A.
00010080 : 4C 00 4C 00 55 00 53 00 45 00 52 00 53 00 50 00 : L.L.U.S.E.R.S.P.
00010090 : 52 00 4F 00 46 00 49 00 4C 00 45 00 3D 00 44 00 : R.O.F.I.L.E.=.D.
000100A0 : 3A 00 5C 00 44 00 6F 00 63 00 75 00 6D 00 65 00 : :.\.D.o.c.u.m.e.
000100B0 : 6E 00 74 00 73 00 20 00 61 00 6E 00 64 00 20 00 : n.t.s. .a.n.d. .
000100C0 : 53 00 65 00 74 00 74 00 69 00 6E 00 67 00 73 00 : S.e.t.t.i.n.g.s.
000100D0 : 5C 00 41 00 6C 00 6C 00 20 00 55 00 73 00 65 00 : \.A.l.l. .U.s.e.
000100E0 : 72 00 73 00 00 00 41 00 50 00 50 00 44 00 41 00 : r.s...A.P.P.D.A.
000100F0 : 54 00 41 00 3D 00 44 00 3A 00 5C 00 44 00 6F 00 : T.A.=.D.:.\.D.o.
00010100 : 63 00 75 00                                     : c.u.

Find a sequence of unsinged int16:
0x10004 [unsigned int32] : 3997754


여러가지 함수중 메모리 덤프가 굉장히 유용해 보인다.


사용법을 알았으니 실전으로 테스트를 해보자.


먼저 예전에 조사해두었던 지뢰찾기의  각 블럭의 메모리 주소들을 ollydbg로 확인한다.




0x01005340 부터 0x01005490까지

초급 지뢰찾기의 형태가 출력되어 있는것을 확인 할 수 있다.


이 블럭의 값들이 이해를 돕기 위해 해당 블럭의 값들을 정리해 보았다.

 

16진수

블록의 용도

0x10

테두리

0x0F

오픈되지 않은 블록

0x0E

체크한 지뢰

0x0D

물음표

0x40~0x48

주변의 지뢰갯수

0x8F

오픈되지 않은 지뢰

0xCC

빨간색 지뢰(지뢰가 터졌을 때)

0x8A

오픈된 지뢰(게임종료시)




실제 게임화면과 비슷하게 정규식을 사용하여 메모리 덤프한 파일들을 보기좋게 정리하는 코드를 짜봤다.

항상 생각하지만 정규표현식이 아직 많이 부족해서..

더 좋은 방법으로 문자열을 뽑아내고 싶은 마음이 든다.




1
2
3
4
5
6
7
8
9
10
11
use Win32::Process::Memory;

my $proc = Win32::Process::Memory->new({ name=>'winmine.exe' });
printf "\nTotal Memory = 0x%X\n", $proc->get_memtotal;
print "\nContent of 0x01005340 -> 0x01005490\n";
my $block = $proc->hexdump(0x01005340, 0x150);
my @blocks = $block =~ m/10\s.*\s10/g;
$block = join "\n",@blocks;
$block =~ s/10//g;
print "$block";
undef $proc;


http://codepad.org/nviziVV4


깔끔하게 지뢰찾기의 블럭들이 정렬되어 출력된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:\Documents and Settings\honey>perl winmine.pl

Total Memory = 0x1B64000

Content of 0x01005340 -> 0x01005490

 0F 0F 0F 8F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 8F 8F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 8F 0F 0F 0F
 8F 0F 8F 0F 0F 0F 0F 0F 0F
 0F 8F 0F 0F 8F 0F 0F 0F 0F
 0F 0F 8F 0F 0F 0F 8F 0F 0F


이제 게임으로 !!




실제로 출력화면을 보고 지뢰찾기를 한 것인데... 시간은 신경쓰지말자;;


보면서 하니깐 더 안되는... OTL...

위의 출력된 지뢰위치와 그림파일의 지뢰위치가 동일한 것을 확인 할 수 있다.



사용자정의로 말도안되는 지뢰찾기맵을 만들더라도 가볍게 클리어 해주자...





Win32::Process::Memory는 메모리를 write도 가능하기 때문에

위의 작성한 코드를 조금만 수정하여..

모든 블럭의 값을 수정하여 지뢰로 만들어 보았다.




원래는 이런 구성은 만들어 질 수 없으며...

생각만해도 아찔한 영상이다;;



전에 소개한 Win32::GuiTest 모듈을 사용하여

MineFinder를 구현해 보았다.

자동으로 Mine을 찾아서 게임을 클리어 해주는 프로그램인데...



지뢰찾기를 실행시킨 뒤

위의 코드와 같이 정규식으로 뽑아낸 값을 통해서 비교를 한 뒤

해당 위치가 지뢰일 때는 우클릭 그 위외에는 모두 좌클릭을 해 주었다.


머릿속으로 생각한 뒤 구현하려니 좀 버벅되긴 했지만... 

이론으로 충분히 가능했기 때문에 구현하는데 그리 오래 걸리진 않았다.


초급으로 만드는 코드를 처음에 실행한다 ㅡ_ㅡ;

반 강제적으로 초급만 되도록... 설정하였다 ( 중급 고급이 다 되게 하는것이 조금 빡세서...)






대부분 3초안에 클리어 할 수 있으며 빠르면 1초안에 클리어도 가능하다.







Good Job  :- )
신고
Trackback 1 Comment 6
2008.11.17 20:04

Win32::GuiTest - Perl GUI Test Utilities.


최근 Gtk를 사용하여 이것저것 실습을 하던 중

perl로 Windows api를 다루는 모듈은 없을까 cpan에서 

Search를 해보던중 흥미로운 모듈을 발견했다.


Win32::GuiTest

Perl GUI Test Utilities. 
Win32-GuiTest-1.56****  (2 Reviews) - 02 Oct 2008 - Dmitry Karasik


Perl GUI Test Utilities...

갱신된지 얼마 되지 않은 이 모듈은 뭘까?

  use Win32::GuiTest qw(FindWindowLike GetWindowText 
    SetForegroundWindow SendKeys);

  $Win32::GuiTest::debug = 0; # Set to "1" to enable verbose mode

  my @windows = FindWindowLike(0, "^Microsoft Excel", "^XLMAIN\$");
  for (@windows) {
      print "$_>\t'", GetWindowText($_), "'\n";
      SetForegroundWindow($_);
      SendKeys("%fn~a{TAB}b{TAB}{BS}{DOWN}");
  }

코드를 대략 살펴보니 보니  FindWindowLike 함수를 사용하여 윈도우 창을 찾고

그 창에 여러 키를 입력하는 코드였다.

일단 설치를 하고 SYSNOPSIS의 기본 코드를 실행을 시켜보니...

(나의 스타일이 결과부터 보자식이라;;)


실행과 동시에 종료되어 버렸다...

아.. 그렇다;; Excel창이 없으니 자동 종료가 되어버렸....


Excel을 실행 시킨후 다시 perl 프로그램을 실행시키니



헉... 엑셀 시트에 n과 a, b 문자를 출력하고 있다.

왠지 흥미롭지 않는가? +_+



전체적으로 key 뿐만아니라 Mouse 까지 다루고 있으며

SendKeys함수의 세부적인 Action 까지 상세하게 다루고 있다.

이것 하나만 있으면 엑셀을 사용하는 사람은... 

조금 더 편하게 문서를 정리 할 수 있지 않을까?




사용법을 완벽하게 익히기에 예제가 조금 부족한 느낌이 들었는데


Win32::GuiTest::Examples

collection of the scripts from eg 
Win32-GuiTest-1.56****  (2 Reviews) - 02 Oct 2008 - Dmitry Karasik


예제까지 확실하게 Cpan에 올려놓으셨다..




Examples에는 총 26개의 예제가 있으며 재밌는 코드를 소개하자면!!


   #!perl -w
    #
    # Draw an X and a box around it
    #
    use strict;
    use Win32::GuiTest qw(FindWindowLike SetForegroundWindow 
        SendMouse MouseMoveAbsPix SendLButtonDown SendLButtonUp);
    
    system("start /max mspaint");
    sleep 2;
    my @windows = FindWindowLike(0, "Paint", "");
    die "Could not find Paint\n" if not @windows;
    
    SetForegroundWindow($windows[0]);
    sleep 1;
    
    #Using low level functions
    MouseMoveAbsPix(100,100);
    SendLButtonDown();
    MouseMoveAbsPix(300,300);
    SendLButtonUp();
    
    
    sleep 1;
    
    MouseMoveAbsPix(100,300);
    SendLButtonDown();
    MouseMoveAbsPix(300,100);
    SendLButtonUp();
    
    sleep 1;
        
    MouseMoveAbsPix(100,100);
    SendLButtonDown();
    MouseMoveAbsPix(300,100);
    MouseMoveAbsPix(300,300);
    MouseMoveAbsPix(100,300);
    MouseMoveAbsPix(100,100);
    SendLButtonUp();


윈도우 창을 찾을 때 한글을 고려하자면...

my @windows = FindWindowLike(0, "Paint", "");

이런식으로 고쳐주셔야...

my @windows = FindWindowLike(0, "제목 없음 - 그림판", "");



시스템 함수를 사용하여 mspaint 를 실행시킨후

마우스를 이동시키며 정사각형안에 X가 들어있는 그림을 그리는 코드이다.

실용성은 없어보이지만 볼거리가 있는 코드라 넣어놓는다






그 이외에...

계산기를 실행하여 자동으로 숫자와 연산자를 입력하여 결과값을 구해주는 코드

노트패드에 글을 쓴 뒤 자동으로 종료해주는 코드, 

//이건 재미있어서 실행파일로 만들어 보았다.




카드놀이를 실행한뒤 이것저것 만져주는 코드,

컴퓨터의 제어판의 여러 목록들을 실행하고 종료하는 코드,

윈도우의 모든 창을 찾아주는 코드,

해당 창을 찾아 캡쳐를 한 뒤 자동으로 저장해주는 코드  등 // 위험한 느낌이 들었던..;

유용한 코드들이 많이 보였다.



보안적인 면에서는 백그라운드로 실행되는 것이 아니기 때문에

해킹툴보다는 조크바이러스 정도로 밖에 안될듯...


나 너 해킹했어요~ 이렇게 알려주는 것이라...

비주얼 적인 면에서는 효과가 뛰어날 것이라 본다.




오토마우스 오토키보드 같은 프로그램이 있긴 하지만...

perl을 사용하여 직접 프로그램을 만들어 보는것도

흥미로운 작업이 아닐까 생각된다^^
신고
Trackback 5 Comment 2