url的encode和decode

相关RFC:http://curl.haxx.se/rfc/rfc2396.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* ---------------------------------------------------------------------------
* Encode URL by converting special characters to %XX (where XX are hexadecimal digits)
* Don't forget to free the return value.
*/
char *urlencode(const char *url)
{
#define COPY_TO_ENCODE_URL(c) \
if (outlen < pos) { \
outlen += 10; \
out = realloc(out, outlen + 1); \
} \
out[pos ++] = c; \
size_t i, len = strlen(url), outlen;
outlen = len;
char *out = malloc(outlen + 1);
int pos;
for (i = 0, pos = 0; i < len; i ++) {
if ((url[i] >= 48 && url[i] <= 57) // 0-9
|| (url[i] >= 65 && url[i] <= 90) //a-z
|| (url[i] >= 97 && url[i] <= 122) //A-Z
|| url[i] == ';' || url[i] == '/' || url[i] == '?'
|| url[i] == ':' || url[i] == '@' || url[i] == '&'
|| url[i] == '=' || url[i] == '+' || url[i] == '$'
|| url[i] == ',' || url[i] == '-' || url[i] == '_'
|| url[i] == '.' || url[i] == '!' || url[i] == '~'
|| url[i] == '*' || url[i] == '\'' || url[i] == '('
|| url[i] == ')') {
/* straight copy */
COPY_TO_ENCODE_URL(url[i]);
}
else {
#undef HEX_TO_DIGIT
char dig1 = (url[i] & 0xF0) >> 4;
char dig2 = (url[i] & 0x0F);
if (dig1 >= 0 && dig1 <= 9) dig1 += 48; //0,48inascii
if (dig1 >= 10 && dig1 <= 15) dig1 += 65 - 10; //A,65inascii
if (dig2 >= 0 && dig2 <= 9) dig2 += 48;
if (dig2 >= 10 && dig2 <= 15) dig2 += 65 - 10;
COPY_TO_ENCODE_URL('%');
COPY_TO_ENCODE_URL(dig1);
COPY_TO_ENCODE_URL(dig2);
}
}
out[pos] = '\0';
return (out);
}
/* ---------------------------------------------------------------------------
* Decode URL by converting %XX (where XX are hexadecimal digits) to the
* character it represents. Don't forget to free the return value.
*/
char *urldecode(const char *url)
{
size_t i, len = strlen(url);
char *out = malloc(len + 1);
int pos;
for (i = 0, pos = 0; i < len; i ++) {
if (url[i] == '%' && i+2 < len &&
isxdigit(url[i + 1]) && isxdigit(url[i + 2])) {
/* decode %XX */
#define HEX_TO_DIGIT(hex) ( \
((hex) >= 'A' && (hex) <= 'F') ? ((hex) - 'A' + 10): \
((hex) >= 'a' && (hex) <= 'f') ? ((hex) - 'a' + 10): \
((hex) - '0') )
out[pos ++] = HEX_TO_DIGIT(url[i + 1]) * 16 +
HEX_TO_DIGIT(url[i + 2]);
i += 2;
#undef HEX_TO_DIGIT
}
else {
/* straight copy */
out[pos ++] = url[i];
}
}
out[pos] = '\0';
return (out);
}
显示 Gitment 评论