## URL編碼
<!-- 打開瀏覽器常常會在上面輸入網址,這個網址統稱為 URL (Uniform Resource Locator),也就是定義網頁的「位置」。
- RFC2396 定義
- Uniform
- 定義統一的格式
- Resource
- 資源,可識別的內容,包含網頁、圖片、影片、js 檔案、css 檔案
- Identifier
- 可識別的符號 -->
- URL:一種統一定義的格式,可以用來表示資源的符號
## URI 格式
* Example:https://www.mlsh.tp.edu.tw/nss/p/index
<!-- :::info
**http://username:password@hostname:9090/path?arg=value#anchor**
::: -->
```
array ( 'scheme' =>
'http', // 協定 :// 'user' => 'username', // 帳號 :
'pass' => 'password', // 密碼
'host' => 'hostname', // 伺服器位置 @
'port' => 9090, // 伺服器 port :
'path' => '/path', // 路徑 /
'query' => 'arg=value', // 查詢字串 ?
'fragment' => 'anchor', // 片段識別碼 #
);
```
編碼 vs 解碼
--------
- 編碼(Encoding):為了統一格式或收集資訊,會轉換成特定的格式
- 解碼(Decoding):還原已經被編碼過的字串,轉成原本的內容
### URL 編碼 (=百分號編碼(Percent-encoding))
- URI 有定義
- 保留字元
- 可看到 URI 格式中 ://、:、@、?、/、# 都是保留字元
- RFC 3986(section 2.2 _保留字元)_
- 未保留字元但合法
- A-Z、a-Z、0-9、-、_、.、~
- RFC 3986(section 2.3 未保留字元)
- 未保留字元(不合法):未被定義
- 使用 URL 編碼,%XX --> 16 進位
- 如:中文字
- 特殊
- 空白
- RFC 3986 URI: 「%20」
- W3C HTML 4.01 : 「+」
Content-Type: MIME類型為 application/x-www-form-urlencoded
-->
---
## Encode
```cpp=
#include <iostream>
#include <string>
std::string url_encode(const std::string& in)
{
std::string out;
for (size_t i = 0; i < in.size(); i++)
{
unsigned char c = in[i];
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
{
out += c;
} else
{
out += '%';
out += "0123456789ABCDEF"[c / 16];
out += "0123456789ABCDEF"[c % 16];
}
}
return out;
}
int main()
{
std::string input = u8"我們不會沉淪"; //這裡輸入
std::string encoded = url_encode(input);
std::cout << encoded << std::endl;
return 0;
}
```
---
## Decode
```cpp=
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
std::string urlDecode(const std::string& input)
{
std::string decoded;
for (size_t i = 0; i < input.length(); ++i)
{
if (input[i] == '%' && i + 2 < input.length())
{
char hex[3] = { input[i + 1], input[i + 2], '\0' };
char decodedChar = strtol(hex, nullptr, 16);
decoded += decodedChar;
i += 2;
}
else if (input[i] == '+')
{
decoded += ' ';
}
else
{
decoded += input[i];
}
}
return decoded;
}
int main()
{
std::string encodedUrl = "line://app/1657024923-2r46WKKN?auto=yes&type=text&text=%E6%88%91%E5%80%91%E4%B8%8D%E6%9C%83%E6%B2%89%E6%B7%AA"; //這裡輸入
std::string decodedUrl = urlDecode(encodedUrl);
std::cout << decodedUrl << std::endl;
return 0;
}
```
---