C/C++对于UrlEncode的编码

x33g5p2x  于2022-03-23 转载在 其他  
字(1.9k)|赞(0)|评价(0)|浏览(597)

UrlEncode编码的实现

关于UrlEncode的实现(C++),网上有很多不同的版本,对需要编码的字符集的选取并不统一。那么到底有没有标准呢?答案是有的!

绝对不编码的,只有字母、数字、短横线(-)、下划线(_)、点(.)和波浪号(~),其他字符要视情况而定,所以一般性的urlencode只需保留上述字符不进行编码。

  • urlencode编码的工具类, urlencode是一个函数,可将字符串以URL编码,用于编码处理。
  • 函数将字符串以 URL 编码。例如空格就会变成加号。Homepage 中 form 资料传送就是用 urlencode 编码后再送出。
  • 百分号编码(Percent-encoding), 也称作URL编码(URL encoding), 是特定上下文的统一资源定位符 (URI)的编码机制. 实际上也适用于统一资源标志符(URI)的编码. 也用于为"application/x-www-form-urlencoded" MIME准备数据, 因为它用于通过HTTP的请求操作(request)提交HTML表单数据。
  • URI所允许的字符分作保留与未保留. 保留字符是那些具有特殊含义的字符. 例如, 斜线字符用于URL (或者更一般的, URI)不同部分的分界符. 未保留字符没有这些特殊含义. 百分号编码把保留字符表示为特殊字符序列. 上述情形随URI与URI的不同版本规格会有轻微的变化。

部分转换规则如下:

    1. 字母数字字符 “a” 到 “z”、“A” 到 “Z” 和 “0” 到 “9” 保持不变。
    1. 特殊字符 “.”、"-"、"*" 和 “_” 保持不变。
    1. 空格字符 " " 转换为一个加号 “+”。
    1. 所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含 3 个字符的字符串 “%xy” 表示,其中 xy 为该字节的两位十六进制表示形式。编码机制是 UTF-8。

举个例子:“中文CPU123”转化为:“%E4%B8%AD%E6%96%87CPU123”。

注意:如果是GB2312的编码方式, 中文CPU123 的转化结果将是 %d6%d0%ce%c4CPU123

urldecode采用相反规则。

下面给出实现:

unsigned char ToHex(unsigned char x) 
{ 
    return  x > 9 ? x + 55 : x + 48; 
}
 
unsigned char FromHex(unsigned char x) 
{ 
    unsigned char y;
    if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
    else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
    else if (x >= '0' && x <= '9') y = x - '0';
    else assert(0);
    return y;
}
 
std::string UrlEncode(const std::string& str)
{
    std::string strTemp = "";
    size_t length = str.length();
    for (size_t i = 0; i < length; i++)
    {
        if (isalnum((unsigned char)str[i]) || 
            (str[i] == '-') ||
            (str[i] == '_') || 
            (str[i] == '.') || 
            (str[i] == '~'))
            strTemp += str[i];
        else if (str[i] == ' ')
            strTemp += "+";
        else
        {
            strTemp += '%';
            strTemp += ToHex((unsigned char)str[i] >> 4);
            strTemp += ToHex((unsigned char)str[i] % 16);
        }
    }
    return strTemp;
}
 
std::string UrlDecode(const std::string& str)
{
    std::string strTemp = "";
    size_t length = str.length();
    for (size_t i = 0; i < length; i++)
    {
        if (str[i] == '+') strTemp += ' ';
        else if (str[i] == '%')
        {
            assert(i + 2 < length);
            unsigned char high = FromHex((unsigned char)str[++i]);
            unsigned char low = FromHex((unsigned char)str[++i]);
            strTemp += high*16 + low;
        }
        else strTemp += str[i];
    }
    return strTemp;
}

相关文章