【C++】URLエンコードを行う
過去の記事(1,2)
でlibcurlを用いたHTTPリクエストをやったけど、GETやらPOSTやらで送信したパラメータは全て半角英数字であった。
しかし、実際にはアルファベットだけでなく日本語や、文字にはならないバイナリデータなども送ることは多い。
このとき、URLに使える文字は半角英数字と一部の記号に限られているので、GET,POST(x-www-form-urlencoded形式)のパラメータに全角など使えない文字が
含まれる場合にはエスケープによるエンコードを行う必要がある。
といっても大したことでは無くて、A-Z,a-z,0-9,/,+
の文字についてはそのまま、
それ以外の文字については1byte毎に%記号に続けて16進数表記で書けばよい。
というわけで、単純に文字列1つエンコードするなら以下のようになる。
プログラム
//urlencode1.cpp
#include<iostream>
#include<string>
std::string urlEncode(const std::string& str){
std::ostringstream oss;
for(char ch : str){
if(
(ch>='A' && ch<='Z')||
(ch>='a' && ch<='z')||
(ch>='0' && ch<='9')||
ch=='-' || ch=='~' ||
ch=='_' || ch=='.'
){
oss << ch;
}else{
char buf[3]={0};
sprintf(buf,"%02x",uint8_t(ch));
oss << '%' << std::string(buf);
}
}
return oss.str();
}
int main(){
std::string str="あいうえお";
for(char b : str){
printf("%02x ",(uint8_t)b);
}
std::cout << std::endl;
auto result=urlEncode(str);
std::cout << result << std::endl;
return 0;
}
実行結果
e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a
%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a
実際にリクエストを送る際にはたった1つの文字列ではなくて、
"パラメータ名=値"を&で繋いだものを送ることが多い。
そこで、パラメータ名と値の連想配列(std::unordered_map<std::string,std::string>
)を引数にしてURLエンコードされた文字列を返す関数も作る。
プログラム
//urlencode2.cpp
#include<iostream>
#include<string>
#include<unordered_map>
using Params=std::unordered_map<std::string,std::string>;
std::string urlEncode(const std::string& str){
//省略
}
std::string urlEncode(const Params& data){
std::ostringstream oss;
for(auto it=data.begin(); it!=data.end(); it++){
if(it!=data.begin()){
oss << "&";
}
oss << urlEncode(it->first)
<< '='
<< urlEncode(it->second);
}
return oss.str();
}
int main(){
Params params;
params["name"]="山田太郎";
params["age"]="20";
auto result1=urlEncode(params);
auto result2=urlEncode({
{"menu","味噌ラーメン"},
{"price","780円"}
});
std::cout << result1 << std::endl;
std::cout << result2 << std::endl;
return 0;
}
実行結果
age=20&name=%e5%b1%b1%e7%94%b0%e5%a4%aa%e9%83%8e
price=780%e5%86%86&menu=%e5%91%b3%e5%99%8c%e3%83%a9%e3%83%bc%e3%83%a1%e3%83%b3
パラメータの順番が追加した順番と異なっているけど、何か問題が生じるかといったら自分には特に思いつかない。
#C++
投稿日時 : 2022/03/04 00:20