터치앤웹http://www.nbass.netasp, 웹2.0, 웹표준, 웹접근성, 웹개발, 웹디자인kodatetime 에 맞는 표현법http://www.nbass.net/5th/doc/blog/?nox=22<blockquote><xmp>now_dt = date & " " & datepart("h",time) & ":" & datepart("n",time) & ":" & datepart("s",time)</xmp></blockquote><br />Sun, 21 Dec 2008 05:25:00 +09002개발자 좀 살려주세요!http://www.nbass.net/5th/doc/blog/?nox=21<h3>● 개발자 좀 살려주세요, 제발!</h3><br /> <p><a href="http://resistan.com/savethedeveloper/">http://resistan.com/savethedeveloper/</a> 에서 제공하는 재미있는 캠페인입니다. 점유율이 70% 수준으로 떨어졌다고는 하지만, 아직도 국내에서 압도적인 점유율을 보이고 있는 IE 6.0 은 사실상 없어져도 벌써 없어졌어야 할, 개발자의 주적 중 하나입니다. 수많은 버그와 비표준 렌더링, 그로 인해 소비되는 무수한 추가개발기간은 돈으로 환산하기 힘들 정도입니다.</p><br /> <p>꼭 남 좋으라고 하는 일만은 아닙니다. 사용해보시면 알겠지만, 6.0보다 편한 브라우저들입니다.^_^</p><br /> <div class="center"> <!-- SAVE THE DEVELOPERS --> <a href="http://resistan.com/savethedeveloper/" style="display:block; display:inline-block; position:relative; white-space:nowrap; width:auto; margin:5px 0; padding:7px; border:1px solid #ccc; line-height:normal; text-decoration:none; background:#FFF;"> <span style="display:block; font:18px/18px Arial; color:#000; margin:0; padding:0; letter-spacing:-1px">SAVE THE DEVELOPERS <span style="position:absolute; cursor:pointer; display:block; top:0; right:5px; font:40px/40px 'Arial Black'; color:#000; opacity:0.25; filter:alpha(opacity=25);"><<span style="font:40px/40px 'Arial Black'; color:#F00">!</span>></span></span> <span style="display:block; font:10px/10px Verdana; color:#F00; margin:0; padding:0; letter-spacing:2px">Upgrade IE 6 Now!</span> </a> <!-- /SAVE THE DEVELOPERS --></div><br />Thu, 4 Dec 2008 11:18:00 +09001base64 인코딩, 유니코드인코딩http://www.nbass.net/5th/doc/blog/?nox=20<blockquote><xmp><% Option Explicit Dim sBASE_64_CHARACTERS, sBASE_64_CHARACTERSansi sBASE_64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" sBASE_64_CHARACTERSansi = strUnicode2Ansi(sBASE_64_CHARACTERS) Function strUnicodeLen(asContents) Dim asContents1 : asContents1 ="a" & asContents Dim Len1 : Len1=Len(asContents1) Dim K : K=0 Dim I, Asc1 For I=1 To Len1 Asc1 = asc(mid(asContents1,I,1)) IF Asc1 < 0 Then Asc1 = 65536 + Asc1 IF Asc1 > 255 Then K = K + 2 ELSE K = K + 1 End IF Next strUnicodeLen = K - 1 End Function Function strUnicode2Ansi(asContents) Dim Len1 : Len1 = Len(asContents) Dim I, VarCHAR, VarASC, VarHEX, VarLOW, VarHIGH strUnicode2Ansi = "" For I = 1 to Len1 VarCHAR = Mid(asContents,I,1) VarASC = Asc(VarCHAR) IF VarASC < 0 Then VarASC = VarASC + 65536 IF VarASC > 255 Then VarHEX = Hex(VarASC) VarLOW = Left(VarHEX,2) VarHIGH = Right(VarHEX,2) strUnicode2Ansi = strUnicode2Ansi & ChrB("&H" & VarLOW ) & ChrB("&H" & VarHIGH ) Else strUnicode2Ansi = strUnicode2Ansi & ChrB(VarASC) End IF Next End Function Function strAnsi2Unicode(asContents) Dim Len1 : Len1 = LenB(asContents) Dim VarCHAR, VarASC, I strAnsi2Unicode = "" IF Len1=0 Then Exit Function For I=1 To Len1 VarCHAR = MidB(asContents,I,1) VarASC = AscB(VarCHAR) IF VarASC > 127 Then strAnsi2Unicode = strAnsi2Unicode & Chr(AscW(MidB(asContents, I+1,1) & VarCHAR)) I = I + 1 Else strAnsi2Unicode = strAnsi2Unicode & Chr(VarASC) End IF Next End function Function Base64encode(asContents) Dim lnPosition Dim lsResult Dim Char1 Dim Char2 Dim Char3 Dim Char4 Dim Byte1 Dim Byte2 Dim Byte3 Dim SaveBits1 Dim SaveBits2 Dim lsGroupBinary Dim lsGroup64 Dim M3, M4, Len1, Len2 Len1 =LenB(asContents) IF Len1 < 1 Then Base64encode = "" Exit Function End IF M3=Len1 Mod 3 IF M3 > 0 Then asContents = asContents & String(3 - M3, ChrB(0)) IF m3 > 0 Then Len1 = Len1 + (3 - M3) Len2 = Len1 - 3 Else Len2 = Len1 End IF lsResult = "" For lnPosition = 1 To Len2 Step 3 lsGroup64 = "" lsGroupBinary = MidB(asContents, lnPosition, 3) Byte1 = AscB(MidB(lsGroupBinary, 1, 1)) : SaveBits1 = Byte1 And 3 Byte2 = AscB(MidB(lsGroupBinary, 2, 1)) : SaveBits2 = Byte2 And 15 Byte3 = AscB(MidB(lsGroupBinary, 3, 1)) Char1 = MidB(sBASE_64_CHARACTERSansi, ((Byte1 And 252) \ 4) + 1, 1) Char2 = MidB(sBASE_64_CHARACTERSansi, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1) Char3 = MidB(sBASE_64_CHARACTERSansi, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1) Char4 = MidB(sBASE_64_CHARACTERSansi, (Byte3 And 63) + 1, 1) lsGroup64 = Char1 & Char2 & Char3 & Char4 lsResult = lsResult & lsGroup64 Next IF M3 > 0 Then lsGroup64 = "" lsGroupBinary = MidB(asContents, Len2 + 1, 3) Byte1 = AscB(MidB(lsGroupBinary, 1, 1)) : SaveBits1 = Byte1 And 3 Byte2 = AscB(MidB(lsGroupBinary, 2, 1)) : SaveBits2 = Byte2 And 15 Byte3 = AscB(MidB(lsGroupBinary, 3, 1)) Char1 = MidB(sBASE_64_CHARACTERSansi, ((Byte1 And 252) \ 4) + 1, 1) Char2 = MidB(sBASE_64_CHARACTERSansi, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1) Char3 = MidB(sBASE_64_CHARACTERSansi, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1) IF M3=1 Then lsGroup64 = Char1 & Char2 & ChrB(61) & ChrB(61) Else lsGroup64 = Char1 & Char2 & Char3 & ChrB(61) End IF lsResult = lsResult & lsGroup64 End IF Base64encode = lsResult End Function %></xmp></blockquote><br /> <p>그리고 사용방법.</p><br /> <blockquote><xmp><% user_id = strAnsi2Unicode(Base64encode(strUnicode2Ansi(user_id))) %></xmp></blockquote><br />Tue, 2 Dec 2008 04:58:00 +09002개발자와의 협업을 위한 올바른 코딩-1http://www.nbass.net/5th/doc/blog/?nox=19<p>퍼블리셔(코더)는 지금까지 국내 웹계에서 전문직종으로 인정받지 못해왔습니다. 제대로 된 코딩을 하려면 많은 지식을 요구함에도 불구하고 많은 에이전시에서는 그 필요성을 느끼지 못해, 혹은 개발비용을 줄이기 위해 퍼블리싱(코딩) 작업을 디자이너, 혹은 개발자에게 맡겨 온 것이 사실입니다.</p><br /> <p>다행히 최근들어 w3c 의 웹 표준 권고안이 국내 웹계의 핫 이슈가 되고, DOM, AJAX, JQuery 등 개발과 퍼블리싱의 중간단계쯤 될 법한 자바스크립트 스킬이 일반적으로 전파되며 전문 퍼블리셔의 수요가 늘어났으며, 전문 퍼블리셔의 숫자도 함께 증가세를 보이고 있다 생각됩니다.</p><br /> <p>하지만 아직도 대다수의 기업과 영세 에이전시에서는 전문 퍼블리셔를 고용하지 못하고 있어 안타깝게도 이 땅의 디자이너들은 쉴 틈이 없습니다. 또 비전문가의 잘못된 코딩(꼭 웹표준을 준수하지 않은 경우만을 말하는 것은 아닙니다!)은 개발자와의 충돌을 야기하기도 합니다. 클라이언트의 (혹은 상사의) 리퀘스트를 이행하기 위해서 필수적으로 거쳐야 할 퍼블리싱, 마크업이 제대로 이루어지지 않고서는 개발이 붙을 수 없기 때문입니다.</p><br /> <h3>올바르지 못한 코딩의 개발상 문제점</h3><br /> <h4>문서의 의미전달이 힘들다. (웹표준 권고안을 준수하지 않은 경우)</h4> <p>PC의 웹브라우저를 통한 일반적인 접속에서는 문제가 되지 않습니다. (시각장애인의 접속은 물론 예외입니다) 하지만 PC 외 플랫폼 - 핸드폰, PDA, 그 외 수많은 멀티미디어 단말기 - 에서 원활한 접속이 불가능할 수 있고, 검색엔진의 크롤링을 방해할 수 있습니다. 기계나 프로그램은 독립적으로 컨텐츠를 이해하지 못합니다. 인공지능의 영원한 한계이자 숙제가 아닐까 합니다. (인공지능의 '이해'를 돕기 위해 우리는 html 이라는 약속을 사용합니다.)</p><br /> <p>또 선형화된 데이터를 추출할 수 없는 페이지의 경우 RSS, trackback 등의 편의성 기능을 개발하는 것이 사실상 힘들어집니다.</p><br /> <h4>문제발생에 유연하지 못하다 (구조가 확연히 드러나지 못한 코딩의 경우)</h4> <p>최근 프리랜서로 작업한 페이지의 일부입니다.</p> <blockquote><xmp><tr> <td><table width="759" border="0" cellspacing="0" cellpadding="0"><tr><td width="39" height="1" rowspan="4">&nbsp;</td></tr> <tr><td><table width="705" border="0" cellpadding="0" cellspacing="0"><tr><td height="10" bgcolor="A6A6A6"></td></tr> <tr><td align="center" valign="top" bgcolor="A6A6A6"><table width="98%"border="0" cellspacing="0" cellpadding="0"> <tr><td width="110" align="center" valign="middle">텍스트필드1<input name="textfield5" type="text" class="input_box2" id="textfield5" size="10" maxlength="4" /></td> <td width="10">&nbsp;</td><td rowspan="2"><textarea name="textarea" cols="75" rows="2"></textarea></td><td rowspan="2"><a href="#"><img src="img/board/bu_re.gif" width="74" height="38" border="0"></a></td></tr> <tr><td align="center" valign="middle">텍스트필드2<input name="textfield5" type="text" class="input_box2" id="textfield5" size="10" maxlength="4" /></td><td>&nbsp;</td></tr></table></td></tr> <tr><td height="10" bgcolor="A6A6A6"></td></tr></table></td></tr><tr><td>&nbsp;</td></tr></xmp></blockquote><br /> <p>이 페이지의 문제점은 비단 테이블로 레이아웃을 구성했다는 것 뿐은 아닙니다. <span class="red">제가 이 포스트를 통해 말하고 싶은 바는 웹표준의 중요성이 아닙니다.</span> 위의 코드가 대체 어느 부분에 붙어 있는 것인지, 어느 부분을 고쳐야 내가 원하는 장소를 수정할 수 있을지 이해하기 힘듭니다.</p><br /> <p>위 소스상에서 작업하다 만약 페이지의 디자인이 깨져나가거나 하게 되면 어떻게 될까요? 멀쩡한 테이블이 옆으로 붙어버린다면? tr 이나 td 등의 구문이 실수로 한개 빠져버린다면? 아 ... 그 후의 노가다는 생각도 하기 싫어집니다. 갑자기 환통이 느껴지네요.ㅡㅡ;</p><br /> <p>개발자들은 드림위버 등의 위지윅 에디터로 작업하지 않습니다. (물론 개인차가 있습니다) EditPlus, Notepad++, Eclipse 등의 텍스트 에디터를 사용합니다. 위같은 코드로는 개발은 커녕, 단순한 loop 도 돌리기 힘듭니다. 개발자에게 주는 페이지라면 최소한,</p><br /> <blockquote><xmp><tr> <td><table width="759" border="0" cellspacing="0" cellpadding="0"><tr><td width="39" height="1" rowspan="4">&nbsp;</td></tr> <tr><td><table width="705" border="0" cellpadding="0" cellspacing="0"><tr><td height="10" bgcolor="A6A6A6"></td></tr> <tr><td align="center" valign="top" bgcolor="A6A6A6"> <!-- 인풋 table, 루프 시작 --> <table width="98%"border="0" cellspacing="0" cellpadding="0"> <tr><td width="110" align="center" valign="middle">텍스트필드1<input name="textfield5" type="text" class="input_box2" id="textfield5" size="10" maxlength="4" /></td> <td width="10">&nbsp;</td><td rowspan="2"><textarea name="textarea" cols="75" rows="2"></textarea></td><td rowspan="2"><a href="#"><img src="img/board/bu_re.gif" width="74" height="38" border="0"></a></td></tr> <tr><td align="center" valign="middle">텍스트필드2<input name="textfield5" type="text" class="input_box2" id="textfield5" size="10" maxlength="4" /></td><td>&nbsp;</td></tr></table> <!-- 인풋 table, 루프 끝 --> </td></tr> <tr><td height="10" bgcolor="A6A6A6"></td></tr></table></td></tr><tr><td>&nbsp;</td></tr></xmp></blockquote><br /> <p>이 정도로는 정돈해야 하지 않나 소심하게 주장해 봅니다. 물론 이것은 어느 정도 개발이 돌아가는 원리를 이해하지 않으면 짜기 힘든 코딩입니다. '디자이너가 할 일이 얼마나 많은데, 이런 부분까지 신경쓸 수 있겠냐' 고 말씀하시는 분들도 계시리라 생각합니다. 그것도 물론 맞는 말입니다. 다만 이 글은 '올바는 웹을 구성하는 것을 목표로 했을 때' 를 전제로 하고 있습니다. 위 전에 하에서는 개발자 역시 올바른 디자인, 올바른 퍼블리싱을 이해해야 합니다. 많은 공부가 필요한 것은 서로 마찬가지입니다. 그렇다 해도 제가 바라는 것이 너무 많은가요? ^^</p><br /> <h4>업무진행에 오랜 시간이 소요된다 (미리 약속되지 않은 엘리먼트명을 사용하거나, 충분히 사전협의되지 못한 경우)</h4> <blockquote><xmp><div id="div4" class="add e4 self opinion"></div></xmp></blockquote><br /> <p>위 div 는 무엇을 의미하고 있을까요? 이름만 봐서는 대체 무엇을 의미하는지 알기 힘듭니다. 개발자가 이걸 알아서 뭐하냐고 생각되지만.. 실제 개발에서는 알아야 할 때가 많습니다. css 속성은 위치를 위한 것과 속성을 위한 것으로 나눌 수 있습니다. (물론 제 맘대로의 분류법입니다) 속성을 위한 분류법이라면 특정 구문을 강조하거나 (font-weight:bold;) 할 때 필요하고, 위치를 위한 것은 주로 db를 통해 얻어온 값을 float 등의 속성을 이용해 강제적으로 고정시키는 것 등, 개발자가 페이지를 이해하는 것이 중요한 이유는 수도 없이 많습니다.</p><br /> <p>또 예를 들어볼까요? 보여지는 위치는 분명 위에 있는데, 코드는 맨 아래 있을 때가 있습니다. position:absolute; top:0; 등의 속성을 사용했을 때 이러합니다. 이러한 속성은 레이아웃에 해당하기 때문에 가급적 id 에 주는 것이 맞다고 생각합니다. 만약 위 클래스 중 add, e4, self, opinion 중 하나에 position:absolute 가 들어있다면? ctrl + f 신공을 펼칠 수밖에 없는 개발자의 마음을 누가 알아줄까요. 제가 생각하는 바람직한 방법은 아래와 같습니다.</p><br /> <blockquote><xmp><div id="opinion" class="bold h4 underline"></div> <!-- /inc/css.css 의 opinion 주석에 포함되어 있습니다. --></div></xmp></blockquote><br /> <p>우선 주석을 달아 어느 페이지를 참조하면 해당 속성을 알 수 있을지 정리되어 있습니다. 또 id 명에 의미가 부여되어 기억하기 쉽고 이해하기 쉬워집니다. 또 속성을 위한 class 들의 이름이 bold, h4, underline 등 익숙한 이름으로 사용되어 해당 div 의 속성이 어떤 값을 가지는지 예상할 수 있습니다. 맨날 이런 페이지만 작업할 수 있으면 정말 원이 없겠네요.</p><br /> <p>하나 더 볼까요? 이번엔 이미지에 alt 를 주지 않았거나 의미없는 파일명을 사용할 때, 혹은 의미없는 이미지를 css로 처리하지 않았을 때의 문제점입니다.</p><br /> <blockquote><xmp><img src="line.gif" /><img src="black.gif" /><img src="title2.gif" /></img src="div4_a2.jpg" /></xmp></blockquote><br /> <p>뭘 의미하는 문서일까요? 페이지를 브라우저에서 열어보기 전엔 절대 알 수 없습니다. 열어본다 해도 저 중 하나가 올 화이트의 의미없는 이미지라면? 그럼 마우스 오른쪽 버튼을 열심히 찍어봐야겠죠^^; 별 수 있을까 싶네요. 의미없는 이미지거나 배경이미지의 경우 css의 background, padding, margin 속성으로 해결해야만 합니다. 그럼 개발자도 무의미한 클릭 수를 줄일 수 있고, 디자이너는 개발자의 질문공세와 따가운 눈초리를 받지 않아도 됩니다. 서로 수명이 2년씩은 늘어날 것입니다.</p><br /> <blockquote><xmp>올바른 이미지 마크업 예제 <div style="background:black url('line.gif');"><img src="title_nbassnet.gif" alt="엔베이스넷" /></div></xmp></blockquote><br />Sun, 26 Oct 2008 05:00:00 +09007DOM 을 통한 HTML 속성 컨트롤http://www.nbass.net/5th/doc/blog/?nox=18<p>DOM 은 HTML 속성을 컨트롤 하기 위한 아래 세가지의 메서드를 제공합니다.</p><br /> <blockquote><xmp>getAttribute() // HTML 요소의 속성을 리턴 합니다 setAttribute() // HTML 요소의 속성을 설정 합니다 removeAttribute() // HTML 요소의 속성을 제거합니다 <img id="myimage" src="http://www.jasko.co.kr/java_data/0000.gif"> <div id="mylayer" style="width:200px;height:30px;background-color:yellow">이 레이어의 배경색은 노랑색 입니다</div> <script> <!-- function checkSrc() { // myimage 의 src 속성을 리턴합니다 getSrc=document.getElementById("myimage").getAttribute("src") alert(getSrc); } function setSrc() { // myimage 의 src 속성을 변경합니다 document.getElementById("myimage").setAttribute("src","http://www.jasko.co.kr/java_data/0001.gif") } function reMove() { // mylayer 의 style 을 제거합니다 document.getElementById("mylayer").removeAttribute("style") } //--> </script></xmp></blockquote><br /> <p>위의 코드는 myimage 에 대해 src 속성을 리턴, 변경하며, mylayer 의 속성을 제거합니다.<p><br />Tue, 14 Oct 2008 18:44:00 +09001AJAX 와 웹접근성에 대해서.http://www.nbass.net/5th/doc/blog/?nox=17<p>ajax (에이잭스) 에 대해 아시나요? 자바스크립트를 이용, 페이지 리로딩 없이 비동기방식으로 새로운 정보를 얻어오는 것을 말합니다. 구글어스를 생각하시면 쉬울 것 같습니다.</p><br /> <p>90년대, 00초반 개발자분들은 기억하실 것입니다. 아이프레임을 이용해서 변수를 주고받던... 엄밀하게 말씀드리면 이것도 ajax 의 범주에 속한다고 볼 수 있을 것입니다. 자바스크립트를 이용했고, 비동기방식으로 데이터를 얻어와 뿌려주었으니까요. 다만 요새의 ajax 는 더욱 진화된 방식을 사용합니다. 변수를 던져주고 받아올 매개체로 아이프레임이 아닌 XML 을 선택했습니다. 과연 웹의 발전은 이런 기술도 보여주네요.</p><br /> <p>다만 구멍은 있습니다. 우선 자바스크립트 없이는 핵심기술을 포함, 모든 데이터를 정상적으로 불러올 수 없습니다. 심지어 하이퍼링크도 안 걸립니다. 새로운 기술이고 웹2.0 트렌드에 정말 잘 맞기는 하나, 아이러니하게도 동시에 웹 2.0 의 핵심인 웹접근성을 크게 해치고 있는 것입니다.</p><br /> <p>따라서 ajax 페이지의 개발은 동시에 두배의 노력을 요구하게 됩니다. '자바스크립트를 사용할 수 없는 환경에서도 페이지가 돌아가게 하라!' 바로 이것입니다. 말도 안되는 일이야.. 그렇게 생각했지만 친절한 자바스크립트와 웹의 신은 noscript 요소의 사용을 우리에게 허락했습니다. 오 마이 갓! ajax 에게 조명을 비춘 구글에게 저주의 편지라도 보내고 싶은 심정입니다.</p><br /> <p>해서, 만들어봤습니다.</p><br /> <p class="center"><a href="/w3_index.asp">w3 테스트페이지 보기 (현재창에서 열립니다)</a></p><br /> <p>구조는 간단합니다. 우선 앵커는 javascript 로 구현합니다. ajax 함수를 호출해야 하니까요. 동시에 앵커를 포함한 링크텍스트를 자바스크립트의 document.write 로 표현해주고, noscript 요소를 사용해 보통의 쿼리스트링 방식의 링크를 한번 더 써줍니다. 자바스크립트를 사용할 수 없는 사용자를 위함입니다.</p><br /> <blockquote><xmp><script type="text/javascript" language="javascript"> document.write("<li><a href=\"javascript:main_navi(\'<%=cate%>\')\"><%=title%></a></li>"); </script> <noscript> <li><a href="/w3_index.asp?menu=<%=cate%>"><%=title%></a></li> </noscript></xmp></blockquote><br /> <p>이제 마무리는 각 asp (php, jsp) 페이지에서 쿼리스트링을 리퀘스트해서 처리해주는 소스를 짜는 일만 남았습니다. 물론 단점은 존재합니다. 유지보수가 상당히 껄끄러워졌습니다. ajax 좋은 기술이긴 한데, 풀 ajax 사이트는 현실성없는 기획인가 싶습니다.^^;</p><br />Tue, 30 Sep 2008 15:07:00 +09007SHA1 암호화루틴http://www.nbass.net/5th/doc/blog/?nox=14<p>SHA1(Secure Hash Algorithm 1) 는 해쉬 알고리즘의 일종입니다. 복호화방법이 없어 충분히 긴 인풋값만 얻어온다면 절대 안전한 데이터보존이 가능합니다. 물론 다시 원래의 값으로 되돌리는 건 불가능합니다. 대입, 비교용으로 쓰면 좋겠죠.</p><br /> <p>예를 들면 사이트 가입할 때 쓰는 주민등록번호 영 찜찜하실텐데.. 회원가입창에 '저희는 SHA1 알고리즘을 이용하여 주민등록번호를 암호화시키기 때문에, 운영자도 절대 주민번호를 알 수 없습니다. 입력하신 주민번호는 중복가입을 막는 용도로만 사용됩니다' 라고 써 있다면.. 훨씬 사이트에 신뢰가 가지 않을까요 :)</p><br /> <p>개인정보를 악용해서 돈 벌어먹을 수 있는 시대는 이미 간지 오래입니다. 불행하게도 과거에 그런 시절이 있긴 했습니다. 이젠 개발자들 스스로가 (물론 클라이언트와 같이) 각성하고 개인정보를 보호하려는 노력을 해야 한다고 봅니다.</p><br /> <blockquote><xmp> <script language="javascript" type="text/javascript" runat="server"> /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Version 2.1a Copyright Paul Johnston 2000 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */ var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} /* * Perform a simple self-test to see if the VM is working */ function sha1_vm_test() { return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; } /* * Calculate the SHA-1 of an array of big-endian words, and a bit length */ function core_sha1(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (24 - len % 32); x[((len + 64 >> 9) << 4) + 15] = len; var w = Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; for(var j = 0; j < 80; j++) { if(j < 16) w[j] = x[i + j]; else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); e = d; d = c; c = rol(b, 30); b = a; a = t; } a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); e = safe_add(e, olde); } return Array(a, b, c, d, e); } /* * Perform the appropriate triplet combination function for the current * iteration */ function sha1_ft(t, b, c, d) { if(t < 20) return (b & c) | ((~b) & d); if(t < 40) return b ^ c ^ d; if(t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d; } /* * Determine the appropriate additive constant for the current iteration */ function sha1_kt(t) { return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; } /* * Calculate the HMAC-SHA1 of a key and some data */ function core_hmac_sha1(key, data) { var bkey = str2binb(key); if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); return core_sha1(opad.concat(hash), 512 + 160); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * Convert an 8-bit or 16-bit string to an array of big-endian words * In 8-bit function, characters >255 have their hi-byte silently ignored. */ function str2binb(str) { var bin = Array(); var mask = (1 << chrsz) - 1; for(var i = 0; i < str.length * chrsz; i += chrsz) bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); return bin; } /* * Convert an array of big-endian words to a string */ function binb2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; for(var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); return str; } /* * Convert an array of big-endian words to a hex string. */ function binb2hex(binarray) { var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for(var i = 0; i < binarray.length * 4; i++) { str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); } return str; } /* * Convert an array of big-endian words to a base-64 string */ function binb2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for(var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); } } return str; } </script> <% Dim strHexSha, strTmp strTmp = "test encrypt string" strHexSha = hex_sha1(strTmp) Response.Write strHexSha %> </xmp></blockquote><br /> Tue, 23 Sep 2008 14:57:00 +09002웹표준이야기-2http://www.nbass.net/5th/doc/blog/?nox=16<p>오랫만에 가진 술자리, 후배 한놈이 저에게 묻습니다. 선배 웹표준 지켜서 작업하세요? 저는 당당히 말합니다. 그걸 어떻게 지켜?</p><br /> <p>참 아이러니하게도 웹표준은 지킬 수 없는 표준입니다. 모든 브라우저가 모든 권고안을 따르는 것이 아닙니다. 특히 M$ 사의 진리의 6.0 은 새로운 리딩값을 창조해냈나 봅니다. 작업할 때 IE7, FF3, Opera9, safari 3 windows, chrome beta, netscape9.. 이렇게 여섯개의 브라우저를 켜놓고 작업합니다. 컴퓨터가 한 대뿐이라 6.0 의 테스트는 다른 자리에 가서 해야 합니다. 그런데.. 오마이갓, 모든 브라우저에서 사소한 오차범위 내에서 보여주던 화면을 6.0 에선 새롭게 재창조했습니다. 소스가 틀렸나 아무리 살펴보아도 원인을 알기 힘듭니다. CSS와 씨름한지 30분, 드디어 저는 부모 엘리먼트에게서 속성을 물려받은 불효자식놈 때문이라는 사실을 깨닫습니다.ㅡㅡ;</p><br /> <p>자식 엘리먼트에게 새로운 속성을 부여해주어서 문제가 해결되면 참 좋으련만 현실은 그렇게 달콤하지 않습니다. 새로운 속성을 부여해주면서 IE 7 도 정상은 아니라는 사실을 알아냅니다. 또 크롬은 나머지 브라우저들과는 조금 다른 화면을 보여줍니다. 이런, 마지막에 나온 브라우저이자 가장 정확한 리딩을 자랑하는 크롬이 혼자 튀었습니다. 아무래도 크롬혼자 맞고 나머지는 다 틀렸나봅니다. ㅡㅡ;</p><br /> <p>걷잡을 수 없는 사태에 당황해 이런저런 시도를 해봅니다. 가상엘리먼트를 넣어보기도 하고, 의미없는 빈 엘리먼트를 넣어서 픽셀을 맞추어보려고 애도 써봅니다. 그러다 결국 부질없는 짓임을 깨닫습니다. 조용히 ctrl+z 를 누르고, 문제의 엘리먼트에 *float:left; *margin-left:20px; _margin-left:10px; 라고 적어넣어줍니다. 모든 브라우저가 일제히 같은 값을 보여주기 시작합니다. 이번에도 '웹표준 방식으로 작업'은 다 틀렸습니다.</p><br /> <p>이전 글에도 말했듯이 저는 웹표준 방식이라는 말 자체에 오류가 있다고 생각합니다. 웹표준이 무슨 삼국시대 건축기법도 아닌데 방식이란 말이 어울리기나 할까요. 웹표준 준수했다고 자랑할 것도 없고, 웹표준 준수 못했다고 창피해할것도 없습니다. '이 제멋대로인 브라우저간의 싸움을 달래고자 핵을 사용했으나 그래도 최대한 웹표준 준수해줬다' 하고 살짝 거만해주면 될 것 같습니다. 사실 코더들이 무슨 죄겠어요. 다 진작 표준안 결의못한(안한) 브라우저 제작사들이 죽을 죄를 지었죠..</p><br /> <p>저는 웹표준의 중요성을 아주 잘 알고 있습니다. 웹 뿐만 아니라 모든 공산품에는 표준이 필요합니다. 핸드폰 충전기도 표준이 필요하고 TV 송출라인도 표준이 필요합니다. 그것은 업무의 효율성으로 이어지고 더 많은 가능성을 열어줄 수 있는 것임을 잘 알고 있습니다.</p><br /> <p>앞으로 15년만 지나면 웹문서가 모든 매체를 통해 컨버터되어 송출될 것입니다. 휴대용 음악 플레이어에 웹문서를 담아 소리를 들을 수 있을지도 모르고, xsl, css만 갈아끼운 같은 페이지들이 각 매체 (TV, 웹, 핸드폰, 휴대용멀티미디어, 그리고 아직 나오지 않은 미래의 매체들) 를 통해 각기 다른 모습, 같은 내용으로 출판될 것입니다. 그것을 위한 표준안이고, 반드시 그렇게 만들어야만 합니다. 다만 핸드폰과 웹이 다른 점은 웹브라우저의 출시속도, 업그레이드 효율이 극히 낮다는 것입니다. 인터넷 익스플로러 7이 나오고, 8이 베타에 들어갔음에도 여전히 모든 피시방에 6이 깔려 있고, 모든 사무실에서 6을 사용합니다. 아무래도 당분간 _ 와 * 키는 쉬지 못할 것 같습니다.</p><br /> <p>후배의 눈이 둥그래집니다. 선배, 그러면 그 뭐더라, w3c 표준검사에서 에러나잖아요. 그럼 저는 말합니다. 넌 그거 통과하려고 사이트 만드냐?</p><br />Tue, 23 Sep 2008 02:29:00 +09007asp 정규식http://www.nbass.net/5th/doc/blog/?nox=13<blockquote><xmp> Function delLink(str) Dim patrn, regEx, match, matches patrn = "\<(\/?)(script|style|SCRIPT|STYLE)([^<>]*)>" SET regEx = New RegExp ' 정규식을 만듭니다. regEx.Pattern = patrn ' 패턴을 설정합니다. regEx.IgnoreCase = false ' 대/소문자를 구분하지 않도록 합니다. regEx.Global = True ' 전체 문자열을 검색하도록 설정합니다. SET Matches = regEx.Execute(str) For Each Match in Matches ' Matches 컬렉션을 반복합니다. str = regEx.Replace(str, "") Next delLink = str End Function pattern0 = "[^가-힣]" '한글만 pattern1 = "[^-0-9 ]" '숫자만 pattern2 = "[^-a-zA-Z]" '영어만 pattern3 = "[^-가-힣a-zA-Z0-9/ ]" '숫자와 영어 한글만 pattern4 = "<[^>]*>" '태그만 pattern5 = "[^-a-zA-Z0-9/ ]" '영어 숫자만 </xmp></blockquote><br />Mon, 22 Sep 2008 16:36:00 +09002웹표준이야기-1http://www.nbass.net/5th/doc/blog/?nox=12<h4>웹표준? 그게 뭔데 먹는건가?</h4> <p>예나 지금이나 직군을 막론하고 사람 상대하는 게 제일 힘듭니다. (특히 영업으로 시작해서 영업으로 끝나는 웹에이전시에서야 더하면 더했지 덜할 건 없다고 봅니다.-_-) 프리랜서로 일하면서 상당히 자주 업체를 돌아다니게 되는데, 웹표준을 설명하는데 아주 진땀을 빼게 됩니다. 생전 들어본 적도 없고, 관심도 없는 생소한 단어를 접할 때 대표님들의 표정이란 참 복잡 미묘한 것입니다. (아마도 비용을 걱정하시는 것 같습니다.ㅋㅋ)</p><br /> <p>하지만 저는 웹표준을 빙자해서 비용을 올려받는 악덕 개발자가 아닙니다! 오히려 웹표준 방식 - 웹표준 방식이라는 말에는 상당한 어폐가 있지만 일단 표현하자면 - 을 도입하면서 개발기간이 상당히 줄어들어, 비용을 내려 받아도 괜찮을 정도입니다. 사실 굳이 대표님들께 웹표준을 설명드릴 필요조차도 없지요.</p><br /> <p>하지만 클라이언트가 '특이한 기능' 을 원할 때는 얘기가 다릅니다. 웹표준의 테두리 안에서 해결할 수 있는 기능이라면 괜찮지만, 대개는 익스플로러 전용이거나 DTD 선언을 포기해야만(-_-) 사용이 가능한 소스나 자바스크립트인 경우일 때는 어쩔 수 없이 <strong>'웹표준'!</strong> 말하는 저 자신도 더 이상 떠올리기 싫은 그 단어를 입 밖에 꺼낼 수밖에 없는 것입니다.</p><br /> <h4>그래요, 그런데 그거, 하면 뭐가 좋은겁니까?</h4> <p>클라이언트가 관심을 가져주어도 이런 질문을 받는데야 딱히 대답할 말이 사라지는 것이 사실입니다. 클라이언트의 기획을 무너트려가면서 지켜야 할 '무언가'가 있다면, 그것은 분명 중요한 것일 터입니다. 그래서 아마 저는 그 더운 여름날 영등포 어느 낯선 사무실에서 필사적으로 머리를 굴렸던 모양입니다.</p><br /> <p>사실 웹표준을 반드시 지켜야할만한 클라이언트의 사정이란 아무것도 없습니다. 당장 한 건의 오더라도 더 소화해야 하는 국내의 어려운 에이전시 사정 하에서는 안타깝게도 그렇습니다. ㅠㅠ 사용자가 이용만 잘하면 됐지요. 간혹 '웹표준을 지키지 않으면 파폭, 넷케 등에서 사이트가 깨져보이잖아요' 하고 말씀하시는 분들이 있는데, 맞는 말씀이기도 하고 틀린 말씀이기도 합니다. 물론 웹표준을 지키지 않았기 때문에 깨져보이는 것입니다. 다만 웹표준을 지키지 않아도, 깨져보이지 않게 할 수도 있습니다. (참 아이러니하지요)</p><br /> <p>우리나라 웹 업계에 웹표준이라는 단어가 존재하지 않던(존재하지 않는 것처럼 느껴졌던) 10년전, 당시의 디자이너들도 나름의 '크로스 브라우징 작업'을 거쳤었습니다. 비록 border="0" 속성이 부여된 테이블을 빈틈없이 채워넣은 사이트였지만 말입니다. 크로스 브라우징을 잊게 된 것은 Windows XP 의 보급과 거의 동시대라고 여겨집니다. 인터넷 익스플로러 6.0 이 대세가 되면서, 더 이상의 크로스 브라우징은 무의미하다고 판단한 디자이너가 많아졌기 때문입니다. (물론 크로스브라우징에 관심이 없는 디자이너들이 늘어났기 때문이기도 합니다.)</p><br /> <p>웹표준이 무엇입니까? xhtml 표준 권고안입니다. 권고안은 권고안일 뿐 법적 강제력은 없습니다. 장차법 역시 '차별요소가 있을시 문제가 되는 것'일 뿐, '웹표준을 지키지 않으면 안된다'는 개념은 아닙니다. 소송당하는 게 무서우면 최소한의 접근성만 지켜주면 됩니다. 5년 후엔 진짜로 소송당할지도 모른다니까요? 아무리 외쳐보아도 관심없는 사람에게는 공허한 메아리처럼 들립니다. 아무래도 '지키지 않으면 이런 꼴을 당해!' 보다는 '웹표준에는 이러이러한 영역들이 있는데, 각 영역들은 이러이러한 장점이 있으니까 한번 고민해 보시지요' 하는 논리로 다가가야 할 것 같습니다.</p><br />Mon, 15 Sep 2008 10:49:00 +09007