날씨 검색 스크립트

구글 날씨 API를 이용해서 적절하게 완성. 제작하는데 소요된 시간은 한시간정도..;
사용법 : !날씨 지역 (국내 도시는 한글로 써도 되지만, 외국 도시의 경우 영어로 써줄것)

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:#: {
  if ($1 == !날씨) {
    if (!$2) {
      msg $chan 사용법 : !날씨 지역”  (ex : !날씨 서울)
      halt
    }
    unset %weather.*
    set %weather.id $replace($2-,$chr(32),+)
    set %weather.id2 $replace(%weather.id,강릉,gangneung,경주,gyeongju,고양,goyang,광명,gwangmyeong,광주,gwangju,구미,gumi,군산,gunsan,군포,gunpo,김해,gimhae,대구,daegu,대전,daejeon,동해,donghae,목포,mokpo,부산,busan,부천,bucheon,서귀포,seogwipo,서울,seoul,성남,seongnam,송탄,songtan,수원,suwon)
    set %weather.id2 $replace(%weather.id2,시흥,siheung,안산,ansan,안양,anyang,용인,yongin,울릉도,ulleung-do,울산,ulsan,원주,wonju,의정부,uijeongbu,익산,iksan,인천,incheon,일산,ilsan,전주,jeonju,제주,jeju,진주,jinju,철원,cheorwon,청주,cheongju)
    set %weather.id2 $replace(%weather.id2,춘천,chuncheon,파주,paju,평택,pyeongtaek,포항,pohang,흑산도,heuksan-do,충주,chungju,상주,sangju,창원,changwon,천안,cheonan,여수,yeosu,안동,andong,양산,yangsan,태안,taean,진해,jinhae,오산,osan,순천,suncheon,당진,dangjin,마산,masan,삼척,samchok,거제,kuje)
    set %weather.chan $chan
    sockclose weather
    sockopen weather www.google.co.kr 80
    halt
  }
}
on *:sockopen:weather*: {
  sockwrite -nt $sockname GET /ig/api?weather= $+ %weather.id2 HTTP/1.1
  sockwrite -nt $sockname User-Agent: Mozilla/4.0
  sockwrite -nt $sockname Host: www.google.co.kr
  sockwrite -nt $sockname Connection: Close
  sockwrite -nt $sockname $crlf
}
on *:sockread:weather: {
  sockread %tmp
  set %weather.end </xml_api_reply>
  set %weather.error problem_cause data
  if (%weather.error isin %tmp) {
    msg %weather.chan 일시적으로 정보가 사용이 불가능한 지역이거나 검색이 지원되지 않는 지역입니다.
    sockclose $sockname
    unset %weather.* 
  }
  set %weather.date $remove($gettok(%tmp,9,62),<forecast_date data=,”,$chr(47))
  set %weather.condition $remove($gettok(%tmp,14,62),<condition data=,”,$chr(47))
  set %weather.tempf $remove($gettok(%tmp,15,62),<temp,$chr(95),data,=,”,$chr(47))
  set %weather.tempc $remove($gettok(%tmp,16,62),<temp,$chr(95),data,=,”,$chr(47))
  set %weather.humidity $remove($gettok(%tmp,17,62),<humidity data=”습도: ,”,$chr(47))
  set %weather.wind $remove($gettok(%tmp,19,62),<wind_condition data=”바람: ,”,$chr(47))
  set %weather.week $remove($gettok(%tmp,22,62),<day_of_week data=,”,$chr(47))
  set %weather.tomorrow $remove($gettok(%tmp,26,62),<condition data=,”,$chr(47))
  set %weather.tomorrow2 $remove($gettok(%tmp,29,62),<day_of_week data=,”,$chr(47))
  set %weather.a3days $remove($gettok(%tmp,33,62),<condition data=,”,$chr(47))
  set %weather.a3days2 $remove($gettok(%tmp,36,62),<day_of_week data=,”,$chr(47))
  set %weather.kmh2ms $mid($calc($remove($gettok(%weather.wind,2,44),kmh) * 1000 / 3600),1,3) m/s

  if (%weather.end isin %tmp) {
    msg %weather.chan 지역명 : $replace(%weather.id,+,$chr(32)) / 날짜 : %weather.date $+ ( $+ %weather.week $+ ) / 상태 : %weather.condition / 기온 : $mid(%weather.tempc,3) °C ( $+ $mid(%weather.tempf,3) °F) / 습도 : %weather.humidity / 풍속 : $replace(%weather.wind,kmh,km/h) ( $+ %weather.kmh2ms $+ ) / 내일( $+ %weather.tomorrow2 $+ ) : %weather.tomorrow / 모래( $+ %weather.a3days2 $+ ) : %weather.a3days
    sockclose $sockname
    unset %weather.* 
  }
}

서든어택 전적 검색 스크립트

적용법
1. 챗창에 //echo -a $mircdir 라고 치고 엔터를 치면, 현재 스크립트를 어디다 저장해야 하는지 경로가 나온다.
2. 아래의 내용을 복사해서 메모장에 넣고 sudden.mrc로 저장한 후 해당 경로로 이동하여 방금 만든 파일을 넣는다.
3. 다시 챗창에 와서 /load -rs sudden.mrc 라고 친 후 앤터.
4. Usage : !서든 아이디명 (ex : !서든 xeriars)

출력결과의 예 :

[12:46:21] <@Xeriars> !서든 Xeriars
[12:46:21] <@Zod> 아이디 : Xeriars / 순위 : 8,941,712위 (▼ 1884) / 계급 : 상병 / 클랜 : 없음 / 경험치 : 22,469 / 게임포인트 : 279
[12:46:21] <@Zod> 킬데스 : 694 / 943(42%) / 전적 : 97전 45승 0무 52패 / 헤드샷 : 116회 / 승률 : 46% / 보유중인 주 무기 : SCOUT SR-69, SMG U101, M16

아래부터가 스크립트의 시작…

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:*:#: {
if ($1 == !서든) {
if (!$2) { msg $chan Usage : !서든 아이디명 | halt }
unset %sda.*
set %sda.chan $chan
set %sda.id $2
set %sda.count 1
sockclose sattack
sockopen sattack suddenattack.netmarble.net 80
halt
}
}

on *:sockopen:sattack: {
sockwrite -nt $sockname GET /Ranking/Total/ninc_Search.asp?id=&pagegu=index&Condition=2&p_userid= $+ $urlencode(%sda.id) HTTP/1.1
sockwrite -nt $sockname User-Agent: Mozilla/4.0
sockwrite -nt $sockname Host: suddenattack.netmarble.net
sockwrite -nt $sockname Accept-Language: ko
sockwrite -nt $sockname Accept: */*
sockwrite -nt $sockname Connection: Keep-Alive
sockwrite -nt $sockname $crlf
}
on *:sockread:sattack: {
sockread %tmp
set %sda.word <td colspan=”5″ style=”color:#82A3A3″><a href=”javascript:GetSaInfo_new
set %sda.word2 <td width=”122″ style=”color:#82A3A3″>
set %sda.word3 <td width=”89″>
set %sda.word4 <td width=”184″>
set %sda.remove $eval(%2Franking%2FPopUp%2FSaGameInfo%2Easp%3FUserID=,0)
set %sda.error private_nosearch01.gif

if (%sda.word isin %tmp) { set %sda.userid $remove($gettok($replace(%tmp,$eval(%3d,0),=),2,39),%sda.remove) }
if (%sda.word2 isin %tmp) {
set %sda.rank $replace($remove(%tmp,<img src=http://c3.img.netmarble.kr/web/2005_cp/img/suddenattack_v2/common/bl/,$chr(9),%sda.word2,02.gif,01.gif,align=’absmiddle’><span class=’blue p11′>,</td>,</span>),down_arrow ,▼,up_arrow ,▲)
}
if (%sda.word3 isin %tmp) { set %sda.grade $remove($gettok(%tmp,3,62),</td) }
if (%sda.word4 isin %tmp) {
set %sda.guild $remove($gettok(%tmp,4,62),</a)
if (!%sda.guild) { set %sda.guild 없음 }
sockclose sda
sockopen sda suddenattack.netmarble.net 80
sockclose $sockname
}
if (%sda.error isin %tmp) {
msg %sda.chan 해당 플레이어의 정보를 찾을 수 없습니다. 아이디를 다시 한번 확인해주시기 바랍니다.
sockclose $sockname
unset %sda.*
}
}
on *:sockopen:sda: {
sockwrite -nt $sockname GET /ranking/PopUp/SaGameInfo.asp?UserID= $+ %sda.userid HTTP/1.1
sockwrite -nt $sockname User-Agent: Mozilla/4.0
sockwrite -nt $sockname Host: suddenattack.netmarble.net
sockwrite -nt $sockname Accept-Language: ko
sockwrite -nt $sockname Accept: */*
sockwrite -nt $sockname Connection: Keep-Alive
sockwrite -nt $sockname $crlf
}
on *:sockread:sda: {
sockread %tmp
set %sda.pword suddenattack_v2/ranking/pop_txt04.gif”></td>
set %sda.pword2 suddenattack_v2/ranking/pop_txt05.gif”></td>
set %sda.pword3 suddenattack_v2/ranking/pop_txt07.gif” style=”margin-left:1px;”></td>
set %sda.pword4 suddenattack_v2/ranking/pop_txt08.gif” style=”margin-left:1px;”></td>
set %sda.pword5 suddenattack_v2/ranking/pop_txt09.gif” width=”98″ height=”12″ style=”margin-left:1px;”></td>
set %sda.pword6 suddenattack_v2/ranking/pop_txt10.gif” width=”98″ height=”12″ style=”margin-left:1px;”></td>

if (%sda.count == 2) { set %sda.exp $remove(%tmp,<td>,</td>,$chr(9)) | set %sda.count 1 }
if (%sda.count == 3) { set %sda.point $remove(%tmp,<td>,</td>,$chr(9)) | set %sda.count 1 }
if (%sda.count == 4) { set %sda.killed $remove(%tmp,<td>,</td>,$chr(9),&nbsp;) | set %sda.count 1 }
if (%sda.count == 5) { set %sda.record $remove(%tmp,<td>,<strong>,</strong>,&nbsp;,<span style=”color:#CC3300″>,</span>,<span style=”color:#0066CC”>,</td>,$chr(9)) | set %sda.count 1 }
if (%sda.count == 6) { set %sda.headshot $remove(%tmp,<td>,</td>,$chr(9)) | set %sda.count 1 }
if (%sda.count == 7) { set %sda.ratio $remove(%tmp,<td>,</td>,$chr(9)) | set %sda.count 100 }

if (%sda.count == 100) {
sockclose sdat
sockopen sdat suddenattack.netmarble.net 80
sockclose $sockname
}

if (%sda.pword isin %tmp) { set %sda.count 2 }
if (%sda.pword2 isin %tmp) { set %sda.count 3 }
if (%sda.pword3 isin %tmp) { set %sda.count 4 }
if (%sda.pword4 isin %tmp) { set %sda.count 5 }
if (%sda.pword5 isin %tmp) { set %sda.count 6 }
if (%sda.pword6 isin %tmp) { set %sda.count 7 }
}
on *:sockopen:sdat: {
sockwrite -nt $sockname GET /Item/GInventory_Ranking.asp?UserID= $+ %sda.userid HTTP/1.1
sockwrite -nt $sockname User-Agent: Mozilla/4.0
sockwrite -nt $sockname Host: suddenattack.netmarble.net
sockwrite -nt $sockname Accept-Language: ko
sockwrite -nt $sockname Accept: */*
sockwrite -nt $sockname Connection: Keep-Alive
sockwrite -nt $sockname $crlf
}
on *:sockread:sdat: {
sockread %tmp
set %sda.aword <td align=”center” bgcolor=”0B1D1A” class=”w02″
set %sda.end <td width=”124″> &nbsp; </td>
if (%sda.aword isin %tmp) { set %sda.weapon %sda.weapon $+ $chr(44) $gettok($gettok(%tmp,2,62),1,60) }
if (%sda.end isin %tmp) {
timeoutoff
msg %sda.chan 아이디 : %sda.id / 순위 : %sda.rank / 계급 : %sda.grade / 클랜 : %sda.guild / 경험치 : %sda.exp / 게임포인트 : %sda.point
msg %sda.chan 킬데스 : %sda.killed / 전적 : %sda.record / 헤드샷 : %sda.headshot / 승률 : %sda.ratio / 보유중인 주 무기 : $mid(%sda.weapon,3)
sockclose $sockname
unset %sda.*
}
}

alias urlencode {
var %i = 0, %r
while (%i < $len($1-)) {
inc %i
%r = %r $+ $chr(37) $+ $base($asc($mid($1-,%i,1)),10,16,2)
}
return %r
}

WOW 캐릭터 정보 검색 스크립트

정상작동을 위해서는 utf8.dll 파일이 필요하다.

utf8.zip

mIRC 6.34에서 정상작동함을 확인하였다.
전투정보실(kr.wowarmory.com)에서 검색하여 IRC상으로 데이터를 뿌려주는것을 기본으로 한다.
스크립트 중간에 변수지정부분에서 글자가 깨진것처럼 보이는것이 있는데,
이것은 UTF-8형식을 CP949 형태로 깨져서 표시되어 그런것이나, 사용상에는 전혀 문제가 없으니 그냥 복사해서 붙일 것.

필자는 WOW에 대해서는 일체 모르므로(플레이 해본적도 없다) 질문은 받지 않음.

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:*:#: {
if ($1 == !와우) {
if (!$2) { msg $chan 사용법 : !와우 캐릭명 서버명 | halt }
if (!$3) { msg $chan 사용법 : !와우 캐릭명 서버명 | halt }
unset %wow.*
set %wow.chan $chan
set %wow.id $2
set %wow.serv $3
set %wow.count 1
sockclose wow
sockopen wow kr.wowarmory.com 80
halt
}
}
on *:input:*: {
if ($1 == !와우) {
if (!$2) { say 사용법 : !와우 캐릭명 서버명 | halt }
if (!$3) { say 사용법 : !와우 캐릭명 서버명 | halt }
unset %wow.*
set %wow.chan $chan
set %wow.id $2
set %wow.serv $3
set %wow.count 1
sockclose wow
sockopen wow kr.wowarmory.com 80
halt
}
}
on *:sockopen:wow*: {
sockwrite -nt $sockname GET /character-sheet.xml?r= $+ $urlencode($dll(utf8.dll,convertutf8,%wow.serv)) $+ &n= $+ $urlencode($dll(utf8.dll,convertutf8,%wow.id)) HTTP/1.1
sockwrite -nt $sockname User-Agent: Mozilla/4.0
sockwrite -nt $sockname Host: kr.wowarmory.com
sockwrite -nt $sockname Connection: Keep-Alive
sockwrite -nt $sockname Accept-Language: ko
sockwrite -nt $sockname $crlf
}
on *:sockread:wow: {
sockread %tmp
set %wow.word1 <a class=”charGuildName”
set %wow.word2 <a href=”character-talents.xml?r=
set %wow.word3 <div class=”bar-container staticTip” onmouseover=”setTipText(
set %wow.word4 <div class=”health-stat”>
set %wow.word5 留덈굹:&nbsp;&nbsp;
set %wow.word6 float: right; margin: 0 0px 0 0;”>
set %wow.word7 <span class=”charLvl”>
set %wow.word8 <a class=”achPointsLink” href=”/character-
set %wow.word9 <span>湲곕젰:&nbsp;&nbsp;
set %wow.word10 <div class=”runic-stat”>
set %wow.word11 <span>遺꾨끂:&nbsp;&nbsp;
set %wow.prefix <span class=”prefix”>
set %wow.error <str id=”armory.labels.nocharacter”>

if (%wow.error isin %tmp) {
msg %wow.chan 존재하지 않는 캐릭터이거나 캐릭터 이전, 유료 캐릭터명 변경 서비스 이용으로 인해 일시적으로 검색이 되지 않는 캐릭터입니다.
msg %wow.chan 캐릭터 이름을 바르게 입력하셨는지 확인하시기 바랍니다. 삭제된 캐릭터는 전투정보실에서 검색할 수 없습니다.
sockclose $sockname
unset %wow.*
halt
}
if (%wow.count == 8) { set %wow.result9 $remove($gettok(%tmp,3,59),</span>) | set %wow.count 1 }
if (%wow.count == 7) { inc %wow.count }
if (%wow.count == 6) { set %wow.result5 $remove($gettok(%tmp,3,59),</span>) | set %wow.count 1 }
if (%wow.count == 5) { inc %wow.count }
if (%wow.count == 4) { set %wow.result4 %wow.result4 $remove($gettok(%tmp,2,62),</b) | set %wow.count 1 }
if (%wow.count == 3) { set %wow.result3 %wow.result3 $remove(%tmp,<span>,</span>,<) | set %wow.count 1 }
if (%wow.count == 2) { inc %wow.count }
if (%wow.word1 isin %tmp) { set %wow.result1 $dll(utf8.dll,convertlocal,$remove($gettok(%tmp,2,62),</a)) }
if (%wow.word2 isin %tmp) { set %wow.result3 %wow.result3 $+ $chr(44) $remove($gettok(%tmp,2,62),</a) | set %wow.count 2 }
if (%wow.word3 isin %tmp) { set %wow.result4 %wow.result4 $+ $chr(44) $remove($gettok(%tmp,4,34),settiptext,’,$chr(40),$chr(41)) | set %wow.count 4 }
if (%wow.word4 isin %tmp) { set %wow.count 5 }
if (%wow.word5 isin %tmp) { set %wow.result6 $remove($gettok(%tmp,3,59),</span>) }
if (%wow.word6 isin %tmp) {
if (%wow.word8 isin %tmp) { set %wow.result7 $remove($gettok(%tmp,3,62),</span) }
else { set %wow.result7 $remove($gettok(%tmp,2,62),</span) }
set %wow.count 100
}
if (%wow.word7 isin %tmp) {
if (%wow.word1 isin %tmp) { set %wow.result2 $remove($replace($gettok(%tmp,4,62),&nbsp;,$chr(32)),</span) }
else { set %wow.result2 $replace($remove(%tmp,%wow.word7,</span>),&nbsp;,$chr(32)) }
}
if (%wow.word9 isin %tmp) { set %wow.result8 $remove($gettok(%tmp,3,59),</span>) }
if (%wow.word10 isin %tmp) { set %wow.count 7 }
if (%wow.word11 isin %tmp) { set %wow.result10 $remove($gettok(%tmp,3,59),</span>) }
if (%wow.prefix isin %tmp) { set %wow.pre $dll(utf8.dll,convertlocal,$remove(%tmp,%wow.prefix,</span>)) }

if (%wow.count == 100) {
set %wow.result2 $dll(utf8.dll,convertlocal,%wow.result2)
set %wow.result3 $dll(utf8.dll,convertlocal,%wow.result3)
set %wow.result4 $dll(utf8.dll,convertlocal,%wow.result4)
if (!%wow.result1) { set %wow.result1 없음 }
if (!%wow.result2) { set %wow.result2 정보없음 }
if (!%wow.result3) { set %wow.result3 없음 }
if (!%wow.result4) { set %wow.result4 없음 }
if (!%wow.result7) { set %wow.result7 없음 }
if (%wow.result8) { set %wow.sp %wow.result8 | set %wow.mana 기력 }
if (%wow.result6) { set %wow.sp %wow.result6 | set %wow.mana 마나 }
if (%wow.result9) { set %wow.sp %wow.result9 | set %wow.mana 룬 마력 }
if (%wow.result10) { set %wow.sp %wow.result10 | set %wow.mana 분노 }

msg %wow.chan 아이디 : %wow.pre %wow.id / 서버 : %wow.serv / 캐릭터 : %wow.result2 / 업적 : $comgen(%wow.result7) $+ 점 / 길드명 : %wow.result1
msg %wow.chan 생명력 : $comgen(%wow.result5) / %wow.mana : $comgen(%wow.sp) / 특성 전문화 : $mid(%wow.result3,3) / 전문 기술 : $mid(%wow.result4,3)
msg %wow.chan 원문주소 : http://kr.wowarmory.com/character-sheet.xml?r= $+ $urlencode($dll(utf8.dll,convertutf8,%wow.serv)) $+ &n= $+ $urlencode($dll(utf8.dll,convertutf8,%wow.id))
sockclose $sockname
unset %wow.*
halt
}
}
alias urlencode {
var %i = 0, %r
while (%i < $len($1-)) {
inc %i
%r = %r $+ $chr(37) $+ $base($asc($mid($1-,%i,1)),10,16,2)
}
return %r
}
alias comgen {
if ($1 == $chr(48)) { return $chr(48) | halt }
if (!$1) { return Error | halt }
if ($1 > 0) { var %sign 1 | var %subsnum $len($int($1)) }
if ($1 <= 0) { var %sign 2 | var %subsnum $calc($len($int($1)) – 1) }
var %rev.left = %subsnum
var %tmp = $reverse($int($1),$int($1))
var %point = $mid($calc($1 – $int($1)),3)
var %i 1
while (%i <= %subsnum) {
if ($len($mid(%tmp,%i,3)) == 3) {
var %rev.var = %rev.var $+ $mid(%tmp,%i,3) $+ $chr(44) | var %rev.left $calc(%rev.left – 3)
}
else { var %rev.var = %rev.var $+ $mid(%tmp,%i,%rev.left) }
var %i $calc(%i + 3)
}
if ($mid(%point,1,1) != $chr(46)) { var %point $chr(46) $+ %point }
if (!$mid(%point,2,1)) { var %point $chr(32) }
if ($mid($reverse(%rev.var,%rev.var),1,1) == $chr(44)) {
if (%sign == 1) { return $mid($reverse(%rev.var,%rev.var),2) $+ %point | halt }
if (%sign == 2) { return $chr(45) $+ $remove($mid($reverse(%rev.var,%rev.var),2),$chr(45)) $+ %point | halt }
}
if ($mid($reverse(%rev.var,%rev.var),1,1) == $chr(45)) {
if (%sign == 1) { return $mid($reverse(%rev.var,%rev.var),1) $+ %point | halt }
if (%sign == 2) { return $chr(45) $+ $remove($mid($reverse(%rev.var,%rev.var),1),$chr(45)) $+ %point }
}
else {
if (%sign == 1) { return $reverse(%rev.var,%rev.var) $+ %point | halt }
if (%sign == 2) { return $chr(45) $+ $reverse(%rev.var,%rev.var) $+ %point | halt }
}
}
alias reverse {
var %i = 1, %tmp
while (%i <= $len($1)) {
var %n = $iif($asc($mid($1,%i,1)) > 127,2,1), %tmp = $iif($mid($1,%i,%n) == $chr(32),$!chr(32),$v1) $+ %tmp
inc %i %n
}
return $replace(%tmp,$!chr(32),$chr(32))
}

Youtube 검색 스크립트

꽤 오래전에 만든 스크립트인데 이제서야 공개하게 되었다.
단, $mircdir 에 utf8.dll 파일이 필요하니 첨부파일을 다운로드 할것.

이 스크립트를 가져다 쓸 사람은 아래부터 복사해서 쓰면 된다. (mIRC 6.3 에서 정상작동 확인함)

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————
on *:text:*:#: {
    if ($1 == @유튜브) {
      if (!$2) { msg $chan Usage : @유튜브 검색어 | halt }
      unset %youtube.*
      set %youtube.chan $chan
      set %youtube.word $2-
      set %youtube.url $urlencode($dll(utf8.dll,convertutf8,%youtube.word))
      set %youtube.count 1
      set %youtube.nick $nick
      sockclose youtube
      sockopen youtube www.youtube.com 80
      halt
    }
}

on *:sockopen:youtube*: {
  sockwrite -nt $sockname GET /results?search_type=&search_query= $+ %youtube.url $+ &aq=f HTTP/1.1
  sockwrite -nt $sockname User-Agent: Mozilla/4.0
  sockwrite -nt $sockname Host: www.youtube.com
  sockwrite -nt $sockname Connection: Close
  sockwrite -nt $sockname $crlf
}
on *:sockread:youtube: {
  sockread %tmp
  set %youtube.search0 약 <strong>
  set %youtube.search0 $dll(utf8.dll,convertutf8,%youtube.search0)
  set %youtube.search1 <div class=”v120WideEntry”><div class=”v120WrapperOuter”>
  set %youtube.search2 class=”video-description”>
  set %youtube.search3 <button class=”master-sprite ratingVS ratingVS-
  set %youtube.search4 class=”video-date-added”>
  set %youtube.search5 class=”video-view-count”>
  set %youtube.search6 <span class=”video-username”>
  set %youtube.error <div style=”margin-top: 10px”><span
  set %youtube.error2 icn_cycds_warning-vfl33982.gif

  if (%youtube.count == 2) {
    set %youtube.describe $dll(utf8.dll,convertlocal,$replace($remove(%tmp,$chr(9)),<b>,,</b>,))
    set %youtube.count 1
  }

  if (%youtube.error isin %tmp) {
    msg %youtube.chan ” $+ %youtube.word $+ ” 의 검색결과가 존재하지 않습니다.
    sockclose $sockname
    unset %youtube.* 
  }
  if (%youtube.error2 isin %tmp) {
    msg %youtube.chan ” $+ %youtube.word $+ ” 의 검색결과가 존재하지 않습니다.
    sockclose $sockname
    unset %youtube.* 
  }
  if (%youtube.search0 isin %tmp) {
    set %youtube.amount $remove($gettok(%tmp,1,47),%youtube.search0,<,$chr(9))
  }
  if (%youtube.search1 isin %tmp) {
    set %youtube.id $remove($gettok(%tmp,8,34),$chr(9),video-url-)
    set %youtube.video http://www.youtube.com/watch?v= $+ %youtube.id
    set %youtube.subject $dll(utf8.dll,convertlocal,$remove($gettok(%tmp,14,34),$chr(9)))
  }
  if (%youtube.search3 isin %tmp) { set %youtube.ratio $gettok(%tmp,4,34) $+ 점 }
  if (%youtube.search4 isin %tmp) { set %youtube.added $dll(utf8.dll,convertlocal,$remove($gettok(%tmp,5,34),</span>,>)) }
  if (%youtube.search5 isin %tmp) { set %youtube.vcount $remove($dll(utf8.dll,convertlocal,$remove($gettok(%tmp,5,34),</span>,>)),조회,수,$chr(32)) }
  if (%youtube.search6 isin %tmp) { set %youtube.user $remove($gettok(%tmp,9,34),</a>,</span>,>) | set %youtube.count 77 } 
  if (%youtube.count == 77) {
    if (!%youtube.ratio) { set %youtube.ratio 평점없음 }
    msg %youtube.chan $chr(91) $+ %youtube.subject $+ $chr(93) – %youtube.video ( $+ 약 %youtube.amount $+ 개의 동영상 검색)
    msg %youtube.chan 설명 : %youtube.describe
    msg %youtube.chan 등록일 : %youtube.added / 평점 : %youtube.ratio / 조회 수 : %youtube.vcount / 등록자 : %youtube.user
    notice %youtube.nick 더 많은 결과를 보시려면 http://www.youtube.com/results?search_type=&search_query= $+ %youtube.url $+ &aq=f 를 참조하십시요.
    sockclose $sockname
    unset %youtube.*
  }
  if (%youtube.search2 isin %tmp) { set %youtube.count 2 }
}

오랜만의 포스팅.. 택배추적 스크립트

핸드폰 고리를 주문한게 오늘 우체국 택배로 온다.
기다림에 지쳐서 IRC에서 검색할수 있도록 택배추적 기능을 만들었다.

혹시나 가져다 쓰실분은 아래부터 복사하시면 된다.

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:*:#: {
if ($1 == @택배추적 || $1 == -택배추적 || $1 == !택배추적) {
if (!$2) { msg $chan 택배 회사를 입력하여 주십시요. | halt }
if (!$3) { msg $chan 운송장 번호를 입력하여 주십시요. | halt }
if ($len($3) != 13) { msg $chan 운송장번호가 13자리가 아닙니다. 다시 확인해주십시요. | halt }
if ($len($3) !isnum) { msg $chan 운송장번호가 잘못되었습니다. | halt }
unset %deli.*
set %deli.chan $gettok(%Zodbot.data,3,32)
set %deli.count 1
if ($2 == 우체국) {
if ($exists(tmp_epost.txt)) { remove tmp_epost.txt }
if ($exists(epost.txt)) { remove epost.txt }
set %deli.id $3
sockclose epost
sockopen epost service.epost.go.kr 80
}
halt
}
}
on *:sockopen:epost*: {
sockwrite -nt $sockname GET /trace.RetrieveRegiPrclDeliv.postal?sid1= $+ %deli.id HTTP/1.1
sockwrite -nt $sockname User-Agent: Mozilla/4.0
sockwrite -nt $sockname Host: service.epost.go.kr
sockwrite -nt $sockname Connection: Close
sockwrite -nt $sockname $crlf
}
on *:sockread:epost: {
sockread %tmp
set %deli.error 배달정보를 찾지 못했습니다.<br><br>
set %deli.sender <td bgcolor=”#FFFFFF” width=”300″ height=”20″ align=left>
set %deli.receiver <td bgcolor=”#FFFFFF” align=”left”>
set %deli.word <tr bgcolor=”#FFFFFF”>
set %deli.worde <input type=hidden name=pcode value=
set %deli.end <td bgcolor=”#FFFFFF” colspan=3 align=’center’>
set %deli.eof 우체국콜센터(1588-1300번)

if (%deli.error isin %tmp) {
msg %deli.chan 배달정보를 찾지 못했습니다. 정보가 아직 입력되지 않았거나 처리 중입니다.
sockclose $sockname
unset %deli.*
}
if (%deli.eof isin %tmp) {
set %deli.date1 $gettok($read(tmp_epost.txt,1),1,47)
var %i 0
var %j 0
while (%i < $lines(tmp_epost.txt)) {
inc %i
if ($mid($read(tmp_epost.txt,1),1,1) == $chr(47)) {
write epost.txt $chr(91) $+ $gettok($read(tmp_epost.txt,%i),1,47) $+ $chr(93) $+ $gettok($deltok($read(tmp_epost.txt,%i),1,62),1,47) ( $+ $gettok($deltok($read(tmp_epost.txt,%i),1,62),2,47) $+ , $gettok($read(tmp_epost.txt,%i),2,47) $+ )
}
}
while (%j < $lines(epost.txt)) {
inc %j
if (%j isnum 1-4) { set %deli.result1 %deli.result1 $+ → $+ $read(epost.txt,%j) }
elseif (%j > 4 && %j < 9) { set %deli.result2 %deli.result2 $+ → $+ $read(epost.txt,%j) }
elseif (%j >= 9) { set %deli.result3 %deli.result3 $+ → $+ $read(epost.txt,%j) }
}
msg %deli.chan 발송인 : %deli.rs / 수취인 : %deli.rr / 수령인 : $remove(%deli.rrr,$chr(40),$chr(41),수령인,$chr(58),님,$chr(9),$chr(32))
msg %deli.chan $mid(%deli.result1,3)
if (%deli.result2) { msg %deli.chan $mid(%deli.result2,3) }
if (%deli.result3) { msg %deli.chan $mid(%deli.result3,3) }
sockclose $sockname
unset %deli.*
}
if (%deli.sender isin %tmp) { set %deli.rs $remove(%tmp,%deli.sender,&nbsp;,</td>,$chr(9)) }
if (%deli.receiver isin %tmp) { set %deli.rr $remove(%tmp,%deli.receiver,&nbsp;,</td>,$chr(9)) }
if (%deli.end isin %tmp) {
set %deli.count 1
set %deli.rrr $remove(%tmp,%deli.end,</td>,$chr(9))
}
if (%deli.worde isin %tmp) { set %deli.count 1 | write tmp_epost.txt $remove(%deli.tmp1,$asctime(yyyy) $+ $chr(46),//,///,$chr(32)) | unset %deli.tmp1 }
if (%deli.count == 7) {
if ($remove(%tmp,$chr(32))) {
set %deli.tmp1 %deli.tmp1 $+ / $+ $remove(%tmp,<td align=’center’>,&nbsp;,<font color=’red’>,<tr>,<td bgcolor=#FFFFFF colspan=3 align=’center’>,<td rowspan=2 align=’center’>,<font color=’red’ >,<b>,</b>,</font>,</td>,</tr>,&nbsp;,$chr(9),$chr(40),$chr(41),</td>,</a>,<a href=”javascript:goPostDetail,$chr(34))
}
}
if (%deli.word isin %tmp) { set %deli.count 7 }
}

Zod의 최초 취약점이 발견된 사건…

종류 : 취약점
증상 : 원격에서 Zod에 임의의 코드를 전송하여 실행시킬수 있음.
발견자 : MrGeek (http://geekproject.net/)

Zod에는 여러가지 기능중 여러가지 Encoded Text를 다시 decoding 할 수 있는 기능을 가지고 있다.
어제 #c0**** 채널에서 놀던 아래와 같은 Encoded Text를 보게되었다.

s60gwKe068fRILDHtOPAzLTZISEhDQpuaWNrILDHtOMNCnF1aXQgOrDHtOMgx9ewocfXsKE=

척 보아하니 MIME(Multipurpose Internet Mail Extensions)로 Encode 된것 같다.
무슨 텍스트인가 싶어서 Zod의 @디코딩 명령을 이용해서 디코드 하려는데.. (@디코딩 m encoded text)
갑자기 Zod의 닉이 “건담”으로 바뀌더니 “건담 항가항가”라는 quit message를 남기고 나가버렸다.

그래서 echo를 통해서 해당 텍스트를 디코딩 해보았다.



var %aaa s60gwKe068fRILDHtOPAzLTZISEhDQpuaWNrILDHtOMNCnF1aXQgOrDHtOMgx9ewocfXsKE=
//say $decode(%aaa,m)을 사용하면 “난 위대한 건담이다!!!!”를 출력한후
/nick 건담 /quit :건담 항가항가(quit message)를 작동시키는 코드가 숨겨져 있었다.

즉, 출력하기전에 decoded message를 변수로 받은후 이 변수를 scan하여
ascii코드중 10~13번 문자열이 포함되어 있다면 그자리에서 출력을 멈추고 에러메시지를 출력함으로써
이 문제를 해결 할 수 있다.
(MSL에는 $crlf 의 함수가 이 문자열을 대신하지만 $chr(10) 등으로 구현하여도 된다.)

실제로 해당 취약점을 이용한 exploit code를 만들어보자면 다음과 같다.

//echo -a $encode(Giving us power from the Zod $+ $crlf $+ nick Zod^exploit $+ $crlf $+ quit :Remember my memories with you to stay your soul in my shadow…,m)

위와같이 실행하면 아래와 같은 출력 결과를 얻는다.

R2l2aW5nIHVzIHBvd2VyIGZyb20gdGhlIFpvZA0KbmljayBab2ReZXhwbG9pdA0KcXVpdCA6UmVtZW1iZXIgbX
kgbWVtb3JpZXMgd2l0aCB5b3UgdG8gc3RheSB5b3VyIHNvdWwgaW4gbXkgc2hhZG93Li4u

이것을 다시 decode 해보면 다음과 같은 exploit code가 된다.



//echo -a $decode(R2l2aW5nIHVzIHBvd2VyIGZyb20gdGhlIFpvZA0KbmljayBab2ReZXhwbG9pdA0KcXVpdCA
6UmVtZW1iZXIgbXkgbWVtb3JpZXMgd2l0aCB5b3UgdG8gc3RheSB5b3VyIHNvdWwgaW4gbXkgc2hhZG93Li4u,m)

이걸 Zod에게 실행시키면 다음과 같은 사태가 벌어져버린다. -_-;;



원리는 간단하다.
//msg 식으로 실행을 시키면 이 구문을 스크립트형식으로 받아들이는데
msg (string1 | string2 | string3) 으로 괄호안의 메시지를 메시지를 보내는게 아니라.
강제로 $crlf (carriage return line feed)를 삽입함으로써 스크립트의 취급을 다음과 같이 하도록 만든다.

msg (string1) | string2 | string3

즉 msg 로는 string1만 메시지로 출력하게 되고 string2,3은 명령어로 취급이 되는것이다.

이 취약점으로 사용할수 있는 명령어는 다음과 같다.

/AWAY [message] (현재 상태를 부재중으로 변환한다.)
/INVITE nickname #channel (지정한 채널에 지정한 사용자를 초대한다.)
/JOIN #channel (지정한 채널로 조인한다.)
/LIST [#channel] [-MIN #] [-MAX #] /ME message
/MSG nickname message (누군가에게 메시지를 출력한다.)
/NICK nickname (닉을 바꾼다.)
/NOTICE nickname message (누군가에게 notice를 보낸다.)
/PART #channel (해당 채널을 나간다.)
/QUERY nickname message (누군가에게 쿼리를 보낸다.)
/QUIT [message] (IRC 서버에서 나간다.)
/TOPIC #channel newtopic (토픽을 바꾼다.)
/WHOIS nickname
/KICK #channel nickname (지정한 채널에 접속해있는 지정한 사용자를 킥한다.)
/MODE #channel|nickname [[+|-]modechars [parameters]] (채널 모드를 바꾼다. 밴, 옵 등등..)

Basic IRC Command이지만 대부분의 명령어가 악용되면 치명적이다.

해결책 :
결과를 출력하기 전에 이 구문을 추가한다.

var %k 1
while (%k <= $len(%decoded)) {
var %dcheck $mid(%decoded,%k,1)
if ($crlf isin %dcheck || $chr(10) isin %dcheck || $chr(11) isin %dcheck || $chr(12) isin %dcheck || $chr(13) isin %dcheck) { msg %dchan 올바르지 않은 형식이거나 잘못된 문자열이 포함되어 있습니다. | halt }
inc %k
}

디데이(D-Day) 스크립트

Inkbot에 있던 d-day 기능을 보고 MSL로 비스꾸무레 하게 converting 해본 스크립트..
윤년까지 계산하여 처리하도록 설계하였다.
단, 윤년인 경우 2월 29일의 입력은 불가능하다.
; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:*:#: {
if ($1 == @디데이 || $1 == -디데이) {
if (!$2) { msg $chan “@디데이 YYYY년MM월DD일”와 같은 형식으로 입력하셔야 합니다. (ex : $rand($asctime(yyyy),9999) $+ 년 $+ $rand(1,12) $+ 월 $+ $rand(1,30) $+ 일) | halt }
var %pyear = $asctime(yyyy), %pmonth = $asctime(mm), %pday = $asctime(dd), %iyear = $mid($2,1,4), %imonth = $mid($2,7,2), %iday = $mid($2,11,2)
var %falsey 0
if ($3 == 과거) {
if (%iyear > $asctime(yyyy)) {
msg $chan 디데이가 현재년도보다 크면 안됩니다. (ex : $rand(1000,$asctime(yyyy)) $+ 년 $+ $rand(1,12) $+ 월 $+ $rand(1,30) $+ 일) | halt }
else {
var %prevmode 1 | goto prev
}
}
if (%pyear > %iyear) { msg $chan 디데이가 현재년도보다 작으면 안됩니다. (ex : $rand($asctime(yyyy),9999) $+ 년 $+ $rand(1,12) $+ 월 $+ $rand(1,30) $+ 일) | halt }
var %prevmode 2
goto prev
:prev
if (%pyear == %iyear) {
if (%pmonth == %imonth) {
if (%pday == %iday) {
msg $chan 입력하신날짜( $+ %iyear $+ 년 %imonth $+ 월 %iday $+ 일 $+ )는 오늘입니다.
halt
}
}
}
if ($len($2) != 14) {
var %pyear = $asctime(yyyy), %pmonth = $asctime(mm), %pday = $asctime(dd), %iyear = $rand($asctime(yyyy),9999), %imonth = $rand(1,12), %iday = $rand(1,30)
var %falsey 1
}
if ((%imonth == 1) || (%imonth == 3) || (%imonth == 5) || (%imonth == 7) || (%imonth == 8) || (%imonth == 10) || (%imonth == 12)) {
if (%iday > 31) {
msg $chan 31일 이상 초과하시면 안됩니다. | halt }
else { var %resign 31 }
}
if ((%imonth == 4) || (%imonth == 6) || (%imonth == 9) || (%imonth == 11)) {
if (%iday > 30) { msg $chan 30일 이상 초과하시면 안됩니다. | halt }
else { var %resign 30 }
}
if (%imonth == 2) {
if (%iday > 28) { msg $chan 28일 이상 초과하시면 안됩니다. | halt }
else { var %resign 28 }
}
if (%prevmode == 1) {
var %result1 $calc((%pyear – %iyear) * 365), %result2 $calc((%pmonth – %imonth) * %resign), %result3 $calc(%pday – %iday), %result $calc(%result1 + %result2 + %result3)
if ($calc(%pyear – %iyear) > 4) { var %result $calc(%result + $int($calc((%pyear – %iyear)/4))) }
if (%falsey == 0) {
msg $chan %iyear $+ 년 %imonth $+ 월 %iday $+ 일 $+ 부터 현재까지는 D- $+ %result $+ 일의 차이가 있습니다.
halt
}
if (%falsey == 1) {
msg $chan 입력하신 값이 올바르지 않습니다.
}
}
if (%prevmode == 2) {
var %result1 $calc((%iyear – %pyear) * 365), %result2 $calc((%imonth – %pmonth) * %resign), %result3 $calc(%iday – %pday), %result $calc(%result1 + %result2 + %result3)
if ($calc(%iyear – %pyear) > 4) { var %result $calc(%result + $int($calc((%iyear – %pyear)/4))) }
if (%falsey == 0) {
msg $chan %iyear $+ 년 %imonth $+ 월 %iday $+ 일 $+ 까지는 앞으로 D- $+ %result $+ 일 남았습니다.
halt
}
if (%falsey == 1) {
msg $chan 입력하신 값이 올바르지 않아 임의의 값을 선정하였습니다. ( $+ %iyear $+ 년 %imonth $+ 월 %iday $+ 일 $+ )
msg $chan $2 $+ 까지는 앞으로 D- $+ %result $+ 일 남았습니다.
halt
}
}
}
}앞으로 얼마간 더 스크립트를 제작할지 모르겠다는.
차후부터는 C Programming으로 배을 옮겨 탈까 생각 중…

왜냐면 MSL은 너무 제약이 많으니까.

작동 예제
[11:50:05] <@Xeriars> @디데이
[11:50:05] <@Zod> “@디데이 YYYY년MM월DD일”와 같은 형식으로 입력하셔야 합니다. (ex : 8652년8월28일)
[11:50:36] <@Xeriars> @디데이 2007년09월22일
[11:50:36] <@Zod> 2007년 09월 22일까지는 앞으로 D-85일 남았습니다.
[11:50:54] <@Xeriars> @디데이 1985년09월22일 과거
[11:50:54] <@Zod> 1985년 09월 22일부터 현재까지는 D-7950일의 차이가 있습니다.

1985년 09월 22일은 내 생년월일…

mIRC용 DLL Support

DLL Support

The /dll and $dll() features allow you to make calls to DLLs designed to work with mIRC. The main reason you’d want to do this is that processing information in a DLL can be far faster than doing so in a script, so for intensive data processing a DLL would be more efficient.

Note that mIRC also supports calling COM objects, for calling non-standard DLLs.

Warning: do not use DLLs from sources you do not trust. See the Accepting Files section for information on the dangers of accepting and using files from the internet.

/dll <filename> <procname> [data] $dll(filename, procname, data)

$dllcall(filename, alias, procname, data)

The above open a DLL, call the procname routine, and send it the specified data. The only difference is that $dll() can return a value, like all other identifiers.

$dllcall() is multi-threaded so it will not halt the script and will call the specified alias once the call returns.

Technical notes
This section contains technical information for programmers who want to create DLLs for use with mIRC.

The routine in the DLL being called must be of the form:

int __stdcall procname(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)

mWnd is the handle to the main mIRC window.

aWnd is the handle of the window in which the command is being issued, this might not be the currently active window if the command is being called by a remote script.

data is the information that you wish to send to the DLL. On return, the DLL can fill this variable with the command it wants mIRC to perform if any.

parms is filled by the DLL on return with parameters that it wants mIRC to use when performing the command that it returns in the data variable.

Note: The data and parms variables can each hold 900 chars maximum.

show is FALSE if the . prefix was specified to make the command quiet, or TRUE otherwise.

nopause is TRUE if mIRC is in a critical routine and the DLL must not do anything that pauses processing in mIRC, eg. the DLL should not pop up a dialog.

The DLL can return an integer to indicate what it wants mIRC to do:

0 means that mIRC should /halt processing

1 means that mIRC should continue processing

2 means that it has filled the data variable with a command which it wants mIRC to perform, and has filled parms with the parameters to use, if any, when performing the command.

3 means that the DLL has filled the data variable with the result that $dll() as an identifier should return.

Note: You may need to create a .def file with the procedure names exported when compiling your DLL.

Keeping a DLL Loaded after a call
By default a DLL is unloaded immediately after you make the /dll or $dll() call. You can keep a DLL loaded by including a LoadDll() routine in your DLL, which mIRC calls the first time you load the DLL:

void __stdcall (*LoadDll)(LOADINFO*);

typedef struct {
DWORD  mVersion;
HWND   mHwnd;
BOOL   mKeep;
} LOADINFO;

mVersion contains the mIRC version number in the low and high words.

mHwnd contains the window handle to the main mIRC window.

mKeep is set to TRUE by default, indicating that mIRC will keep the DLL loaded after the call. You can set mKeep to FALSE to make mIRC unload the DLL after the call (which is how previous mIRCs worked).

Unloading a DLL
You can unload a loaded DLL by using the -u switch:

/dll -u <filename>

You can browse the list of loaded DLLs by using:

$dll(N/filename)   returns the Nth loaded DLL

mIRC will automatically unload a DLL if it is not used for ten minutes, or when mIRC exits.

You can also define an UnloadDll() routine in your DLL which mIRC will call when unloading a DLL to allow it to clean up.

int __stdcall (*UnloadDll)(int mTimeout);

The mTimeout value can be:

0   UnloadDll() is being called due to a DLL being unloaded when mIRC exits, or unloaded with /dll -u.

1   UnloadDll() is being called due to a DLL not being used for ten minutes. The UnloadDll() routine can return 0 to keep the DLL loaded, or 1 to allow it to be unloaded.

엉터리 단어 스크립트

; ————————————————————–
; | Coded by PSG-01 (Perl)                                                       |
; | Converted by Xeriars (MSL)                                                  |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)     |
; ————————————————————–

on *:text:*:#: {
if ($1 == @엉터리단어) {
if (!$2) { msg $chan Usage : @엉터리단어 단어명(영어만) | halt }
unset %jscript.*
set %jscript.chan $chan
set %jscript.word $2
set %jscript.error1 Your acronym must be composed only of letters. Call it a Y2K bug.
set %jscript.error2 Your acronym must have between 2 and 6 letters. Sorry about that, but TANSTAAFL.
sockclose junkword
sockopen junkword brunching.com 80
}
}
on *:sockopen:junkword*: {
sockwrite -nt $sockname GET /cgi/toy-acronymer.cgi?acronym= $+ %jscript.word HTTP/1.1
sockwrite -nt $sockname User-Agent: Kagebot Web Client
sockwrite -nt $sockname Host: brunching.com
sockwrite -nt $sockname Connection: Close
sockwrite -nt $sockname $crlf
}
on *:sockread:junkword: {
sockread %tmp
if (%jscript.temp == 1) {
set %jscript.result %tmp
unset %jscript.temp
if (%jscript.error1 == %jscript.result) { msg %jscript.chan Y2K 버그를 일으키고 싶지 않거든, 영어로만 입력하세요. | halt }
if (%jscript.error2 == %jscript.result) { msg %jscript.chan 단어는 2~6글자만 가능합니다. 다시 시도해주세요. | halt }
msg %jscript.chan $head %jscript.word : $+ %jscript.result
halt
}
if (<P><BIG><B> isin %tmp) {
set %jscript.temp 1
}
}

사용 예제 및 결과
[13:37:56] <@[Kage]> @엉터리단어 Kage
[13:37:57] <@[Kagebot^MKII]> KageBot – Kage : Kilo-Asymmetric Gateway Equipment

사실 예전에 만든건데.. 요즘 블로그가 썰렁해서.
한달전쯤인가 참진에 올렸던걸 고대로 올려주는 센스..;

원래 코딩은 푸성귀님이 펄로 하셨고. 그걸 다시 MSL로 컨버팅한것.

진수변환 스크립트

“디지털 공학” 이란 과목을 듣는중
교수가 진수변환을 해오라는 무지막지한 숙제를 내준 관계로 (다합치면 백문제넘으려나)
귀찮아서 만들어버린 스크립트

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

alias dec2bqox {
if ($exists(div_tmp.txt)) { remove div_tmp.txt }
if (!$1) {
return 변환할숫자와 진법을 입력하여 주십시요. (ex : $chr(36) $+ dec2bqo(100,bin))
halt
}
if ($1 !isnum) {
return $1 $+ 은(는) 올바른 숫자가 아닙니다. 다시 확인하여 주십시요.
halt
}
if (!$2) {
return 몇진법으로 환산하실것인지 입력하여 주십시요.
halt
}
if ($1 > 100000000000000000000) {
return 숫자가 너무 큽니다. 다시 입력하여 주십시요.
halt
}
if ($2 == bin) { goto narycalc } | if ($2 == qua) { goto narycalc } | if ($2 == oct) { goto narycalc } | if ($2 == hex) { goto narycalc }
else {
return $2 $+ 은(는) 변환할수 없는 진법입니다.
return bin : 2진수, qua : 4진수, oct : 8진수, hex : 16진수 (ex : $chr(36) $+ dec2bqo(100,bin))
halt
}
:narycalc
var %i 0
var %divider $1
var %nary = $replace($2,bin,2,qua,4,oct,8,hex,16)
:div
write div_tmp.txt $calc(%divider % %nary)
if (%divider > 1) {
var %divider = $int($calc(%divider / %nary))
inc %i
goto div
}
var %q 0
while (%q < $lines(div_tmp.txt)) {
if (%nary == 16) {
var %div_result = %div_result $+ $replace($read(div_tmp.txt,%q),10,A,11,B,12,C,13,D,14,E,15,F)
}
if (%nary != 16) {
var %div_result = %div_result $+ $read(div_tmp.txt,%q)
}
inc %q
}
remove div_tmp.txt
return $reverse(%div_result,%div_result)
}
alias 숙제 {
var %i 00
var %amount 150
var %num $rand(1000,9999)
while (%i < %amount) {
inc %i
write con_result.txt %i $+ $chr(46) %num
write con_result.txt 2진수 : $dec2bqox(%num,bin)
write con_result.txt 4진수 : $dec2bqox(%num,qua)
write con_result.txt 8진수 : $dec2bqox(%num,oct)
write con_result.txt 16진수 : $dec2bqox(%num,hex)
write con_result.txt $crlf
var %num $rand(1000,9999)
}
}

결과는 다음과 같이 con_result.txt로 저장.

1. 4492
2진수 : 1000110001100
4진수 : 1012030
8진수 : 10614
16진수 : 118C

2. 4954
2진수 : 1001101011010
4진수 : 1031122
8진수 : 11532
16진수 : 135A

3. 2697
2진수 : 101010001001
4진수 : 0222021
8진수 : 05211
16진수 : 0A89

냠냠.. 귀찮~
위 함수로 살짝 건드려서 만든.. @진수변환 스크립트

; ————————————————————
; | Made by Xeriars                                                               |
; | (변경해서 쓰는건 니맘대로지만 이 부분은 지우지 말아주세요.)  |
; ————————————————————

on *:text:*:#: {
if ($1 == @진수변환) {
if (!$2) { msg $chan Usage : @진수변환 변환할진수. (10진수만 가능) | halt }
if ($2 !isnum) { msg $chan 올바른 숫자가 아닙니다. 숫자로만 입력하십시오. | halt }
msg $chan 2진수 : $dec2bqox($2,bin)
msg $chan 4진수 : $dec2bqox($2,qua)
msg $chan 8진수 : $dec2bqox($2,oct)
msg $chan 16진수 : $dec2bqox($2,hex)
halt
}
}