鑑於有時要用C++ 寫CGI,url encode、decode是必不可少的,有必要單獨整理下。這裏吐槽下,C++做web真是笨重,沒有python、php爽。
http://blog.csdn.net/nanjunxiao/article/details/9303619之前寫過一個簡單的encode,這裏補充更新下。
#include <string>
#include <iostream>
using namespace std;
//static const char safe[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static const char safe[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
std::string encode(const std::string &uri)
{
string ret;
const unsigned char *ptr = (const unsigned char *)uri.c_str();
ret.reserve(uri.length());
for (; *ptr ; ++ptr)
{
if (!safe[*ptr])
{
char buf[5];
memset(buf, 0, 5);
#ifdef WIN32
_snprintf_s(buf, 5, "%%%X", (*ptr));
#else
snprintf(buf, 5, "%%%X", (*ptr));
#endif
ret.append(buf);
}
else if (*ptr==' ')
{
ret+='+';
}
else{
ret += *ptr;
}
}
return ret;
}
std::string decode(const std::string &uri)
{
//Note from RFC1630: "Sequences which start with a percent sign
//but are not followed by two hexadecimal characters (0-9,A-F) are reserved
//for future extension"
const unsigned char *ptr = (const unsigned char *)uri.c_str();
string ret;
ret.reserve(uri.length());
for (; *ptr; ++ptr)
{
if (*ptr == '%')
{
if (*(ptr + 1))
{
char a = *(ptr + 1);
char b = *(ptr + 2);
if (!((a >= 0x30 && a < 0x40) || (a >= 0x41 && a < 0x47))) continue;
if (!((b >= 0x30 && b < 0x40) || (b >= 0x41 && b < 0x47))) continue;
char buf[3];
buf[0] = a;
buf[1] = b;
buf[2] = 0;
ret += (char)strtoul(buf, NULL, 16);
ptr += 2;
continue;
}
}
if (*ptr=='+')
{
ret+=' ';
continue;
}
ret += *ptr;
}
return ret;
}