천객만래 [千客萬來] (It has an interminable succession of visitors)

[개발/VC++] URLEncode, URLDecode, 유니코드 변환 소스



[개발/VC++] URLEncode, URLDecode, UTF8 변환 소스


[유니코드 문자집합용]


CString Unicode_URLDecode( CString strEncodedText )
{
 CString strResult;
 wchar_t ch0, ch1, ch2;
 wchar_t wch;
 TCHAR tch;
 int i = 0;


 while( i<strEncodedText.GetLength() )
 {
  tch = strEncodedText.GetAt(i);
  
  if( tch != _T('%') )
  {
   // a character not encoded
   strResult += tch;
   i++;
  }
  else
  {
   // a character encoded !!
   ch0 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
   i += 3;


   if( ch0 < 0x80 )
    // 1 byte for UTF-8
    // 0xxx xxxx
    wch = ch0;
   else
   {
    if( strEncodedText.GetAt(i)!= _T('%') ) // Error!
     continue;


    ch1 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
    i += 3;


    if( ch0 < 0xe0 )
    {
     // 2 byte for UTF-8
     // 110x xxxx 10xx xxxx
     wch = ((ch0&0x1f)<<6)
      | (ch1&0x3f);
    }
    else
    {
     // 3 byte for UTF-8
     if( strEncodedText.GetAt(i)!= _T('%') ) // Error!
      continue;


     ch2 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
     i += 3;


     // 1110 xxxx 10xx xxxx 10xx xxxx
     wch = ((ch0&0x0f)<<12)
      | ((ch1&0x3f)<<6)
      | (ch2&0x3f);
    }
   }
   strResult += wch;
  }
 }


 return strResult;
}

 

-------------------------------------------------------------------------------------------
[멀티바이트 문자집합용]


inline BYTE CURLEncode::toHex(const BYTE &x) {
 return x > 9 ? x + 55: x + 48;
}


inline BYTE CURLEncode::toByte(const BYTE &x) {
 return x > 57? x - 55: x - 48;
}

CString CURLEncode::URLDecode(CString sIn)
{
    CString sOut;
    const int nLen = sIn.GetLength() + 1;
    register LPBYTE pOutTmp = NULL;
    LPBYTE pOutBuf = NULL;
    register LPBYTE pInTmp = NULL;
    LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
    //alloc out buffer
    pOutBuf = (LPBYTE)sOut.GetBuffer(nLen);
    
    if(pOutBuf)
    {
        pInTmp   = pInBuf;
        pOutTmp = pOutBuf;
        // do encoding
        while (*pInTmp)
        {
            if('%'==*pInTmp)
            {
                pInTmp++;
                *pOutTmp++ = (toByte(*pInTmp)%16<<4) + toByte(*(pInTmp+1))%16;
                pInTmp++;
            }
            else if('+'==*pInTmp)
                *pOutTmp++ = ' ';
            else
                *pOutTmp++ = *pInTmp;
            pInTmp++;
        }
        *pOutTmp = '\0';
        sOut.ReleaseBuffer();
    }
    sIn.ReleaseBuffer();
    
    return sOut;
}


CString CURLEncode::URLEncode(CString sIn)
{
    CString sOut;
    const int nLen = sIn.GetLength() + 1;
    register LPBYTE pOutTmp = NULL;
    LPBYTE pOutBuf = NULL;
    register LPBYTE pInTmp = NULL;
    LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
    //alloc out buffer
    pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3);
    
    if(pOutBuf)
    {
        pInTmp   = pInBuf;
        pOutTmp = pOutBuf;
        // do encoding
        while (*pInTmp)
        {
            if(isalnum(*pInTmp) || '-'==*pInTmp || '_'==*pInTmp || '.'==*pInTmp)
                *pOutTmp++ = *pInTmp;
            else if(isspace(*pInTmp))
                *pOutTmp++ = '+';
            else
            {
                *pOutTmp++ = '%';
                *pOutTmp++ = toHex(*pInTmp>>4);
                *pOutTmp++ = toHex(*pInTmp%16);
            }
            pInTmp++;
        }
        *pOutTmp = '\0';
        sOut.ReleaseBuffer();
    }
    sIn.ReleaseBuffer();
    
    return sOut;
}


 





Posted by SB패밀리

[개발/VC++] URLEncode, URLDecode, UTF8 변환 소스



아래 소스는 멀티바이트 문자집합 프로젝트 설정으로 작업해야 작동된다.

inline BYTE toHex(const BYTE &x)
{
       return x > 9 ? x + 55: x + 48;
}

CString URLEncode(CString sIn)
{
       CString sOut;
       const int nLen = sIn.GetLength() + 1;
       register LPBYTE pOutTmp = NULL;
       LPBYTE pOutBuf = NULL;
       register LPBYTE pInTmp = NULL;
       LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
       BYTE b = 0;

       //alloc out buffer
       pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen * 3];

       if(pOutBuf)
       {
             pInTmp   = pInBuf;
              pOutTmp = pOutBuf;

              // do encoding
              while (*pInTmp)
              {
                     if(isalnum(*pInTmp))
                            *pOutTmp++ = *pInTmp;
                     else
                            if(isspace(*pInTmp))
                                   *pOutTmp++ = '+';
                            else
                            {
                                   *pOutTmp++ = '%';
                                   *pOutTmp++ = toHex(*pInTmp>>4);
                                   *pOutTmp++ = toHex(*pInTmp%16);
                            }
                     pInTmp++;
              }
              *pOutTmp = '\0';
              //sOut=pOutBuf;
              //delete [] pOutBuf;
              sOut.ReleaseBuffer();
       }
       sIn.ReleaseBuffer();
       return sOut;
}


UrlDecode:
#define IsHexNum(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))

CString Utf8ToStringT(LPSTR str)
{
    _ASSERT(str);
    USES_CONVERSION;
    WCHAR *buf;
    int length = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
    buf = new WCHAR[length+1];
    ZeroMemory(buf, (length+1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, length);

    return (CString(W2T(buf)));
}

CString UrlDecode(LPCTSTR url)
{
    _ASSERT(url);
    USES_CONVERSION;
    LPSTR _url = T2A(const_cast<LPTSTR>(url));
    int i = 0;
    int length = (int)strlen(_url);
    CHAR *buf = new CHAR[length];
    ZeroMemory(buf, length);
    LPSTR p = buf;
    while(i < length)
    {
        if(i <= length -3 && _url[i] == '%' && IsHexNum(_url[i+1]) && IsHexNum(_url[i+2]))
        {
            sscanf(_url + i + 1, "%x", p++);
            i += 3;
        }
        else
        {
            *(p++) = _url[i++];
        }
    }
    return Utf8ToStringT(buf);
}








Posted by SB패밀리

[개발/VC++] URLEncode, URLDecode, UTF8 변환 소스


[유니코드 문자집합용]


CString Unicode_URLDecode( CString strEncodedText )
{
 CString strResult;
 wchar_t ch0, ch1, ch2;
 wchar_t wch;
 TCHAR tch;
 int i = 0;


 while( i<strEncodedText.GetLength() )
 {
  tch = strEncodedText.GetAt(i);
  
  if( tch != _T('%') )
  {
   // a character not encoded
   strResult += tch;
   i++;
  }
  else
  {
   // a character encoded !!
   ch0 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
   i += 3;


   if( ch0 < 0x80 )
    // 1 byte for UTF-8
    // 0xxx xxxx
    wch = ch0;
   else
   {
    if( strEncodedText.GetAt(i)!= _T('%') ) // Error!
     continue;


    ch1 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
    i += 3;


    if( ch0 < 0xe0 )
    {
     // 2 byte for UTF-8
     // 110x xxxx 10xx xxxx
     wch = ((ch0&0x1f)<<6)
      | (ch1&0x3f);
    }
    else
    {
     // 3 byte for UTF-8
     if( strEncodedText.GetAt(i)!= _T('%') ) // Error!
      continue;


     ch2 = _tcstol( strEncodedText.Mid( i+1, 2 ), NULL, 16 );
     i += 3;


     // 1110 xxxx 10xx xxxx 10xx xxxx
     wch = ((ch0&0x0f)<<12)
      | ((ch1&0x3f)<<6)
      | (ch2&0x3f);
    }
   }
   strResult += wch;
  }
 }


 return strResult;
}

 

-------------------------------------------------------------------------------------------
[멀티바이트 문자집합용]


inline BYTE CURLEncode::toHex(const BYTE &x) {
 return x > 9 ? x + 55: x + 48;
}


inline BYTE CURLEncode::toByte(const BYTE &x) {
 return x > 57? x - 55: x - 48;
}

CString CURLEncode::URLDecode(CString sIn)
{
    CString sOut;
    const int nLen = sIn.GetLength() + 1;
    register LPBYTE pOutTmp = NULL;
    LPBYTE pOutBuf = NULL;
    register LPBYTE pInTmp = NULL;
    LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
    //alloc out buffer
    pOutBuf = (LPBYTE)sOut.GetBuffer(nLen);
   
    if(pOutBuf)
    {
        pInTmp   = pInBuf;
        pOutTmp = pOutBuf;
        // do encoding
        while (*pInTmp)
        {
            if('%'==*pInTmp)
            {
                pInTmp++;
                *pOutTmp++ = (toByte(*pInTmp)%16<<4) + toByte(*(pInTmp+1))%16;
                pInTmp++;
            }
            else if('+'==*pInTmp)
                *pOutTmp++ = ' ';
            else
                *pOutTmp++ = *pInTmp;
            pInTmp++;
        }
        *pOutTmp = '\0';
        sOut.ReleaseBuffer();
    }
    sIn.ReleaseBuffer();
   
    return sOut;
}


CString CURLEncode::URLEncode(CString sIn)
{
    CString sOut;
    const int nLen = sIn.GetLength() + 1;
    register LPBYTE pOutTmp = NULL;
    LPBYTE pOutBuf = NULL;
    register LPBYTE pInTmp = NULL;
    LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
    //alloc out buffer
    pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3);
   
    if(pOutBuf)
    {
        pInTmp   = pInBuf;
        pOutTmp = pOutBuf;
        // do encoding
        while (*pInTmp)
        {
            if(isalnum(*pInTmp) || '-'==*pInTmp || '_'==*pInTmp || '.'==*pInTmp)
                *pOutTmp++ = *pInTmp;
            else if(isspace(*pInTmp))
                *pOutTmp++ = '+';
            else
            {
                *pOutTmp++ = '%';
                *pOutTmp++ = toHex(*pInTmp>>4);
                *pOutTmp++ = toHex(*pInTmp%16);
            }
            pInTmp++;
        }
        *pOutTmp = '\0';
        sOut.ReleaseBuffer();
    }
    sIn.ReleaseBuffer();
   
    return sOut;
}


 

Posted by SB패밀리

[개발/VC++] URLEncode, URLDecode, UTF8 변환 소스

아래 소스는 멀티바이트 문자집합 프로젝트 설정으로 작업해야 작동된다.

inline BYTE toHex(const BYTE &x)
{
       return x > 9 ? x + 55: x + 48;
}

CString URLEncode(CString sIn)
{
       CString sOut;
       const int nLen = sIn.GetLength() + 1;
       register LPBYTE pOutTmp = NULL;
       LPBYTE pOutBuf = NULL;
       register LPBYTE pInTmp = NULL;
       LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
       BYTE b = 0;

       //alloc out buffer
       pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen * 3];

       if(pOutBuf)
       {
             pInTmp   = pInBuf;
              pOutTmp = pOutBuf;

              // do encoding
              while (*pInTmp)
              {
                     if(isalnum(*pInTmp))
                            *pOutTmp++ = *pInTmp;
                     else
                            if(isspace(*pInTmp))
                                   *pOutTmp++ = '+';
                            else
                            {
                                   *pOutTmp++ = '%';
                                   *pOutTmp++ = toHex(*pInTmp>>4);
                                   *pOutTmp++ = toHex(*pInTmp%16);
                            }
                     pInTmp++;
              }
              *pOutTmp = '\0';
              //sOut=pOutBuf;
              //delete [] pOutBuf;
              sOut.ReleaseBuffer();
       }
       sIn.ReleaseBuffer();
       return sOut;
}


UrlDecode:
#define IsHexNum(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))

CString Utf8ToStringT(LPSTR str)
{
    _ASSERT(str);
    USES_CONVERSION;
    WCHAR *buf;
    int length = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
    buf = new WCHAR[length+1];
    ZeroMemory(buf, (length+1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, length);

    return (CString(W2T(buf)));
}

CString UrlDecode(LPCTSTR url)
{
    _ASSERT(url);
    USES_CONVERSION;
    LPSTR _url = T2A(const_cast<LPTSTR>(url));
    int i = 0;
    int length = (int)strlen(_url);
    CHAR *buf = new CHAR[length];
    ZeroMemory(buf, length);
    LPSTR p = buf;
    while(i < length)
    {
        if(i <= length -3 && _url[i] == '%' && IsHexNum(_url[i+1]) && IsHexNum(_url[i+2]))
        {
            sscanf(_url + i + 1, "%x", p++);
            i += 3;
        }
        else
        {
            *(p++) = _url[i++];
        }
    }
    return Utf8ToStringT(buf);
}


 

Posted by SB패밀리

utf-8 방식을 추구하기 위해 원래는 코드비하인드에서 한글데이터값을 Server.UrlEncode 매서드를 사용해 인코딩해서 쿠키에 넣은후 자바스크립트에서 쿠키값을 읽어와 GET 방식으로 넘겨주려 했지만 GET방식으로 호출한 페이지에서 Server.UrlDecode 매서드를 사용해보았지만 한글데이터가 깨지는 이유로 부득이하게 Cookie가 아닌 Hidden 컨트롤을 사용하였다.

 web.config

utf-8 방식 사용

<globalization requestEncoding="utf-8" responseEncoding="utf-8" />


 

A.cs

Hidden 컨트롤에 인코딩된 데이터를 넣는다.

hidRName.Value = Server.UrlEncode(m_strRname);  <- UrlEncode 매서드를 사용하면 한글데이터를 스크립트단에서 이진데이터로 표시되게 해준다. UrlEncode  매서드를 사용하면 주소창에 한글데이터를 이진데이터로 표시해서 넘겨주는 장점이 있는것 같다.

 

A.aspx

Hidden 컨트롤값을 변수에 담는다.

var vR_NAME = document.getElementById("hidRName").value;

var avs_URL = "B.aspx?R_NAME=" + vR_NAME ;

 

B.aspx 호출

 

B.cs

TextBox 값에 넘어온 파라미터값 셋팅

txtRName.Value = Server.UrlDecode(Request["R_NAME"]);

이렇게하면 UTF-8 방식일경우 한글데이터를 넘겨받을수 있다.  ( txtRName.Value = Request["R_NAME"];  <- 이방법도 가능함. )


 

 

원래 시도하였던 방식의 자바스크립트에서 쿠키값 가져오는 함수. 좀더 보강하면 Cookie 를 사용하더라도 한글데이터가 깨지지않게 넘겨받을수 있을거 같다. (해결방법 : js 파일내에서 escape() 함수를 사용하면 된다)

// *****************************************************
// 내용 : 쿠키값 가져오기
// 작성일자 : 2007.11.29
// 작성자 : 한재준
// name : Cookie Name
// *****************************************************
function getCookie( name )
{
    var tempArr = document.cookie.split("&");
    var nameOfCookie = name + "=";
    var x = 0;
    var y = (nameOfCookie.length);
    var returnValue = "";
   
    for(var i=0; i<tempArr.length; i++)
    {
        if(tempArr[i].substring( x, y ) == nameOfCookie)
        {
            endOfCookie = tempArr[i].length;
            returnValue = unescape(tempArr[i].substring( y, endOfCookie));
            break;
        }
    }
   
    return returnValue;
}

  

Tip !

위와 같은방식으로 UrlEncode 매서드와 HtmlEncode 매서드의 차이점을 확인하기 위해서 HtmlEncode 매서드를 사용해봤으나( hidRName.Value = Server.HtmlEncode(m_strRname); )  B.cs 페이지에서  HtmlDecode 매서드를 사용해 넘어온 파라미터값을 디코딩해보았지만 한글데이터가 깨지는것을 확인하였다.
 결론은 utf-8 방식에서는 한글데이터를 GET 방식으로 넘겨줄때는 항상 UrlEncode 매서드를 사용해야 한다는 것이다

Posted by SB패밀리