URL转义意义和其c++实现
2015-12-25 13:06
609 查看
URL中的字符只能是ASCII字符,但是ASCII字符比较少,而URL则常常包含ASCII字符集以外的字符,如非英语字符、汉字、特殊符号等等,所以要对URL进行转换。这个过程就叫做URL编码,或者叫URL转义,实质上就是将包含非ASCII字符的URL转换为有效的ASCII字符格式。
在进行URL编码时,每一个非ASCII字符都被替换为“%hh”格式,其中hh为两位十六进制数,它对应于该字符在ISO-8859-1字符集里的编码值。比如“中国”这两个汉字出现在URL,就要将他们转为“%D6%D0%B9%FA”,由于一个汉字需要两个字节,所以“中国”被替换成了四个ASCII字符。
转换代码入戏下:
ASCII字符与URL编码的对照表如下
ASCII字符 URL编码
空格 %20
! %21
" %22
# %23
$ %24
% %25
& %26
' %27
( %28
) %29
* %2A
+ %2B
, %2C
- %2D
. %2E
/ %2F
0 %30
1 %31
2 %32
3 %33
4 %34
5 %35
6 %36
7 %37
8 %38
9 %39
: %3A
; %3B
< %3C = %3D > %3E
? %3F
@ %40
A %41
B %42
C %43
D %44
E %45
F %46
G %47
H %48
I %49
J %4A
K %4B
L %4C
M %4D
N %4E
O %4F
P %50
Q %51
R %52
S %53
T %54
U %55
V %56
W %57
X %58
Y %59
Z %5A
[ %5B
\ %5C
] %5D
^ %5E
_ %5F
` %60
a %61
b %62
c %63
d %64
e %65
f %66
g %67
h %68
i %69
j %6A
k %6B
l %6C
m %6D
n %6E
o %6F
p %70
q %71
r %72
s %73
t %74
u %75
v %76
w %77
x %78
y %79
z %7A
{ %7B
| %7C
} %7D
~ %7E
%7F
€ %80
%81
? %82
? %83
? %84
… %85
? %86
? %87
? %88
‰ %89
? %8A
? %8B
? %8C
%8D
? %8E
%8F
%90
‘ %91
’ %92
“ %93
” %94
? %95
– %96
— %97
? %98
? %99
? %9A
? %9B
? %9C
%9D
? %9E
? %9F
%A0
? %A1
¢ %A2
£ %A3
%A4
¥ %A5
| %A6
§ %A7
¨ %A8
? %A9
a %AA
? %AB
? %AC
ˉ %AD
? %AE
ˉ %AF
° %B0
± %B1
2 %B2
3 %B3
′ %B4
μ %B5
? %B6
· %B7
? %B8
1 %B9
o %BA
? %BB
? %BC
? %BD
? %BE
? %BF
à %C0
á %C1
? %C2
? %C3
? %C4
? %C5
? %C6
? %C7
è %C8
é %C9
ê %CA
? %CB
ì %CC
í %CD
? %CE
? %CF
D %D0
? %D1
ò %D2
ó %D3
? %D4
? %D5
? %D6
%D7
? %D8
ù %D9
ú %DA
? %DB
ü %DC
Y %DD
T %DE
? %DF
à %E0
á %E1
a %E2
? %E3
? %E4
? %E5
? %E6
? %E7
è %E8
é %E9
ê %EA
? %EB
ì %EC
í %ED
? %EE
? %EF
e %F0
? %F1
ò %F2
ó %F3
? %F4
? %F5
? %F6
÷ %F7
? %F8
ù %F9
ú %FA
? %FB
ü %FC
y %FD
t %FE
? %FF
在进行URL编码时,每一个非ASCII字符都被替换为“%hh”格式,其中hh为两位十六进制数,它对应于该字符在ISO-8859-1字符集里的编码值。比如“中国”这两个汉字出现在URL,就要将他们转为“%D6%D0%B9%FA”,由于一个汉字需要两个字节,所以“中国”被替换成了四个ASCII字符。
转换代码入戏下:
/// 十六进制对应的字符 static unsigned char hexchars[] = "0123456789ABCDEF"; /** * \brief 对url特殊字符进行编码 * \param s 输入字符串 * \param len 输入字符串长度 * \param new_length 输出字符串长度 * \return 输出编码后的url字符串,这段内存再使用完成以后需要释放 */ char *url_encode(const char *s, int len, int *new_length) { register int x, y; unsigned char *str; str = (unsigned char *)malloc(3 * len + 1); for(x = 0, y = 0; len--; x++, y++) { str[y] = (unsigned char) s[x]; if (str[y] == ' ') { str[y] = '+'; } else if ((str[y] < '0' && str[y] != '-' && str[y] != '.') || (str[y] < 'A' && str[y] > '9') || (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') || (str[y] > 'z')) { str[y++] = '%'; str[y++] = hexchars[(unsigned char) s[x] >> 4]; str[y] = hexchars[(unsigned char) s[x] & 15]; } } str[y] = '\0'; if (new_length) { *new_length = y; } return ((char *) str); } void url_encode(std::string &s) { char *buf = url_encode(s.c_str(), s.length(), NULL); if (buf) { s = buf; free(buf); } } //字符串转换整数 static inline int htoi(char *s) { int value; int c; c = ((unsigned char *)s)[0]; if (isupper(c)) c = tolower(c); value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; c = ((unsigned char *)s)[1]; if (isupper(c)) c = tolower(c); value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; return (value); } /** * \brief url字符串解码 * \param str 待解码的字符串,同时也作为输出 * \param len 待解码字符串的长度 * \return 解码以后的字符串长度 */ int url_decode(char *str, int len) { char *dest = str; char *data = str; while (len--) { if (*data == '+') *dest = ' '; else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) { *dest = (char) htoi(data + 1); data += 2; len -= 2; } else *dest = *data; data++; dest++; } *dest = '\0'; return dest - str; } /** * \brief url字符串解码 * \param str 待解码的字符串,同时也作为输出 */ void url_decode(std::string &str) { char buf[str.length() + 1]; strcpy(buf, str.c_str()); url_decode(buf, str.length()); str = buf; } /** * \brief url字符串解码,并处理成符合json格式 * \param str 待解码的字符串,同时也作为输出 */ void url_decode_json(std::string &str) { char buf[str.length() + 1]; strcpy(buf, str.c_str()); url_decode(buf, str.length()); //去掉前后的'\"'符号 if(buf[0] && buf[0] == '\"') { buf[0] = ' '; } unsigned int bufStrLen = strlen(buf); if(bufStrLen && bufStrLen < sizeof(buf) && buf[bufStrLen-1] == '\"') { buf[bufStrLen-1] = ' '; } str = buf; //去掉符号'\\'作为'\"'的前缀 std::string::size_type pos = 0;//位置 std::string strsrc = "\\\"";//要替换的字符串 std::string strdst = "\"";//目标字符串 std::string::size_type srclen = strsrc.size();//要替换的字符串大小 std::string::size_type dstlen = strdst.size();//目标字符串大小 while((pos = str.find(strsrc,pos)) != std::string::npos) { str.replace(pos,srclen,strdst); pos += dstlen; } }
ASCII字符与URL编码的对照表如下
ASCII字符 URL编码
空格 %20
! %21
" %22
# %23
$ %24
% %25
& %26
' %27
( %28
) %29
* %2A
+ %2B
, %2C
- %2D
. %2E
/ %2F
0 %30
1 %31
2 %32
3 %33
4 %34
5 %35
6 %36
7 %37
8 %38
9 %39
: %3A
; %3B
< %3C = %3D > %3E
? %3F
@ %40
A %41
B %42
C %43
D %44
E %45
F %46
G %47
H %48
I %49
J %4A
K %4B
L %4C
M %4D
N %4E
O %4F
P %50
Q %51
R %52
S %53
T %54
U %55
V %56
W %57
X %58
Y %59
Z %5A
[ %5B
\ %5C
] %5D
^ %5E
_ %5F
` %60
a %61
b %62
c %63
d %64
e %65
f %66
g %67
h %68
i %69
j %6A
k %6B
l %6C
m %6D
n %6E
o %6F
p %70
q %71
r %72
s %73
t %74
u %75
v %76
w %77
x %78
y %79
z %7A
{ %7B
| %7C
} %7D
~ %7E
%7F
€ %80
%81
? %82
? %83
? %84
… %85
? %86
? %87
? %88
‰ %89
? %8A
? %8B
? %8C
%8D
? %8E
%8F
%90
‘ %91
’ %92
“ %93
” %94
? %95
– %96
— %97
? %98
? %99
? %9A
? %9B
? %9C
%9D
? %9E
? %9F
%A0
? %A1
¢ %A2
£ %A3
%A4
¥ %A5
| %A6
§ %A7
¨ %A8
? %A9
a %AA
? %AB
? %AC
ˉ %AD
? %AE
ˉ %AF
° %B0
± %B1
2 %B2
3 %B3
′ %B4
μ %B5
? %B6
· %B7
? %B8
1 %B9
o %BA
? %BB
? %BC
? %BD
? %BE
? %BF
à %C0
á %C1
? %C2
? %C3
? %C4
? %C5
? %C6
? %C7
è %C8
é %C9
ê %CA
? %CB
ì %CC
í %CD
? %CE
? %CF
D %D0
? %D1
ò %D2
ó %D3
? %D4
? %D5
? %D6
%D7
? %D8
ù %D9
ú %DA
? %DB
ü %DC
Y %DD
T %DE
? %DF
à %E0
á %E1
a %E2
? %E3
? %E4
? %E5
? %E6
? %E7
è %E8
é %E9
ê %EA
? %EB
ì %EC
í %ED
? %EE
? %EF
e %F0
? %F1
ò %F2
ó %F3
? %F4
? %F5
? %F6
÷ %F7
? %F8
ù %F9
ú %FA
? %FB
ü %FC
y %FD
t %FE
? %FF
相关文章推荐
- 飞机售票系统
- (C++) CreateThread
- 解决libc++abi.dylib: terminate_handler unexpectedly threw an exception(1)
- 巧妙地用二叉树完成算式计算算法<计算器,二叉树,C++,独辟蹊径>
- extern "C"的用法解析
- C++ 输出控制
- C++——谈谈你对面向对象编程的认识
- c++设计模式之策略模式
- C++ 输入/输出(一)
- 算法学习 - 图的广度优先遍历(BFS) (C++)
- C++之创建对象时的new与不new
- 使用Javah 生成C/C++头文件的误区
- c语言中字符串和字符串函数
- c++ 中__declspec 的用法
- interbase C++Builder 简单例子
- XML解析简介及Xerces-C++简单使用举例
- 二叉树层次遍历
- C++ math.h库函数
- 基础:c++中引用与java中的引用
- c++回调函数 callback