이 영역을 누르면 첫 페이지로 이동
웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

페이지 맨 위로 올라가기

웬디의 기묘한 이야기

C/C++ Windows Hooking 개발자의 블로그 입니다! 이곳은 개발 외에도 저의 취미들이 공유되는 기묘한 이야기가 펼쳐집니다.

[C/C++] URL 전달을 위한 urlencode & urldecode

  • 2019.07.11 21:27
  • ⌨ DEVELOPMENT/C++
반응형

이번에 크로미움 등 브라우저 URL 전달 시 특수문자, 한글 등 문제 때문에 필요해서 만들어보았습니다.

다른 encoder, decoder에 비해 간단하게 제작이 가능하며, 더 좋은 방법이 있으면 댓글로 달아주세요 :)

 

URL 전달을 위한 urlencode & urldecode

인터넷에서의 URL은 ASCII 문자열을 이용해서만 전송될 수 있는데, 그렇지 않게 전송한 경우 브라우저의 특성에 따라 question mark(?), ampersand(&), 슬래시(/), 공백 문자 같은 특수문자의 경우 잘리거나 의도치않게 변형이 될 수 있습니다.

그래서 이런 특수문자는 인코딩이 되는 것이 좋습니다. ASCII에 포함되지 않는 문자들(한글, 일본어 등등)은 더욱 encoding이 필요하게 됩니다.

인코딩은 %octer 형태로 만들어 주는 것입니다. ex) #은 %23

RFC1738 Document

https://www.ietf.org/rfc/rfc1738.txt

 

Character Encoding Chart

To help promote the cause of Web Standards and adhering to specifications,

here is a quick reference chart explaining which characters are “safe” and which characters should be encoded in URLs.

Safe characters Alphanumerics [0-9a-zA-Z], special characters $-_.+!*'(),, and reserved characters used for their reserved purposes (e.g., question mark used to denote a query string) NO
ASCII Control characters Includes the ISO-8859-1 (ISO-Latin) character ranges 00-1F hex (0-31 decimal) and 7F (127 decimal.) YES
Non-ASCII characters Includes the entire “top half” of the ISO-Latin set 80-FF hex (128-255 decimal.) YES
Reserved characters ; / ? : @ = & (does not include blank space) YES
Unsafe characters Includes the blank/empty space and " < > # % { } | \ ^ ~ [ ] ` YES

그렇다면 샘플을 한번 보실까요?


#include <iostream>
#include <Windows.h>
#include <string>

char _x2c(
    __in char hex_up, 
    __in char hex_low
    ) {
    char digit;

    digit = 16 * (hex_up >= 'A' ? ((hex_up & 0xdf) - 'A') + 10 : (hex_up - '0'));
    digit += (hex_low >= 'A' ? ((hex_low & 0xdf) - 'A') + 10 : (hex_low - '0'));
    
    return digit;
}

DWORD url_decode(
    __out std::string& output_string,
    __in std::string& encode_string
    ) {

    DWORD error = ERROR_SUCCESS;

    do {

        if (encode_string.empty()) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        std::string temp_output_string;

        for (size_t i = 0; i < encode_string.size(); i++) {
            switch (encode_string.at(i)) {
            case '%':
            {
                temp_output_string.push_back(_x2c(encode_string.at(i + 1), encode_string.at(i + 2)));
                i += 2;
            }
            break;

            default:
            {
                temp_output_string.push_back(encode_string.at(i));
            }
            break;

            }
        }

        if (false == temp_output_string.empty()) {
            output_string.assign(temp_output_string);
        }

    } while (false);

    return error;
}

DWORD url_encode(
    __out std::string& output_string,
    __in std::string& plain_string
    ) {
    DWORD error = ERROR_SUCCESS;

    do {

        if (plain_string.empty()) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        std::string temp_output_string;

        for (size_t i = 0; i < plain_string.size(); i++) {
            char ch = plain_string.at(i);
            if (isdigit(ch)) {
                temp_output_string.push_back(ch);
            }
            else if (isalpha(ch)) {
                temp_output_string.push_back(ch);
            }
            else if (ch == '$' || // Safe characters 이지만 모두 encoding 해도 무관함.
                ch == '-' ||
                ch == '_' ||
                ch == '.' ||
                ch == '+' ||
                ch == '!' ||
                ch == '*' ||
                ch == '\'' ||
                ch == '(' ||
                ch == ')' ||
                ch == ',') {
                temp_output_string.push_back(ch);
            }
            else {
                char temp[3] = "";
                sprintf_s(temp, "%02x", ch);
                temp_output_string.push_back('%');
                temp_output_string.push_back(temp[0]);
                temp_output_string.push_back(temp[1]);
            }
        }

        if (false == temp_output_string.empty()) {
            output_string.assign(temp_output_string);
        }

    } while (false);

    return error;
}


int main()
{

    do {
        std::string plain_string = "plain & text !@#$%^&*()_+-=,.[]{};:\'\"`";
        std::string encode_string = "";

        DWORD error = url_encode(encode_string, plain_string);
        if (ERROR_SUCCESS != error) {
            break;
        }

        std::string decode_string = "";
        error = url_decode(decode_string, encode_string);

        if (ERROR_SUCCESS != error) {
            break;
        }

        printf(decode_string.c_str());

    } while (false);

    system("pause");
}


 

 

위의 조건에 맞게 작성해보았습니다.

정상 encoding 된 문자열이라면 decoding시 아무런 문제가 없겠지만, 검증이 되지 않은 문자열을 decoding 시도하면 분명 문제가 발생할 수 있습니다.

보장된 상황이 아니라면 추가 작업이 필요할 수 있지만, 기본적으론 사용에 문제가 없어 보이네요!

더 좋은 방법이 있으신 분은 댓글 달아주세요!!

반응형

'⌨ DEVELOPMENT > C++' 카테고리의 다른 글

[C++] How to use GDIPlus Library in c++  (0) 2019.07.28
[MFC] 다이얼로그의 윈도우 소멸자 호출 순서  (1) 2019.07.28
[C/C++] string wstring format 사용하기  (1) 2019.07.27
[C/C++] 윈도우10 Boost 최신버전 설치 및 사용법  (13) 2019.07.27
[C/C++] process crash 로그 및 덤프 남기기 (access violation)  (0) 2019.07.06
[C/C++] convert string, wstring, utf-8  (9) 2019.07.06
[C/C++] 작업표시줄 아이콘 깜빡이게 하기 (FlashWIndow)  (0) 2019.07.03
[C++] std::string to std::wstring 서로 변환하기  (3) 2016.01.31

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [C/C++] string wstring format 사용하기

    [C/C++] string wstring format 사용하기

    2019.07.27
  • [C/C++] 윈도우10 Boost 최신버전 설치 및 사용법

    [C/C++] 윈도우10 Boost 최신버전 설치 및 사용법

    2019.07.27
  • [C/C++] process crash 로그 및 덤프 남기기 (access violation)

    [C/C++] process crash 로그 및 덤프 남기기 (access violation)

    2019.07.06
  • [C/C++] convert string, wstring, utf-8

    [C/C++] convert string, wstring, utf-8

    2019.07.06
다른 글 더 둘러보기

정보

웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

  • 웬디의 기묘한 이야기의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록
  • 이야기

카테고리

  • 분류 전체보기 (204)
    • MY STORY (2)
    • 📸 WALKING WITH YOU (85)
      • 아이슬란드 신혼여행 이야기 (14)
      • 대한민국 구석구석 (62)
      • CONTAX N1 + T* 28-80mm (4)
      • SAMSUNG NX3000 (1)
      • 어느 멋진 날 (4)
    • ⌨ DEVELOPMENT (80)
      • BOOK:Review (1)
      • AI (13)
      • C++ (26)
      • Python (10)
      • WIndows Hooking (9)
      • Windows Kernel (3)
      • Design Pattern (3)
      • Debugging (9)
      • Tools (0)
      • Project (1)
      • Android (1)
      • 상업용 무료폰트 (4)
    • OS (4)
      • News (0)
      • Windows 일반 (4)
    • 모바일 (2)
      • 모바일 게임 (2)
    • 멘사 퍼즐 (9)
    • 생활 꿀 TIP (7)
      • 건강 (3)
      • 일상 (2)
    • 물생활 (8)
      • 골든볼 라미네지 롱핀 (8)
    • IT 기기 (2)
    • BLOG (4)
      • TISTORY BLOG TIP (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 아이슬란드
  • AI
  • 신혼여행
  • c++
  • windbg
  • 카페
  • c
  • 해외여행

나의 외부 링크

  • kernel undocument api
  • 지구 관찰자의 일기
  • 지구와 지구곰

정보

WENDYS의 웬디의 기묘한 이야기

웬디의 기묘한 이야기

WENDYS

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © WENDYS. Designed by Fraccino.

티스토리툴바