1. 空文字列
  2. 全部 ASCII 英字
  3. スペース 1 個
  4. + と = 2 個
  5. 日本語 5 文字
  6. unreserved 記号のみ
  7. 数字と記号混在
  8. URL 風
コース一覧
コンピューターサイエンス入門:理論編
URL エンコード対象文字数

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

URL エンコード対象文字数

検索語に空白や日本語を入れて URL を作ると、アドレスバーに貼った瞬間に %E3%81%AD のような文字列に化けます。壊れたのではありません。そのままでは置けない文字が、置き換えられただけです。

URL にそのまま置ける文字は、意外と少ない

URL の中では、記号の多くが区切りとしての役割を持っています。? はクエリの始まり、& は次のパラメータ、/ は階層の区切り、# はページ内の位置です。値の中にこれらが混ざると、区切りなのか中身なのかを見分けられません。

そこで、区切りに使う記号や、そもそも URL に書けない文字は、% と 16 進数 2 桁の組に置き換えます。これがパーセントエンコーディングです。そのまま置いてよいのは、RFC 3986 で unreserved と呼ばれる次の範囲だけです。

  • 英字 A-Z a-z
  • 数字 0-9
  • 記号 4 つ - _ . ~

これ以外はすべて置き換えの対象になります。空白も、+ も = も、日本語も入ります。. は記号なので対象に見えますが、この 4 つに入っているので置き換えません。逆に / は見慣れているぶん安全に見えますが、値の中では必ず置き換えが要ります。

プレーンテキスト

検索 A -> %E6%A4%9C%E7%B4%A2%20A path/to?x=1 -> path%2Fto%3Fx%3D1

日本語 1 文字が %XX 3 組に化ける

日本語は UTF-8 でバイトに直してから置き換えられるので、1 文字が %XX 3 組、9 文字ぶんに膨らみます。ここで数え方を決めておきます。今回数えるのは、%XX が何組できるかではありません。入力の中の何文字が置き換えの対象かです。日本語 1 文字は、バイトが 3 つでも 1 と数えます。

数えられると何が嬉しいのかというと、置き換えたあとの長さが先に分かることです。1 文字が 3 文字や 9 文字に膨らむので、対象の数が分かればおよその長さが読めます。URL の長さに上限のある経路へ渡す前や、書き込む先の大きさを決めるときに効いてきます。

1 文字ずつ見て、条件に合うものを数える

やることは走査と数え上げです。集合を先に作っておいて、含まれるかどうかで数を増やします。

Python

vowels = set("aeiou") count = 0 for ch in "encoding": if ch in vowels: count += 1 print(count) # 3

集合への in は、中身が増えても速さが変わりません。JavaScript なら、正規表現で範囲を書くほうが読みやすいこともあります。

JavaScript

console.log(/[a-z]/.test("A")); // false

厳密には、URL のどこに置く値かによって置き換えの要否は少し変わります。パスの途中なのか、クエリの値なのかで、そのまま置ける記号が違うためです。今回はそこを単純にして、unreserved 以外はすべて対象、と決めて数えます。

文字列を回すときは for...of を使います。添字で回すと、絵文字のように内部で 2 つ分の場所を使う文字が 2 文字として数えられてしまいます。for...of は文字の単位で進むので、この食い違いが起きません。

要件

  1. A-Z a-z 0-9 - _ . ~ を安全文字 (unreserved) とみなす
  2. それ以外の文字をエンコード対象として数え、整数を返す
  3. 日本語などの非 ASCII 文字は 1 文字として数える

入出力例

urlEncodeCount("") → 0 urlEncodeCount("hello") → 0 urlEncodeCount("hello world") → 1 urlEncodeCount("a+b=c") → 2 urlEncodeCount("こんにちは") → 5 urlEncodeCount("a-b_c.d~e") → 0 urlEncodeCount("1+1=2") → 2 urlEncodeCount("page?q=hi#top") → 3

ヒント

Python なら set を使うと判定が O(1)

JavaScript なら正規表現 /[A-Za-z0-9\-_.~]/ を 1 文字ずつテスト

for...of で回すと絵文字や日本語もコードポイント単位で扱える

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • IPv4 アドレスを 32bit 整数に変換

    192.168.1.1 のような IPv4 アドレスを 32bit の整数に変換する関数を作ります。

  • 32bit 整数を IPv4 アドレスに変換

    32bit の整数を 192.168.1.1 のような IPv4 文字列に戻す関数を実装します。前レッスンの逆操作です。

  • CIDR プレフィックスからネットマスクを作る

    /24 のような CIDR プレフィックスから、対応する 32bit のネットマスク (上位 prefix bit が 1) を返します。

  • 単純チェックサム

    バイト配列の各要素を 256 (1 バイト) の範囲で足し合わせ、単純なチェックサムを計算します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • URLページの住所全体
  • 階層ネットワークを役割ごとに積み重ねた構造
  • JavaScriptWeb で動的な振る舞いを担う言語
main.py
学習モード
エディタを読み込んでいます

メモ

URL エンコード対象文字数

⌘S で保存