[C/C++] URL 전달을 위한 urlencode & urldecode
이번에 크로미움 등 브라우저 URL 전달 시 특수문자, 한글 등 문제 때문에 필요해서 만들어보았습니다.
다른 encoder, decoder에 비해 간단하게 제작이 가능하며, 더 좋은 방법이 있으면 댓글로 달아주세요 :)
URL 전달을 위한 urlencode & urldecode
인터넷에서의 URL은 ASCII 문자열을 이용해서만 전송될 수 있는데, 그렇지 않게 전송한 경우 브라우저의 특성에 따라 question mark(?), ampersand(&), 슬래시(/), 공백 문자 같은 특수문자의 경우 잘리거나 의도치않게 변형이 될 수 있습니다.
그래서 이런 특수문자는 인코딩이 되는 것이 좋습니다. ASCII에 포함되지 않는 문자들(한글, 일본어 등등)은 더욱 encoding이 필요하게 됩니다.
인코딩은 %octer 형태로 만들어 주는 것입니다. ex) #은 %23
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 |
댓글
이 글 공유하기
다른 글
-
[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