|
개발 2007. 11. 12. 10:54
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-11-09
웹서버와 통신을 할 때 GET 또는 POST method를 사용하여 통신을 하게 됩니다. 파라미터로 어떤 값을 보내야 할 때 한글이나 공백등이 있으면 URL 표현 규칙에 않맞게 되어 서버쪽에서 올바르게 인식을 못하게 됩니다. ‘Good’ 이나 ‘김희선’ 처럼 붙어 있는 단어는 상관이 없지만 ‘김 희선’ ‘boy friend’ 처럼 중간에 공백이 있을때는 서버에서 인식을 못하게 됩니다.
이런 경우에 아래처럼 인코딩을 해서 보내주어야 합니다.
‘boy friend’ => ‘%62%6f%79%20%66%72%69%65%6e%64’
‘김 희선’ => ‘%b1%e8%20%c8%f1%bc%b1’
변환되는 규칙을 살펴보면 빈문자(스페이스)는 %20으로 변환 되는 것을 알 수 있고 ‘b’는 %62로 변환되는 것을 알 수 있습니다. 오~ 이건 바로 해당 문자의 아스키값을 16진수로 표현한 것에 앞에 %를 추가한 것임을 알 수 있습니다. 코드로는 간단하게 sprintf를 사용하여 16진수로 변환을 할 수도 있지만 직접 비트연산을 통해서 변환하는 함수를 만들어 보았습니다.
long TextToUrlString(TCHAR* szText, TCHAR* out, unsigned len)
{
unsigned nSrcLen = lstrlen(szText);
// check output buff
if( nSrcLen*3 >= len) return 0;
int nIdx = 0;
for( int i=0 ; i < nSrcLen ; ++i)
{
out[nIdx++] = '%';
char src = szText[i];
char leftI = src & 0x0f;
char rightI = (src>>4) & 0x0f;
char leftA[2] = {0};
char rightA[2] = {0};
itoa(leftI, leftA, 16);
itoa(rightI, rightA, 16);
out[nIdx++] = rightA[0];
out[nIdx++] = leftA[0];
}
out[nIdx] = 0;
return nIdx;
}
텍스트 문자를 url스트링으로 변환을 했으면 반대로 url스트링을 텍스트로 변환하는 함수도 있어야 겠죠.. 그래서..
long UrlStringToText(TCHAR* szUrlString, TCHAR* out, unsigned len)
{
unsigned nSrcLen = lstrlen(szUrlString);
// check output buff
unsigned nTargetLen = nSrcLen/3;
if( nTargetLen >= len) return 0;
int nSrcIdx = 0;
int nTargetIdx=0;
for( nTargetIdx=0 ; nTargetIdx < nTargetLen ; ++nTargetIdx)
{
//
char ch[3];
ch[0] = szUrlString[nSrcIdx++]; // %
ch[1] = szUrlString[nSrcIdx++]; //
ch[2] = szUrlString[nSrcIdx++]; //
ch[1] = tolower(ch[1]);
ch[2] = tolower(ch[2]);
// 16진수
if( ch[1] > '9' )
ch[1] = ch[1] - 'a' + 10;
else
ch[1] = ch[1] - '0';
if( ch[2] > '9' )
ch[2] = ch[2] - 'a' + 10;
else
ch[2] = ch[2] - '0';
char target = (ch[1]<<4) | ch[2];
out[nTargetIdx] = target;
}
out[nTargetIdx] = 0;
return nTargetIdx;
}
IT활용 2007. 11. 7. 11:46
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-11-07
인터넷을 돌아 다니다가 재미있는 곳을 발견 했습니다. http://web.archive.org 이라는 곳인데, 웹페이지를 년도별로 모아둔 곳입니다. 이곳에서 네이버를 찾아보면 네이버의 예전 모습을 볼 수 있는데요, 예전 모습은 참 단조롭습니다. 지금 개인도 만들수 있을 것 같네요~ ㅎㅎ. 참고로 검색된 결과를보면 화면이 깨지는데, 인코딩을 조절해주면 잘 나옵니다.
<1999년 네이버> - 초창기의 모습입니다. 정말 간단하네요 ^^ 네이버의 상징인 초록색도 안보이구요..
<2000년 네이버> - 색상에서 초록색이 보이기 시작하네요 ^^
<2001년 네이버> - 현재의 모습과 유사한 디자인이네요. 한게임과 합병도 했죠..
<2002년 네이버> 월드컵이 있던해였죠.. 화면이 점점 복잡해 지고, JTL 기사도 보이네요.. ^^
<2005년 네이버> 초록색이 점점 세련되어 지고 있네요~ 현재의 모습과 상당히 비슷하네요.. 그래서 여기까지만..
개발 2007. 11. 5. 14:34
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-11-05
이번에는 CPU가 메모리를 읽는 순서에 대해서 살펴 보도록 하겠습니다. 먼저 엔디언이란 여러 바이트로 되어있는 자료를 하나의 데이터로 간주하여 어떤 바이트 순서로 데이터를 배열 할 것인지를 나타내는 것입니다. 주소가 낮은쪽에 최하위 바이트를 저장하는 방식을 리틀 엔디안(Little-endian) 이라 하고, 반대로 낮은쪽에 최상휘 바이트를 저장하는 방식을 빅 엔디안(Big-endian)이라고 합니다.
이해하기 쉽게 예를 들면, long 타입의(32bit 환경에서 4byte) 데이터를 메모리에 쓴다고 할때
long a = 0x1234;
리틀엔디안 에서는 0x0012FED4 34 12 00 00
빅엔디안 에서는 0x0012FED4 00 00 12 34
위와 같은 구조로 메모리에 저장이 되게 됩니다.
빅엔디안은 우리가 평소에 보던 방식으로 메모리에 쓴다고 생각하면 되구요, 리틀엔디안은 뒤집어 져서 쓴다고 생각하며 됩니다. 그럼 리틀엔디안은 왜 뒤집어서 쓰는 걸까요??
그것은 산술연산유닛(ALU)에서 메모리를 읽는 방식이 메모리 주소가 낮은 쪽에서부터 높은 쪽으로 읽기 때문에 산술 연산의 수행이 더 쉽기 때문이랍니다. (음~ 그렇군~)
우리가 사용하는 인텔(Intel)의 x86 계열의 CPU등은 리틀엔디언 방식의 CPU이구요, Motorola, Sun, Sparc 같은 Risc 타입은 빅엔디안 방식입니다.
빅엔디안 방식의 장점이라면,
정수로 정렬된 수에대한 비교가 메모리에서 읽는 순서대로 바로 비교가 가능
정수와 숫자타입의 데이터를 같은 순서 방향으로 읽을수 있음.
등이 되겠습니다.
보통 IBM 호환 컴퓨터의 Windows 환경을 많이 사용하고 있는데, 이때는 리틀엔디안의 방법으로 사용되고 있습니다. 그런데 네트워크는 네트워크 오더링 이라고 하여서 빅엔디안 방식의 바이트 정렬 방법을 사용하고 있는습니다. 따라서 통신 프로그램을 할 때는 이 바이트 정렬을 맞추어 주어야 합니다. C 함수로 ntohs, htons, ntohl, htonl 등의 함수를 이용하면 리틀엔디안과 빅엔디안 사이의 변환을 수행 할 수 있습니다.
위의 htonl 함수를 호출하기 전/후 메모리를 찍어 보면 아래와 같습니다.
long a = 0x1234;
a = htonl(a);
호출전: 0x0012FED4 34 12 00 00
호출후: 0x0012FED4 00 00 12 34
htonl 과 ntohl 함수는 같은 실제적으로 같은 역할을(바이트 순서 변경) 하는데, 의미상 이름을 host to network, network to host로 해서 제공하고 있습니다.
사회&문화 2007. 11. 1. 16:27
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
네이버의 만화란에 보면 웹툰이 있습니다. 거기 목요웹툰에 보면 ‘수사9단’이라는 만화가 있습니다. 어제 여유시간이 있어서 밀린 만화를 차례차례 보고 있었지요. 2006년 5월부터 쭉~쭉~쭉~ 보다가 2007년 2월쯤에 오니 중간에 이벤트(?)같은 것을 하더군요. 작가는 미궁게임 이라고 이름을 붙였는데, 게임의 방법은 다음과 같습니다.
이곳(http://www.susa9dan.vo.to/ )에서부터 시작하여 목적 페이지까지 도달하는 것인데, 다음 페이지의 url이 퀴즈나 추리로 찾아야 되는 방식입니다. 그래서 다음페이지의 답이라고 생각되는 것을 페이지의 하단에 있는 곳에 써넣으면 되는 것이죠. 처음 몇단계는 아주 쉽습니다. 첫문제의 답이 ‘정보통’인데 만화내용에서는 주로 ‘보통이’라고 나와 처음부터 조금 해매고.. 절반의 답은 수사9단 만화의 내용에서 찾을 수 있습니다. 마지막 단계로 갈수록 어려워 지는데, 검색해보니까 누군가 답을 정리해 놓은 것이 있더군요.
만화를 열심히 읽은 사람은 1~2시간 정도면 마지막까지 도달 할 수 있을 듯 싶습니다. 막판에 어려운 것 몇 개 있긴 하지만요.. 정답을 보고시작하면 너무 재미가 없습니다. 문제의 초반은 쉽게되어 있으니 직접 하나하나 풀어보면 재미있습니다. ‘홍달기’ 반장이 되어 수사를 해나가는 듯이요.. 총단계는 세어보니 12단계입니다. 그리고 문제를 이끄는 스토리도 재미있구요~
아래는 마지막에 도착하면 엔딩을 위한 게시판이 준비되어 있는데, 저는 7593번째로 도착했네요..기념으로 스샷 하나 남겨둡니다.
개발 2007. 10. 29. 12:19
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-10-26
인터넷익스플로러(Internet Explorer, 이하 IE)로 웹서핑을 하다보면 페이지에 스크립트 오류(script error)가 발생시에 오류창이 뜨게 되어 있습니다. 스크립트 오류가 발생하는 경우는 서핑중인 페이지에서 사용한 스크립트의 문제로 페이지 자체의 오류라고 할 수 있습니다. 사소한 오류의 경우에 IE 7.0에서 확인한 결과 오류창이 뜨지 않는데, WebBrowser Control을 사용하여 프로그램에서 해당 페이지를 서핑할 경우에 오류창이 아래와 같이 표시가 되었습니다.
이것은 네이버에서 OpenAPI를 이용하여 CNN 뉴스를 듣게 만든 위젯에서(iCNN) 발생하였는데, ‘아니오’를 누르면 프로그램은 문제없이 실행 되지만 실행할 때 마다 오류메시지가 보이니까 프로그램이 버그를 가지고 있는 것 같아서 수정이 필요하였습니다. (실제적인 원인은 cnn에서 제공하는 스크립트 문제입니다~ ㅋㅋ) 이문제를 해결하기 위해서 검색을 해보니, IE에서 스크립트 오류시에 나오는 메시지 창을 핸들링 할 수 있는 방법이 있었습니다.
(How to handle script errors as a WebBrowser control host)
참고 : http://support.microsoft.com/kb/261003
WebBrowser control에서 에러가 발생하면 컨테이너에서 IOleCommandTarget 인터페이스가 구현되어 있으면 IOleCommandTarget::Exec 메소드를 호출하게 되어 있는데, 이때 nCmdID가 CGID_DocHostCommandHandler로 전달 된다고 합니다. 따라서 구현시에 nCmdID를 체크하여 CGID_DocHostCommandHandler인 경우에 S_OK를 반환해주면 오류창이 않뜬다고 합니다.
그래서 IOleCommandTarget을 아래처럼 가볍게 구현을 해주었습니다. 재사용성을 위해서 템플릿 클래스로 만들었는데, 중요 부분만 발췌하면 아래와 같습니다.
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID __RPC_FAR *pguidCmdGroup, ULONG cCmds, OLECMD __RPC_FAR prgCmds[], OLECMDTEXT __RPC_FAR *pCmdText)
{
T* pT = static_cast<T*>(this);
return m_spDefaultOleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT __RPC_FAR *pvaIn, VARIANT __RPC_FAR *pvaOut)
{
T* pT = static_cast<T*>(this);
BOOL bCmdGroupFound = FALSE;
if (nCmdID == OLECMDID_SHOWSCRIPTERROR)
{
// 요기가 중요
(*pvaOut).vt = VT_BOOL;
(*pvaOut).boolVal = VARIANT_TRUE;
return S_OK;
}
return m_spDefaultOleCommandTarget->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
참고로 이 방법이 동작하기 위해서는 IE의 ‘인터넷 옵션 -> 고급’ 에서 아래그림처럼 ‘스크립트 디버깅 사용안함’에 체크가 되어 있어야 합니다. 기본으로는 이 항목에 체크가 되어 있으니 별 문제가 없는데, 혹시라도 작동이 않된다면 이옵션을 체크해 보아야 합니다.
그리고 검색하면서 IE programming쪽을 조금 보게 되었는데, IE가 생각보다 잘 만들어진 것 같습니다. (사용자 입장이 아닌, 개발자 입장에서) IE도 윈도우의 탐색기(shell)처럼 여러가지 확장가능하도록 다양한 인터페이스를 노출하고 있더군요. IE에서 보여지는 UI를 변경하고 싶을때는 IDocHostShowUI, IDocHostUIHandler 등을 구현해주면 다음과 같은 것들을 할 수 있습니다.
* 마우스 오른쪽 클릭시 뜨는 메뉴를 커스터 마이징 : IDocHostUIHandler::ShowContextMenu
* IE에서 띄우는 메시지 박스 커스터 마이징 : IDocHostShowUI::ShowMessage
위의 두 인터페이스를 구현시 다음을 참고
MFC : http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/samples/internet/browser/driller/default.asp (Driller(MFC))
ATL : http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/samples/internet/browser/atlbrowser/default.asp (ATLBrowser)
그리고 팝업창 띄우는 것을 막으려면 http://www.codeproject.com/atl/popupblocker.asp
IT활용 2007. 10. 26. 14:03
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-10-26
요즘에는 바이러스가 워낙 강력한 것들이 많아서, 한번 잘못 걸리면 컴퓨터를 밀어야 하는 경우도 있습니다. 그래서 사후처리인 치료 기능보다는 사전에 바이러스로부터 예방을 하는 실시간 감시 기능이 좋은 제품을 사용하려고 하는 추세입니다. 소 잃고 외양간 고치기가 싫기 때문이죠..
저자는 백신 프로그램으로 시만텍의 프로그램을 사용하고 있습니다. 딱히 이제품이 성능이 좋다는 말은 아니고, 그냥 어디서 구해져서 사용하고 있습니다~ ㅎㅎ 이제까지 특별히 바이러스에 걸리진 않았구요. 몇달전에 컴퓨터에 이상한 파일이 하나 생겨서 IE를 죽이는 것입니다. 다행이 IE가 죽으면서 오류창에 죽는 모듈의 이름이 나와서 해당 파일을 찾는데, 컴퓨터에서 파일을 찾아도 파일의 위치가 나오질 않는 것입니다. 아니 없는 파일이 실행이 되는것인가? 라는 바보 같은 생각을 하면서 고민을 하다가 Process Explorer 라는 프로그램일 이용하였습니다. 이 프로그램은 실행시에 참조하는 dll 들을 보여주는 프로그램으로 IE를 살펴보니 해당 dll의 위치를 찾을 수가 있었습니다. 인터넷에서 다운받은 임시폴더에( C:\Window\Temp ) 해당 파일이 있었습니다. 그래서 그때 해당 파일을 삭제 하였습니다. 그 파일이 어디서 유입된 것인지 확인도 안했구요. 혹시 트로이 같은 프로그램이었으면, 정보가 유출 되었을 까요?
오늘 인터넷을 돌아다니가 우연히 유익한 곳을 발견하였습니다. 현재 존재하는 다양한 백신 진단프로그램을 사용해서 파일에 유해성을 검새해주는 곳입니다. 현재 대락 33개 정도의 백신을 사용하는 것 같습니다. 우리나라의 Ahnlab-V3도 보이는 군요. 시험삼아서 컴퓨터에 있는 그림파일을 전송해서 테스트를 해보니 아래와 같은 결과를 보여줍니다.
Antivirus |
Version |
Last Update |
Result |
AhnLab-V3 |
2007.10.26.0 |
2007.10.26 |
- |
AntiVir |
7.6.0.27 |
2007.10.25 |
- |
Authentium |
4.93.8 |
2007.10.25 |
- |
Avast |
4.7.1074.0 |
2007.10.25 |
- |
AVG |
7.5.0.503 |
2007.10.25 |
- |
BitDefender |
7.2 |
2007.10.26 |
- |
CAT-QuickHeal |
9.00 |
2007.10.25 |
- |
ClamAV |
0.91.2 |
2007.10.26 |
- |
DrWeb |
4.44.0.09170 |
2007.10.25 |
- |
eSafe |
7.0.15.0 |
2007.10.22 |
- |
eTrust-Vet |
31.2.5241 |
2007.10.25 |
- |
Ewido |
4.0 |
2007.10.25 |
- |
FileAdvisor |
1 |
2007.10.26 |
- |
Fortinet |
3.11.0.0 |
2007.10.19 |
- |
F-Prot |
4.3.2.48 |
2007.10.25 |
- |
F-Secure |
6.70.13030.0 |
2007.10.25 |
- |
Ikarus |
T3.1.1.12 |
2007.10.26 |
- |
Kaspersky |
7.0.0.125 |
2007.10.26 |
- |
McAfee |
5149 |
2007.10.25 |
- |
Microsoft |
1.2908 |
2007.10.26 |
- |
NOD32v2 |
2618 |
2007.10.26 |
- |
Norman |
5.80.02 |
2007.10.25 |
- |
Panda |
9.0.0.4 |
2007.10.26 |
- |
Prevx1 |
V2 |
2007.10.26 |
- |
Rising |
19.46.32.00 |
2007.10.26 |
- |
Sophos |
4.22.0 |
2007.10.26 |
- |
Sunbelt |
2.2.907.0 |
2007.10.26 |
- |
Symantec |
10 |
2007.10.26 |
- |
TheHacker |
6.2.9.107 |
2007.10.25 |
- |
VBA32 |
3.12.2.4 |
2007.10.25 |
- |
VirusBuster |
4.3.26:9 |
2007.10.25 |
- |
Webwasher-Gateway |
6.6.1 |
2007.10.25 |
- |
당연히 바이러스가 있을리가 없지요~ ㅋㅋ 파일단위로 검사를 해서 그렇지 여러가지 백신프로그백신프부터 진단 결과를 받을수 있다니 유용한 곳임에는 틀림없습니다. 더구나 무료입니다. 이것을 진작에 알았더라면 그때 그 파일을 검사해보는 것인데..
참고로 신종 바이러스의 경우에 이곳을 통해서 백신프로그램의 정확한 진단여부를 확인해 볼 수 있을 것 같습니다. 앗! 이곳 주소를 아직까지 말하지 않았네요~ ㅎㅎ
요기요 : http://www.virustotal.com
이름이 바이러스토탈인데, 이름에 잘 맞네요~ ㅎ
개발 2007. 10. 26. 11:19
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저자 : hanburn
날짜 : 2007-10-26
개인적으로 네이버 데스크톱이 귀여운 면이 있어서 야후위젯에서 이쪽으로 건너 왔는데, 드디어 OpenAPI 제공으로 위젯을 제작할 수 있게 되었습니다. 네이버 데스크톱의 위젯을 개발 할 수 있는 interface를 노출 시켜주고 있는데, 한번 살펴 보도록 하겠습니다. 일단 네이버 데스크톱의 위젯 만들기로 가면 자세한 정보를 제공하고 있습니다. (http://desktop.naver.com/openapi/index.nhn) 개발자 가이드, key 발급, 카페, 위젯등록등 여러가지 정보를 제공하고 있습니다.
아래의 그림이 전체적인 개괄도인데요
COM 기반의 인터페이스를 노출하고 있군요..
그리고 문서다운로드에서 위젯 샘플로 mp3 player를 제공하고 있어서 위젯을 만들기에 별 어려움은 없었습니다. 참고로 저는 cnn의 뉴스를 편리하게 들을 수 있는 위젯을 만들었습니다. 이름하여 iCNN위젯~ ㅋㅋ
위젯을 만드는 과정은 잘 설명이 되어 있는데, 한가지 아쉬운 점이라면, 위젯 메이커에서 ‘step5 단계’에서 [위젯 아이콘 등록하기] 과정이 있는데, 여기에서 아이콘 파일을 꼭 png로 만들어야 된다는 것입니다. 헐~ 평소 자주 사용하던 그림판에서 않되더군요.. png 말고 jpg도 사용할수 있게 해주면 좋을 것 같은 아쉬움이 남습니다. 참고로 위젯아이콘 제작에 대한 가이드도 마련되어 있더군요.. (http://desktop.naver.com/openapi/guide/index.nhn?menu=28)
Png 파일을 만들기 위해서 Paint.net이라는 프로그램을 사용하였습니다. 프로그램이 직관적이어서 그림판에 익숙한 사용자라면 10분 정도의 삽질을 통해서 바로 사용할수 있는 프로그램입니다. 삽질을 통해서 png 파일도 만들고 네이버에서 위젯 키도 발급받아서 위젯을 만드는데 완성하였습니다. 짬짬이 만드는데 몇일 걸리더군요..
만든 위젯과 발급 받은 키를 이용해서 위젯 등록하를 하면 1~2주 정도 지나니까 위젯이 등록되었다고 메일이 옵니다. 그래서 가서 확인해보니 제가 만든 위젯이 등록이 되었습니다~ ㅎㅎ 그래서 기념으로 갭쳐링~
오옷~ 벌써 581명이 다운을 받았네요~ 평점은 8.0 이군요~ ㅎㅎ
사회&문화 2007. 10. 19. 11:07
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
재미있는 그림이 소개되고 있습니다. 아래의 그림을 보면 보는사람에 따라서 시계방향/반시계방향으로 회전하는 것처럼 보이는 그림이 있습니다. 저는 처음에는 반시계방향으로 돌더니 계속 보고 있으면 다시 반대로 회전을 하다가 다시 반시계/시계 방향으로 회전 방향이 바뀌었습니다. 여러분은 어느 방향으로 회전하는 것으로 보이나요?
파일을 보니까 ani-gif로 만들어져 있었습니다. 처음에는 파일에 어떤 조작이 있는게 아닌가 생각되었습니다. 일정시간이 지나면 반대로 회전하게 만들어 진게 아닌가 하고 gif 에서 프레임을 추출해 보고 싶었습니다. 그래서 bmp파일 여러게를 추출해서 보니 이럴수가 조작은 아니었더군요.. 일부언론에서는 시계방향으로 회전하는 것처럼 보이는 사람은 우뇌가 발달한 사람이고 반시계방향으로 회전하는 것처럼 보이면 좌뇌가 발달한 사람이라고 하는데, 정확한 근거는 없습니다. 다른 해석은, 이 2차원 그림은 회전 방향을 뇌에게 알려줄 3차원적 정보를 충분히 담고 있지 않아서 회전 방향이 애매하니 뇌가 적극적으로 개입해 정보를 채워넣고 ‘임의적으로’ 회전 방향을 해석해낸다는 것이다. 위 설명이 정확한 설명인데, 아래의 해설 그림을 보면 정확하게 알 수가 있습니다. (참고로 아래의 설명은 누군가 만든 것입니다. ) 그림에서 몸이 모두 검정색인데, 생각하기에 따라서 앞 모습이 될 수도 있고 뒷 모습이 될 수도 있습니다. 그림에 라인을 그려넣으면 확실히 구분이 됩니다. 그런데 라인이 없으면 처음 보는 순간 그 모습이 앞모습인지 뒷모습인지 둘 중에 하나로 인식을 하게 되고 그에 따라 도는 방향이 보이게 되는 것입니다.
개발 2007. 10. 18. 09:51
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
제목 : 비트필드 사용하기
저자 : hanburn
날짜 : 2007-10-17
앞에서 비트벡터에 대해서 알아 보았는데, 이번에는 비트필드에 대해서 알아보도록 하겠습니다. C/C++ 언어에서 비트연산을 제공하고 있지만 바이트의 값에서 원하는 비트의 값을 가지고 오기가 쉽지 않습니다. 예를 들면 윈도우에서 키보드가 눌렸을 때 발생하는 WM_KEYDOWN 메시지에서 LPARAM으로 넘어오는 값은 많은 정보를 가지고 있습니다.
0~15 : 키가 반복되는 정보
16~23 : 키 스캔코드(OEM 정보)
24 : 확장정보 오른쪽 ALT/CTRL 키에대한 확장정보
25~28 : 예약필드
29 : context code
30 : 이전 키의 상태 (previous key state)
31 : 변화 상태 (transition state)
여기에서 30번째 비트의 정보를 읽어 오려면, shift 연산과 & 연산 등으로 해당 값을 가지고 와야 하는데 너무 번거로운 코드가 들어가야 합니다. 반대로 4바이트의 데이터에 원하는 비트를 설정하려면 비슷한 류의 번거로운 코드가 들어가야 합니다.
이러한 번거로운 작업을 편하게 해주는 방법이 비트필드를 이용하는 코딩 방법입니다. 비트필드는 C/C++언어에서 지원을 해주는데 평소에 사용할 일이 없어서 모르는 경우가 많습니다. 비트필드는 바이트단위의 정보를 비트단위로 쪼개어 쉽게 사용할 수 있게 해주는 방법입니다. WM_KYEDOWN에서 사용할 비트필드를 만들어 보면,
typedef struct ST_KEYINFO_FIELD
{
long repeat:16;
long scancode:8;
long extendkey:1;
long reserved:4;
long contextcode:1;
long previous_keystate:1;
long transition_state:1;
};
스트럭처의 변수옆에 : 표현뒤에 오는 숫자는 비트의 크기를 나타냅니다. 숫자를 다 더해보면 16+8+1+4+1+1+1 = 32 가되어 4Byte의 크기로 바로 LPARAM의 크기와 같습니다. Long은 비트필드를 사용할 바이트의 정보로 총 4바이트의 크기의 공간을 예약하고 그 뒤에 오는 숫자로 비트필드의 수를 나타닙니다. 이렇게 구조체를 정의하면 다음과 같이 편하게 값을 읽어오고 쓸수가 있게 됩니다.
ST_KEYINFO_FIELD keyInfo;
int a = keyInfo.repeat; // 반복정보(0~15비트) 읽기
keyInfo.extendkey = 1; // 확장키정보(24번째비트에) 쓰기
해당비트의 값을 읽고/쓰기는 편해졌는데, 이렇게 정의된 ST_KEYINFO_FIELD 타입의 변수에 값을 넣기는 그냥 대입을 하면 않됩니다. 아니 그럼 memcpy 등으로 복사를 해야된다는 말인가? 당연히 아니죠~ 위의 구조체와 union을 함께 사용하면 됩니다.
typedef union ST_KEYINFO
{
LPARAM lParam;
ST_KEYINFO_FIELD field;
};
공용체를 정의할때는 비트필드와 같은 키기의 변수를 잡는 것이 포인트입니다. 그래야 lparam의 값을 바로 할당 할 수가 있죠. 위에 정의된 ST_KEYINFO 공용체(union)을 사용하여 값을 읽는 코드는 아래와 같습니다.
CxxWnd::OnKeyDown(WPARAM wParam, LPARAM lParam)
{
ST_KEYINFO keyInfo;
keyInfo.lParam = lParam;
int a = keyInfo.field.repeat; //
bool b = keyInfo.field.previous_keystate;
}
공용체(union)와 비트필드를 함께 사용하면 깔끔하게 일정메모리에서 복잡한 비트연산없이 비트단위의 정보를 읽고/쓰기 작업이 편리해 지는 방법입니다.
비트벡터보다 훨씬 유용하니까 많이많이 사용하세요
개발 2007. 10. 17. 17:33
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
제목 : 비트벡터 이용하기
날짜 : 2007-10-02
저자 : hanburn
데이터를 표현할 때 비트단위를 이용하면 효율적인 경우가 있다. 요즘처럼 메모리도 많아지고 CPU도 빨라진 상황에서 굳이 비트단위의 연산을 사용할 필요가 있나 라고 생각할 수도 있지만 상황에 따라서 사용하면 상당히 효과적인 경우가 있다. 예를 들어서 2, 5, 8, 10, 14 19 이렇게 6개의 숫자를 저장해야 한다고 할 때 다음과 같이 표현될 수 있다.
비트 : 0010 0100 1010 0010 0001 0000
앞에서부터 각각의 비트는 0,1,2,3,... 을 나타내는 표현방식으로 3번째 비트가 참이므로 2를 의미하게 된다. 20이하의 숫자이므로 3Byte로(3*8=24 : 24까지 표현가능) 표현을 할 수가 있는 것이다. 6개의 int를 저장하려면 4*6=24Bytye 가 필요한것에 피하면 21Byte가 절약이 된것이다. 1백만 이하의 숫자를 저장하는데는 1백만 비트가 필요하므로 125000 바이트가(약 125KB) 필요하게 된다. 그냥 4Byte 의 숫자 1백만개를 저장하려면 4백만 바이트 (약 4MB)의 공간이 필요하다. 메모리 사용측면에서 엄청난 효율이다. 더욱이 사용하는 메모리가 줄어들면 속도도 빨라지는 이점이 있으므로 상당히 괜찮은 방법이다.
하지만 몇가지 제약사항이 있는데, 다음과 같다.
첫째, 중복되는 숫자가 있으면 안 된다.
둘째, 상대적으로 작은 숫자의 범위
셋째, 숫자와 연관되는 데이터가 없어야 한다.
그러면 이러한 비트형태의 데이터를 표현하기 위해서는 어떻게 하면 좋을까?
보통의 경우라면 C++ 의 표준라이브러리에서(STL) 제공하는 vector<bool> 을 이용하는 것이 좋은 방법이고, 환경적인 요인으로 C++의 STL을 사용할 수 없다면 다음과 같이 간단하게 구현하여 사용 할 수 있을 것이다. 간단한 클래스라서 C 함수로 변경도 쉬울 것이다.
// BitVector.h 파일
#define BITPERWORD 32
#define SHIFT_FIVE 5
#define MASK_BYTE 0x1F // 0001 1111
#define BITCOUNT 1000000
class CBitVector
{
public:
CBitVector(){}
~CBitVector(){}
void SetBit(int i)
{
bitVector[i>>SHIFT_FIVE] |= ( 1<<(i&MASK_BYTE) );
}
void ClearBit(int i)
{
bitVector[i>>SHIFT_FIVE] &= ~( 1<<(i&MASK_BYTE) );
}
int GetBit(int i)
{
return bitVector[i>>SHIFT_FIVE] & ( 1<<(i&MASK_BYTE) );
}
protected:
int bitVector[BITCOUNT/BITPERWORD+1];
private:
};
위의 클래스를 사용하는 예는 다음과 같다.
BOOL bit;
CBitVector bitVector;
bitVector.SetBit(5);
bit = bitVector.GetBit(5);
bitVector.ClearBit(5);
bit = bitVector.GetBit(5);
5번째 비트를 설정하고 그값을 확인하고 다시 5번째 비트를 해제하고 값을 확인하는 간단한 코드이다.
정리하면, 비트벡터는 적절한 경우에 사용하면 메모리와 수행성능에서 좋은 결과를 보여준다. 다만 사용할 때 몇 가지 제약사항이 있고, 나중에 프로그램이 변경되어서(요구사항 변경으로) 비트벡터로 저장된 값이 다른데이터와 연관이 생기는 경우에는 대폭적인 수정이 필요 할 수도 있다.
비트벡터라는 개념과 사용시의 주의점을 알아두고 나중에 필요할 때 한번씩 사용을 해보자.
|