网址URL特殊字符编码

一、URL中的特殊字符及其对应的编码

网址URL中特殊字符转义编码

字符    -    URL编码值

空格     -    %20
"          -    %22
#         -    %23
%        -    %25
&         -    %26
(          -    %28
)          -    %29
+         -    %2B
,          -    %2C
/         -    %2F
:          -    %3A
;          -    %3B
<         -    %3C
=         -    %3D
>         -    %3E
?         -    %3F
@        -    %40
\         -    %5C
|          -    %7C 

URL特殊字符转义,URL中一些字符的特殊含义,基本编码规则如下:

1、空格换成加号(+)
2、正斜杠(/)分隔目录和子目录
3、问号(?)分隔URL和查询
4、百分号(%)制定特殊字符
5、#号指定书签
6、&号分隔参数
 

如果需要在URL中用到,需要将这些特殊字符换成相应的十六进制的值
+     %2B
/      %2F
?     %3F
%    %25
#     %23
&    %26

二、为什么需要Url编码

        一样东西需要编码的原因有很多,但通常可能是Size过大,包含隐私数据等。对于Url来说要进行编码的原因是Url中有些字符会引起歧义。例如Url参数字符串中使用key=value键值对这样的形式来传参,键值对之间以&符号分隔,如“myVideo.mp4?t=5a71afc0&rlimit=3&us=72d4cd1101”(QueryString方式)。如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和= 符号进行转义,也就是对其进行编码。

http://example.vod2.myqcloud.com/dir1/dir2/myVideo.mp4?t=5a71afc0&rlimit=3&us=72d4cd1101&sign=c5214f0d5df

      又如,Url的编码格式采用的是ASCII码,而不是Unicode,这也就是说你不能在Url中包含任何非ASCII字符,例如中文。否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。

url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。

哪些字符需要编码

RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。

RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。

US-ASCII字符集中没有对应的可打印字符

Url中只允许使用可打印字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符都不能直接出现在Url中。同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,因此也不可以放在Url中。

保留字符

Url可以划分成若干个组件,协议、主机、路径等。有一些字符(:/?#[]@)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔 主机和路径,?用于分隔路径和查询参数,等等。还有一些字符(!$&'()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中 的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。

三、C++代码的实现

#include<iostream>
#include <string>
using namespace std;


static std::string UrlEncode(const std::string& in_url)
{
    const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}/,";
    const char hex[] = "0123456789ABCDEF";

    int len = in_url.size();

    std::string out_url;
    out_url.reserve(len + len);

    for (int i = 0; i < len; ++i)
    {
        char c = in_url[i];
        if (c < ' ' || c > '~' || strchr(urlunsafe, c))
        {
            out_url += '%';
            out_url += char(hex[(c >> 4) & 0x0f]);
            out_url += char(hex[c & 0x0f]);
        }
        else
        {
            out_url += c;
        }
    }
    return out_url;
}


std::string UrlDecode(const std::string& in_url)
{
    int len = in_url.size();
    std::string out_url;
    out_url.reserve(len);

    const char* p = in_url.data();
    for (int i = 0; i < len; ++i)
    {
        unsigned int tmp = 0;
        char c = in_url[i];
        if ((c == '%') && (i + 2 < len) && (sscanf(p + i + 1, "%2x", &tmp) == 1))
        {
            out_url += (char)tmp;
            i += 2;
        }
        else
        {
            out_url += c;
        }
    }
    return out_url;
}


int main(){
    std::string str;
    cout << "Please input a string:";
    cin >> str; 

    cout << "raw str is : " << str << endl;
    str = UrlEncode(str);
	cout << "do urlencode:" << str << endl;
    str = UrlDecode(str);
    cout << "do urldecode:" << str << endl;
}

效果如下:

网址URL中特殊字符转义编码_p312011150的博客-CSDN博客_url转义字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱齿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值