<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" >
  <channel>
  <title>プログラミングの練習</title>
  <link>http://struts123etc.blog.shinobi.jp/</link>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://struts123etc.blog.shinobi.jp/RSS/" />
  <description>プログラミングの問題やプログラミング関連知識、ソフトウェアのテストについてのブログです</description>
  <lastBuildDate>Wed, 23 Sep 2026 10:48:33 GMT</lastBuildDate>
  <language>ja</language>
  <copyright>© Ninja Tools Inc.</copyright>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" />

    <item>
    <title>【PicoCTF】WebインスペクターとBase64解読で隠し要素を暴く！「WebDecode」攻略アプローチ</title>
    <description>
    <![CDATA[<br />
<br />
<p>今回は、Webアプリケーションの構造調査とクライアント側のデータ隠蔽の仕組みを学ぶWeb Exploitationの入門問題<b>「WebDecode」</b>に挑戦しました！</p><br />
<p>ブラウザの開発者ツール（Webインスペクター）を駆使してページを構成するファイル群を走査し、HTML内に隠された難読化データを見つけ出して復元するまでのアプローチをまとめました。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 開発者ツールによるファイルとソースの調査</span></h3><p>Webアプリケーションの構造を理解するため、ブラウザの標準機能である「Webインスペクター（開発者ツール）」を活用します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>リンクや関連ファイルの走査：</b> トップページだけでなく、サイト内に含まれる別のページ（例: <code>about.html</code> など）のソースコードや、構造を構成するファイルをくまなく確認。<br />
<br />
<br />
・<b>カスタム属性の発見：</b> <code>about.html</code> のソースコード内にあるセクションタグを調査したところ、通常の表示テキストとは別に <code>notify_true="..."</code> という怪しいカスタム属性が埋め込まれていることが判明。</li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. Base64エンコード文字列の識別と特徴</span></h3><p>発見した属性値には、英数字と記号で構成された独特の文字列が設定されていました。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">エンコード方式の推測</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
文字列例: <code>cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfZjZmNmI3OGF9</code><br />
<br />
<br />
・<b>特徴の把握：</b> 大文字・小文字・数字が綺麗に並んでおり、記号の少なさと全体的な雰囲気から「Base64エンコード」であると仮説を立てる。</div></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. ターミナルを用いたBase64のデコード</span></h3><p>特定したBase64文字列を、Linux環境のコマンドラインツールを使ってデコードし、本来の文字列を復元します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">デコードの実行</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>echo "cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfZjZmNmI3OGF9" | base64 -d</code><br />
<br />
<br />
<code>base64 -d</code> コマンドにより、隠されていた機密情報を正確に抽出し、目的のテキストを取得することに成功。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【実務的な教訓】</b><br />
Webブラウザに読み込まれるフロントエンドのデータ（HTML、CSS、JSなど）は、ユーザーが開発者ツール等で自由に閲覧・改変できるという前提（"Client-side is not trustable"）があります。実務のセキュリティ診断や開発においても、機密情報をフロントエンドのコードや属性にハードコードしない設計の重要性を再認識する良い機会となりました。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・Webインスペクターを活用した、HTML・関連ファイル・カスタム属性の体系的な走査<br />
<br />
<br />
・Base64エンコード特有の文字列フォーマットの識別と切り分け<br />
<br />
<br />
・Linuxの <code>base64 -d</code> コマンドによるスムーズな復元手法の確立</li></ul><p>フロントエンドの仕組みとクライアント側の検証手法を基礎から学べる素晴らしい問題でした。このアプローチを活かして、次のWeb問題もロジカルに攻略していきたいと思います！<br />
<br />
<br />
</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/38/</link>
    <pubDate>Wed, 23 Sep 2026 10:48:33 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/38</guid>
  </item>
    <item>
    <title>【PicoCTF】sudoの特権昇格を見抜け！「SUDO MAKE ME A SANDWICH」の攻略アプローチ</title>
    <description>
    <![CDATA[<p>今回は、Linuxのアクセス権限と特権昇格（sudo）の仕組みが問われる問題<b>「SUDO MAKE ME A SANDWICH」</b>に挑戦しました！</p><br />
<p>一般ユーザーではアクセスできない保護されたファイルに対し、システムに許可された正当な権限（sudo設定）をどのように探し出し、アクセス権を突破したのか。そのアプローチとコマンドラインの操作手順をまとめておきます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 現状の調査とパーミッションの確認</span></h3><p>まずはリモート環境にログインし、自分自身のユーザー権限と、ターゲットとなるファイルの属性を調査します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>ユーザー権限の確認（<code>id</code>）：</b> 現在のセッションが特権を持たない一般ユーザー（例: <code>ctf-player</code>）であることを確認。<br />
<br />
<br />
・<b>ファイルのパーミッション確認（<code>ls -l</code>）：</b> ホームディレクトリにあるターゲットファイル（<code>flag.txt</code>）を確認すると、オーナーである <code>root</code> 以外からのアクセスが一切拒否（<code>-r--r-----</code>）されていることが判明。</li></ul><p>一般ユーザーの権限のままでは直接中身を読むことができないため、システム上で許可された特権昇格のパスを探す必要が生じます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. <code>sudo -l</code> による実行可能コマンドの特定</span></h3><p>Linux環境において、現在のアカウントに許可されている `sudo` 権限を調べるためには以下のコマンドを使用します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">特権リストの照会</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>sudo -l</code><br />
<br />
<br />
出力結果を確認すると、パスワードの入力を必要とせず（<code>NOPASSWD</code>）、最高権限（<code>ALL</code>）で特定のプログラム（例: <code>/bin/emacs</code>）を実行できる設定が組み込まれていることが分かります。</div></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. 許可されたツールを用いたファイルの安全な閲覧</span></h3><p>許可されたパスのプログラムを <code>sudo</code> 経由で呼び出すことで、root権限でファイルを直接読み込みます。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">root権限でのエディタ起動</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>sudo /bin/emacs flag.txt</code><br />
<br />
<br />
システム管理者が許可した正規のコマンドルートを通り、root権限でテキストエディタを起動してターゲットファイルをオープンします。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【ポイント】</b><br />
「システム上の権限設定（sudoers）を読み解き、許可されたバイナリを通じて制限されたデータにアクセスする」というアプローチは、脆弱性診断やペネトレーションテストにおいて基本かつ非常に重要なスキルです。パーミッションと設定の不備（あるいは意図された許可設定）がいかにシステム挙動に影響するかを学ぶ好例となりました。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<code>id</code> および <code>ls -l</code> による環境の初期偵察と、アクセス制御の仕組みの把握<br />
<br />
<br />
・<code>sudo -l</code> を用いた、一般ユーザーに許可されている特権コマンドの精査<br />
<br />
<br />
・許可されたプログラムパスを正確に指定したroot権限でのファイルオープン手法の確立</li></ul><p>Linuxの権限周りの仕組みを体系的に実感できる素晴らしい問題でした。次回のチャレンジも、一歩ずつロジカルに攻略していきたいと思います！<br />
<br />
<br />
</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/37/</link>
    <pubDate>Wed, 23 Sep 2026 10:27:45 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/37</guid>
  </item>
    <item>
    <title>【PicoCTF】分割ファイルを復元せよ！「Piece by Piece」のファイル結合とアーカイブ抽出アプローチ</title>
    <description>
    <![CDATA[<br />
<br />
<p>前回に続き、愛用のM3 MacBook Airのターミナルを相棒に、CyLab Security Academy（旧PicoCTF）のカテゴリにある問題<b>「Piece by Piece」</b>に挑戦しました！</p><br />
<p>今回のテーマは、リモートサーバー上に散らばった複数のファイルパーツを回収し、正しく結合・解凍して中身を暴く<b>「Linuxのファイル操作とアーカイブの復元」</b>です。どのようなコマンドを組み立てて解決に至ったのか、そのアプローチをまとめておきます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 「Piece by Piece」とはどんな問題？</span></h3><p>指定されたホストとポートへSSHでリモート接続し、ログイン後のホームディレクトリを確認します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>接続方法：</b> SSHを用いた非標準ポートへのリモートログイン<br />
<br />
<br />
・<b>確認されたファイル：</b> ホームディレクトリには、実行手順が書かれた指示書（<code>instructions.txt</code>）と、アルファベット順に分割された複数のファイルパーツ（<code>part_aa</code> 〜 <code>part_ae</code>）が配置されていました。</li></ul><p>指示書（<code>instructions.txt</code>）のヒントを読むと、「ファイルは複数のパーツに分割されたZIPファイルであること」「指定されたパスワードを用いて解凍する必要があること」が示されており、ここから具体的なコマンド操作の組み立てに入ります。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 2ステップで進めるファイル復元プロセス</span></h3><p>ターミナルから標準コマンドを組み合わせて、断片化したデータを1つのアーカイブとして復元・抽出します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">1. 分割ファイルの結合（Concatenation）</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>cat part_aa part_ab part_ac part_ad part_ae &gt; archive.zip</code><br />
<br />
<br />
<code>cat</code>コマンドと標準出力のリダイレクト（<code>&gt;</code>）を使い、順序通りに並んだ複数のパーツファイルを1つのZIPアーカイブファイルへと完全に結合します。</div></li><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">2. パスワード保護されたアーカイブの解凍</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>unzip archive.zip</code><br />
<br />
<br />
指示書で指定された保護パスワードを入力し、結合して復元したZIPファイルを解凍。内部に封入されていたターゲットファイルを抽出します。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【ポイント】</b><br />
「分割されたデータの構造を正しく理解し、適切な順序で結合して復元する」というプロセスは、データリカバリやインシデント調査（フォレンジック）の現場でも求められる極めて実用的なスキルです。地味ながらLinuxの基本コマンドの応用力が試される好例ですね！</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・「Piece by Piece」は、リモートサーバー上の断片化したファイル群を<code>cat</code>コマンドの連結によって1つのアーカイブへ復元する手法を学ぶ問題<br />
<br />
<br />
・パスワード付きアーカイブに対する適切な解凍アプローチにより、隠されたターゲットファイルを抽出<br />
<br />
<br />
・CUI環境でのファイル結合やアーカイブ操作など、エンジニアの基礎体力となる必須の操作手順を確認</li></ul><p>ターミナル上での直感的なファイル操作と、ヒントから正解のコマンドを組み立てていくプロセスは非常に爽快です。次回のチャレンジもコマンドラインを駆使して華麗に攻略していきたいと思います！</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/36/</link>
    <pubDate>Wed, 23 Sep 2026 10:11:47 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/36</guid>
  </item>
    <item>
    <title>【リファクタリング入門】Code Smell（コードの臭い）とは？代表例7選と危険なコードの見分け方</title>
    <description>
    <![CDATA[<p>プログラムが「一応動く」状態であっても、内部構造に問題を抱えていることがあります。そのような<b>将来的にバグや不具合の原因となり得るコードの不吉な兆候</b>を<b>「Code Smell（コードの臭い）」</b>と呼びます。<br />
<br />
今回は代表的な Code Smell の例と、それを解消するための考え方を解説します。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #d13438; padding-left: 10px; color: #d13438;">1. Code Smell（コードの臭い）とは？</span></h3><p>Code Smell とは、直ちにエラーになるわけではないものの、<b>「可読性の低下」「修正のしづらさ（保守性の悪化）」「バグの温床」</b>につながるコード設計上の警告サインです。<br />
<br />
早期に察知してリファクタリング（内部構造の改善）を行うことが、健全なソフトウェア開発を保つキーとなります。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 代表的な Code Smell の例（7選）</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fde8e8; border-left: 4px solid #d13438; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d13438; font-size: 1.05em;">① コードの重複（Duplicated Code）</b><br />
<br />
<b>【解説】</b>同じ処理やよく似た記述が複数の場所にコピペされている状態。<br />
<br />
<b>【リスク】</b>仕様変更があった際に修正漏れが発生し、バグの原因になります。<br />
<br />
<b>【改善案】</b>共通処理をメソッドやクラスへ抽出・共通化（DRY原則の適用）します。</li><li style="background-color: #fde8e8; border-left: 4px solid #d13438; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d13438; font-size: 1.05em;">② 長いクラス（Large Class / God Class）</b><br />
<br />
<b>【解説】</b>1つのクラスに大量のフィールドやメソッドが詰め込まれ、膨大な行数になっている状態。<br />
<br />
<b>【リスク】</b>クラスの全容を把握するのが困難になり、影響範囲の特定が難しくなります。<br />
<br />
<b>【改善案】</b>関連する機能ごとにクラスを分割・抽出します。</li><li style="background-color: #fde8e8; border-left: 4px solid #d13438; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d13438; font-size: 1.05em;">③ 長いメソッド（Long Method）</b><br />
<br />
<b>【解説】</b>1つの関数やメソッドの中に何百行もの処理が詰め込まれている状態。<br />
<br />
<b>【リスク】</b>「このメソッドが何をしているか」を一目で理解できず、テストも書きづらくなります。<br />
<br />
<b>【改善案】</b>処理のまとまりごとに小さなメソッドへ分割（関数の抽出）します。</li><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d76d00; font-size: 1.05em;">④ 不適切なコメント（Bad Comments）</b><br />
<br />
<b>【解説】</b>「コードを見ればわかること」をそのまま書いた冗長なコメントや、古い仕様のまま残された嘘のコメント。<br />
<br />
<b>【リスク】</b>コードの変更に伴いコメントが陳腐化し、読み手を混乱させます。<br />
<br />
<b>【改善案】</b>「何をしているか（How）」ではなく「なぜそうしたか（Why）」を書き、コード自体を自己説明的に修正します。</li><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d76d00; font-size: 1.05em;">⑤ 単一責務違反（Single Responsibility Principle Violation）</b><br />
<br />
<b>【解説】</b>1つのクラスやメソッドが複数の異なる役割（例：データ取得・計算・ファイル保存など）を兼ね備えている状態。<br />
<br />
<b>【リスク】</b>一部の修正がまったく無関係な機能に影響を与えてしまいます。<br />
<br />
<b>【改善案】</b>SOLID原則の「単一責任の原則（SRP）」に従い、1つのコンポーネントには「変更する理由が1つだけ」になるよう分割します。</li><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">⑥ 複雑な判定条件（Complex Conditional Logic）</b><br />
<br />
<b>【解説】</b><code>if</code> 文の条件式に <code>&amp;&amp;</code> や <code>||</code> が何重にも連なり、ネスト（深さ）が深くなっている状態。<br />
<br />
<b>【リスク】</b>どの条件で真・偽になるかの視認性が悪く、境界値の不具合が発生しやすくなります。<br />
<br />
<b>【改善案】</b>ガード節の利用、条件判定を独立したメソッドへ抽出、またはポリモーフィズムを活用します。</li><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">⑦ 不適切なネーミング（Bad Naming）</b><br />
<br />
<b>【解説】</b><code>data</code>, <code>temp</code>, <code>x</code> などの意図が不明な名前や、実際の挙動と異なる不正確な命名。<br />
<br />
<b>【リスク】</b>コードの意図を汲み取るために処理を精査する必要が生じ、解読の時間が大幅に増えます。<br />
<br />
<b>【改善案】</b>変数・関数・クラスの役割や戻り値が明確に伝わる、自己説明的な名前を付けます。</li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. 補足解説：Code Smell と上手に付き合うポイント</span></h3><div style="font-family: sans-serif; border: 1px solid #ccc; padding: 15px; background-color: #f9f9f9; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b>【Code Smell 探知の心構え】</b><br />
<br />
<br />
<br />
<span style="color: #0078d4;">■ Smell（臭い）は「バグ」そのものではない</span><br />
<br />
Code Smell があるからといって、必ずしもプログラムが間違って動いているわけではありません。しかし、そのまま放置すると将来の機能追加や変更コストが肥大化します。<br />
<br />
<br />
<br />
<span style="color: #107c41;">■ ボーイスカウト・ルールの実践</span><br />
<br />
「自分が作業する前よりも、コードを少しだけきれいにして立ち去る」というボーイスカウト・ルールを意識し、日々の開発の中で少しずつ不吉な臭いを消していくのが理想的です。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>Code Smell：</b>将来のトラブルを未然に防ぐための警告サイン。<br />
<br />
・<b>主な原因：</b>コピペによる重複、膨大すぎるクラス・メソッド、意味の不透明な命名など。<br />
<br />
・<b>対策：</b>リファクタリングを日々の開発習慣に取り入れ、可読性と保守性を高める。</li></ul><p>コードを書く際は「動くかどうか」だけでなく、「不吉な臭いがしていないか」チェックする習慣を身につけましょう！<br />
<br />
<br />
</p>]]>
    </description>
    <category>その他</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/35/</link>
    <pubDate>Mon, 21 Sep 2026 22:35:12 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/35</guid>
  </item>
    <item>
    <title>【プログラミング基礎】アルゴリズム表現の共通言語「疑似コード（Pseudocode）」の読み方・書き方ガイド</title>
    <description>
    <![CDATA[<p>アルゴリズムの解説書や基本情報技術者試験などでよく使われる<b>「疑似コード（Pseudocode）」</b>の書き方・読み方の基本ガイドです。<br />
<br />
特定のプログラミング言語に依存せず、処理のロジックを直感的に表現するための共通文法を分かりやすくまとめました。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 入出力と関数の宣言</span></h3><p>アルゴリズムの前提条件（入力）と、最終的に得られる結果（出力）を明記するための記述です。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">Input / Output / return</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
Input: 〇〇 &nbsp;&nbsp;&nbsp;&nbsp;// 入力や関数の引数などを記述<br />
<br />
Output: 〇〇 &nbsp;&nbsp;&nbsp;// 出力や関数の返り値を記述<br />
<br />
<br />
<br />
return 値 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 関数の返り値として、値を返す</div></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 制御構造（繰り返し・条件分岐）</span></h3><p>処理の流れ（ループや分岐）を構造化して表現します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #eef9f2; border-left: 4px solid #107c41; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #107c41; font-size: 1.05em;">① for文（指定回数の繰り返し）</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
for 変数 = 値1 to 値2 do<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;処理<br />
<br />
end for</div><span style="font-size: 0.9em; color: #555; display: block; margin-top: 6px;">変数の値を「値1」から「値2」まで、1ずつ増やしながら処理を実行します。</span></li><li style="background-color: #eef9f2; border-left: 4px solid #107c41; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #107c41; font-size: 1.05em;">② while文（条件を満たす間の繰り返し）</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
while 条件 do<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;処理<br />
<br />
end while</div><span style="font-size: 0.9em; color: #555; display: block; margin-top: 6px;">条件が「真（True）」の間、処理を実行し続けます。</span></li><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">③ if文（条件分岐）</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
if 条件 then<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;処理1<br />
<br />
else<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;処理2<br />
<br />
end if</div><span style="font-size: 0.9em; color: #555; display: block; margin-top: 6px;">条件が真ならば「処理1」を、偽（False）ならば「処理2」を実行します。</span></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. 演算子とデータ構造</span></h3><p>代入、比較、論理演算、および配列の参照方法です。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d76d00; font-size: 1.05em;">代入・比較・論理演算・配列</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<b># 代入演算</b><br />
<br />
変数 = 値 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 変数に値を代入<br />
<br />
<br />
<br />
<b># 比較演算</b><br />
<br />
値1 == 値2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 値1と値2が等しければ真、異なれば偽<br />
<br />
値1 != 値2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 値1と値2が等しくなければ真、等しければ偽<br />
<br />
<br />
<br />
<b># 論理演算</b><br />
<br />
条件1 and 条件2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 条件1と条件2がともに真のとき真（AND）<br />
<br />
条件1 or 条件2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 条件1または条件2のいずれかが真のとき真（OR）<br />
<br />
<br />
<br />
<b># 配列構造</b><br />
<br />
配列名[添字] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 配列の指定された添字（インデックス）番目の要素を参照</div></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. 補足：疑似コードを実際のプログラムに落とし込む例</span></h3><div style="font-family: sans-serif; border: 1px solid #ccc; padding: 15px; background-color: #f9f9f9; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b>【疑似コードを使ったアルゴリズム例（配列の合計値を求める）】</b><br />
<br />
文法例を組み合わせて作成したサンプル疑似コードです。<br />
<br />
<br />
<div style="font-family: monospace; border: 1px solid #ccc; padding: 8px 12px; background-color: #ffffff; margin-top: 6px; border-radius: 4px;"><br />
Input: 配列 A, 要素数 N<br />
<br />
Output: 合計値 total<br />
<br />
<br />
<br />
total = 0<br />
<br />
for i = 0 to N - 1 do<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;total = total + A[i]<br />
<br />
end for<br />
<br />
return total</div><br />
<br />
<span style="color: #0078d4;">■ 疑似コードを使うメリット</span><br />
<br />
Python、Java、C言語など、言語ごとに異なる文法差異を気にせず、<b>「アルゴリズムの本質的なロジック（解法手順）」だけに集中して設計・共有できる</b>のが最大の強みです。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">5. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>基本構文：</b><code>for</code> / <code>while</code> による繰り返しと <code>if ... else</code> による条件分岐を明示する。<br />
<br />
・<b>終了タグ：</b><code>end for</code> や <code>end if</code> でスコープの終わりを明確にする。<br />
<br />
・<b>演算と参照：</b><code>==</code> や <code>!=</code> で比較し、<code>配列名[添字]</code> で要素を取り出す。</li></ul><p>アルゴリズムを学ぶ際やアイデアをコードに落とし込む前の整理に、ぜひ疑似コードを活用してみましょう！<br />
<br />
<br />
</p>]]>
    </description>
    <category>その他</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/34/</link>
    <pubDate>Mon, 21 Sep 2026 22:05:30 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/34</guid>
  </item>
    <item>
    <title>【プログラミング基礎】アルゴリズムの考え方｜「総当たり」と「近似アルゴリズム（ヒューリスティクス）」の違いを徹底解説</title>
    <description>
    <![CDATA[<p>プログラムで問題を解決する際、状況や規模に応じて適切な<b>「アルゴリズムのアプローチ（考え方）」</b>を選ぶことが非常に重要です。<br />
<br />
今回は、すべてのパターンを検証する<b>「総当たりアルゴリズム」</b>と、現実的な時間で実用的な解を見つける<b>「近似アルゴリズム（精度保証・ヒューリスティクス）」</b>について、具体例を交えて解説します。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 総当たりアルゴリズム（Brute Force Algorithm）</span></h3><p>考えられる<b>すべての条件や組み合わせを順番に試し、確実に正解を導き出す</b>最もシンプルで確実な手法です。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">特徴とメリット・デメリット</b><br />
<br />
・<b>解の確実性：</b>すべての可能性を検証するため、解が存在すれば必ず正解（最適解）を見つけられます。<br />
<br />
・<b>計算量の問題：</b>データ数や組み合わせが増えると計算時間が爆発的（指数関数的）に増加します。</li></ul><div style="font-family: monospace; border: 1px solid #b7e1cd; padding: 12px 15px; background-color: #eef9f2; margin: 12px 0; border-radius: 4px; color: #333; line-height: 1.6;"><br />
<b>【総当たりの具体例：4桁のダイヤルロック解除】</b><br />
<br />
0000、0001、0002 &hellip;&hellip; 9999 まで、最大 10,000 通りを順番にすべて試せば必ず開きます。<br />
<br />
しかし、これが桁数の多いパスワードや都市を巡るルート選択になると、計算に何年・何百年もかかるようになります。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 近似アルゴリズム（Approximation Algorithm）</span></h3><p>すべての組み合わせを試すと途方もない時間がかかる問題に対し、<b>「100%の最適解ではなく、十分に満足できる&ldquo;正解に近い解&rdquo;を素早く探す」</b>手法です。</p><br />
<p>近似アルゴリズムは、精度の保証があるかどうかで大きく2つに分類されます。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #eef9f2; border-left: 4px solid #107c41; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #107c41; font-size: 1.05em;">① 精度保証付きアルゴリズム</b><br />
<br />
・得られる解が<b>「理論上の本当の正解からどのくらいの誤差（例：真の最適解の1.5倍以内など）におさまっているか」</b>が数学的に証明・保証されている手法です。<br />
<br />
・品質の一定ラインを絶対に確保したい重要な計算システムなどで利用されます。</li><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d76d00; font-size: 1.05em;">② 発見的手法（ヒューリスティック / Heuristics）</b><br />
<br />
・数学的な精度保証はないものの、<b>「経験則」や「直感的なルール」</b>に基づいて現実的な時間内でそこそこ良い解を導き出す手法です。<br />
<br />
・遺伝的アルゴリズムや貪欲法（Greedy Algorithm）などが代表例です。AIやゲームの思考ルーチン、配送ルートの最適化などで広く活用されています。</li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. 補足解説：NP困難問題と現実的なアプローチ</span></h3><div style="font-family: sans-serif; border: 1px solid #ccc; padding: 15px; background-color: #f9f9f9; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b>【なぜ「妥協のアルゴリズム」が必要なのか？】</b><br />
<br />
<br />
<br />
<span style="color: #0078d4;">■ 組み合わせ爆発（巡回セールスマン問題の例）</span><br />
<br />
「複数の都市を最も短い距離で一度ずつ巡って戻ってくるルート」を探す問題（巡回セールスマン問題）では、都市が30個になるだけでルートの組み合わせは $10^{32}$ を超え、最新のスーパーコンピュータで総当たりしても宇宙の年齢以上の時間がかかります。<br />
<br />
<br />
<br />
<span style="color: #107c41;">■ 現代プログラミングでの使い分け</span><br />
<br />
このように厳密な正解を求めることが現実的に不可能な問題（NP困難問題など）に対して、<b>「数分〜数秒で95点の解を出す」</b>ために近似アルゴリズムやヒューリスティクスが活躍します。<br />
<br />
<br />
<br />
プログラミングでは、常に100点満点の厳密解を目指すのではなく、<b>問題の規模や制限時間（レスポンス速度）に応じてアルゴリズムを使い分ける思考</b>が重要です。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>総当たりアルゴリズム：</b>全パターン検証。確実に正解が出るが、要素が増えると時間がかかりすぎる。<br />
<br />
・<b>精度保証付きアルゴリズム：</b>正解に近い解を求め、誤差の範囲が理論的に証明されている。<br />
<br />
・<b>ヒューリスティック（発見的手法）：</b>精度保証はないが、経験則を用いて高速に実用的な「良い解」を見つける。</li></ul><p>アルゴリズムの基礎知識として、「厳密さ（確実性）」と「計算スピード（実用性）」のトレードオフの関係を理解しておきましょう！<br />
<br />
<br />
</p>]]>
    </description>
    <category>その他</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/33/</link>
    <pubDate>Mon, 21 Sep 2026 12:49:42 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/33</guid>
  </item>
    <item>
    <title>【Javaで学ぶアルゴリズム】ユークリッドの互除法で最大公約数（GCD）を求める｜自作ロジックとBigInteger活用</title>
    <description>
    <![CDATA[<p>取り上げるテーマは、紀元前から伝わる世界最古のアルゴリズムの一つ<b>「ユークリッドの互除法」</b>です。<br />
<br />
アルゴリズムの基本概念からJavaでの自作実装、さらには実務で役立つJava標準ライブラリ（<code>BigInteger</code>）を使った一発解決法まで詳しく解説します。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. ユークリッドの互除法とは？</span></h3><p>2つの整数の<b>最大公約数（GCD: Greatest Common Divisor）</b>を効率よく見つけるための定番手法です。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">アルゴリズムの定理</b><br />
<br />
2つの整数 $X, Y$ ($X \ge Y$) について、<br />
<br />
<b>「$X$ を $Y$ で割った余りを $R$ とすると、$X$ と $Y$ の最大公約数は、$Y$ と $R$ の最大公約数に等しい」</b><br />
<br />
<br />
<br />
この性質を利用し、<b>余り $R$ が 0 になるまで計算を繰り返す</b>ことで、どんなに大きな数字同士でもすばやく最大公約数を導き出すことができます。</li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. Javaでの実装例（自作ロジック）</span></h3><p>まずは、アルゴリズムの仕組みを理解するために <code>while</code> 文を使って自作してみましょう。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #0078d4; font-size: 1.05em;">サンプルコード（GCDSample.java）</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
public class GCDSample {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int x = 1071;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int y = 1029;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int result = getGcd(x, y);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(x + " と " + y + " の最大公約数は " + result + " です。");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;// 最大公約数を求めるメソッド<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static int getGcd(int x, int y) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// R = 0 となるまで、YとRを変えながらループ<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (y != 0) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int r = x % y; // 剰余Rを求める<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = y; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 次の計算のためにYをXに代入<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = r; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 次の計算のためにRをYに代入<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return x; // 余りが0になった時の除数が最大公約数<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</div></li></ul><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. アルゴリズムの挙動を追う</span></h3><p>$X = 1071, Y = 1029$ の場合の計算推移をシミュレーションしてみます。</p><div style="font-family: monospace; border: 1px solid #b7e1cd; padding: 12px 15px; background-color: #eef9f2; margin: 12px 0; border-radius: 4px; color: #333; line-height: 1.6;"><br />
1071 &divide; 1029 = 1 余り <b>42</b><br />
<br />
1029 &divide; 42 = 24 余り <b>21</b><br />
<br />
42 &divide; 21 = 2 余り <b>0</b><br />
<br />
<br />
<br />
$\rightarrow$ 余りが 0 になったため、その時の除数 <b>21</b> が最大公約数！</div><p>桁数の大きな数字同士であっても、驚くほど少ないループ回数で答えに辿り着くことができます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">4. 【必見】Java標準ライブラリで一発解決！</span></h3><p>アルゴリズムの自作ロジックを理解した上で押さえておきたいのが、Java標準ライブラリ <b><code>java.math.BigInteger</code></b> の存在です。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
<b style="color: #d76d00; font-size: 1.05em;">BigInteger.gcd() を使った実装例</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
import java.math.BigInteger;<br />
<br />
<br />
<br />
public class GCDMain {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// valueOfを使用してBigIntegerインスタンスを作成<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BigInteger b1 = BigInteger.valueOf(1071);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BigInteger b2 = BigInteger.valueOf(1029);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// gcdメソッドを呼び出すだけ<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BigInteger gcd = b1.gcd(b2);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("最大公約数は: " + gcd); // 実行結果: 21<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ccc; padding: 15px; background-color: #f9f9f9; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b>【解説と補足ポイント：なぜ標準機能を知っておくべきなのか】</b><br />
<br />
<br />
<br />
<span style="color: #0078d4;">■ 1. 正確性と桁数上限の克服</span><br />
<br />
<code>long</code> 型の範囲を超えるような極めて巨大な数値同士の計算でも、オーバーフローを起こさずに安全に処理できます。<br />
<br />
<br />
<br />
<span style="color: #107c41;">■ 2. 堅牢性と最適化</span><br />
<br />
内部で最適化されたアルゴリズムが採用されており、パフォーマンス・信頼性ともに非常に高く設計されています。<br />
<br />
<br />
<br />
<span style="color: #d76d00;">■ 3. 実務における「車輪の再発明」の防止</span><br />
<br />
基本ロジックを理解した上で、実務開発では実績のある標準ライブラリを賢く活用するのがプロエンジニアのベストプラクティスです。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><br />
<h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">5. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>基本：</b>「$X \div Y$ の余り」を次の除数にするループを回して最大公約数（GCD）を求める。<br />
<br />
・<b>応用：</b>最大公約数（GCD）がわかれば、最小公倍数（LCM）は $(X \times Y) \div \text{GCD}$ で計算可能。<br />
<br />
・<b>Javaの実務テクニック：</b><code>BigInteger.gcd()</code> を使えば1行で確実に実装可能。</li></ul><p>アルゴリズムの仕組みを知ることはプログラミングの<b>「思考力」</b>を鍛え、便利な標準機能を知ることは<b>「生産性」</b>を高めてくれます。両方のアプローチをバランスよく身につけていきましょう！<br />
<br />
<br />
</p>]]>
    </description>
    <category>Java</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/32/</link>
    <pubDate>Mon, 21 Sep 2026 12:39:54 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/32</guid>
  </item>
    <item>
    <title>【PicoCTF】単層パーセプトロンの限界を暴け！「Perceptron Train XOR」の数理検証アプローチ</title>
    <description>
    <![CDATA[<p>CyLab Security Academy（旧PicoCTF）の「AI」カテゴリにある問題<b>「Perceptron Train XOR」</b>に挑戦しました！</p><br />
<p>今回のテーマは機械学習の基礎である<b>「単層パーセプトロンの学習限界」</b>。非線形なXORデータに対し、重みの更新ルールがどう働き、どこで頭打ちになるのかを実際にパラメータを操作して検証したアプローチをまとめておきます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 「Perceptron Train XOR」とはどんな問題？</span></h3><p>問題文とルールを確認します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>カテゴリ：</b> AI / Machine Learning（難易度：Easy）<br />
<br />
<br />
・<b>問題文：</b> 「Watch a perceptron learn in real time on XOR data using the classic update rule: only misclassified points trigger updates, with no weight decay. Because XOR is not linearly separable, a single perceptron cannot hit 100% accuracy. Reach 75% accuracy to prove you understand the limitation and reveal the flag.」<br />
<br />
<br />
・<b>ヒント・制約：</b> 誤分類された点のみが重みの更新を引き起こし、重み減衰はない。XORは線形分離不可能なため単一パーセプトロンでは100%に到達せず、目標である75%の精度に到達することがクリア条件となる。</li></ul><p>XOR（排他的論理和）は直線を1本引くだけでは綺麗に分類できない<strong>「非線形分離不可能」</strong>なデータセットです。そのため、単層のパーセプトロンでは理論上100%正解することができず、4点中3点が正解となる<strong>75%の精度がモデルの限界点</strong>となります。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. パラメータの確認とトレーニングの実行プロセス</span></h3><p>ブラウザ上でインスタンスを立ち上げ、以下の手順で挙動を検証します。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">1. 学習率（Learning Rate）の設定</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
Learning rate: 0.02 (デフォルト値)<br />
<br />
<br />
初期パラメータとして設定されている学習率を確認し、モデルがどのように重みを更新していくかのベースラインを置きます。</div></li><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">2. トレーニングの実行と精度の収束確認</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
Status: Target accuracy (75%) reached.<br />
<br />
<br />
「Run training」を実行し、誤分類されたデータポイントトリガーによる重み・バイアスのリアルタイム更新を追跡。非線形分離の構造的限界により、数ステップで精度の頭打ち（75%）に到達することを確認します。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【解法のポイント】</b><br />
「アルゴリズムの数理的限界（非線形分離の不可能性）を理解しているか」がそのままクリア条件に直結している点が秀逸です。単にコードを動かすだけでなく、モデルがどこで失敗し、なぜそれ以上精度が上がらないのかという「制約のメカニズム」を把握することが本質的な攻略アプローチとなります。</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・単層パーセプトロンにおけるXOR問題の非線形分離の限界と、誤分類ベースの重み更新ルールをハンズオン形式で検証<br />
<br />
<br />
・デフォルトの学習率（0.02）を用いたトレーニングにより、理論上の限界値である75%の精度に到達することを確認<br />
<br />
<br />
・機械学習モデルの構造的制約を理論と実機の両面から理解・証明するプロセスとしての重要性</li></ul><p>インフラやWebの脆弱性だけでなく、AI・機械学習の数理モデルの制約検証まで一貫したプロセスでドキュメント化できるのは非常に価値があります。次回のチャレンジもこの検証スタイルを貫いて攻略を進めていきます！<br />
<br />
<br />
</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/31/</link>
    <pubDate>Sun, 20 Sep 2026 08:05:21 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/31</guid>
  </item>
    <item>
    <title>【PicoCTF】複数の命令で扉を開け！「ping-cmd」のコマンドインジェクションアプローチ</title>
    <description>
    <![CDATA[<p>前回に続き、愛用のM3 MacBook Airのターミナルを相棒に、CyLab Security Academy（旧PicoCTF）の「Web Exploitation」または「General Skills」カテゴリにある問題<b>「ping-cmd」</b>に挑戦しました！</p><br />
<p>今回の問題は、入力値の検証の隙を突く**「OSコマンドインジェクション」**がテーマ。どのようなヒントから脆弱性を見抜き、複数の命令を組み立てていったのか、そのアプローチをまとめておきます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. 「ping-cmd」とはどんな問題？</span></h3><p>問題文とヒントを見ると、次のように書かれています。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>カテゴリ：</b> Web Exploitation / General Skills（難易度：Easy）<br />
<br />
・<b>問題文：</b> 「Can you make the server reveal its secrets? It seems to be able to ping Google DNS, but what happens if you get a little creative with your input?（サーバーに秘密を明かさせることができますか？Google DNSにpingを飛ばせるようですが、入力をちょっと工夫するとどうなるでしょうか？）」<br />
<br />
・<b>ヒント：</b> 「OSのコマンドとして実行します」「一度に複数の命令出してみて」</li></ul><p>Netcat（<code>nc</code>）で接続する対話型インターフェースになっており、IPアドレスの入力を求められますが、制限として「8.8.8.8しか許可していない」と表示されます。しかし、ヒントにある<strong>「OSコマンドとしての実行」</strong>や<strong>「一度に複数の命令を出す」</strong>というキーワードが、今回の最大の攻略の糸口になります。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 2つのステップでコマンドインジェクションを仕掛ける</span></h3><p>M3 MacBook AirのターミナルからNetcatでサーバーに接続し、シェル文字を用いた入力の工夫を試みます。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">1. 区切り文字を用いたファイル構造の偵察</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>8.8.8.8; ls</code><br />
<br />
許可されているIPアドレスの後にセミコロン（<code>;</code>）を挟んで別のコマンドを連結し、サーバー内部のファイル一覧（<code>flag.txt</code> など）を確認します。</div></li><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">2. ターゲットファイルの読み込み</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>8.8.8.8; cat flag.txt</code><br />
<br />
同様にコマンドセパレータを活用して、見つけたフラグファイルの中身を標準出力へ強制的に吐き出させます。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【ポイント】</b><br />
「複数の命令を一度に出す」というヒント通りにコマンドの区切り文字を利用することで、制限された入力をすり抜けて任意のシステムコマンドを実行できるのが、OSコマンドインジェクションの恐ろしさであり、パズルとしての醍醐味ですね！</div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・「ping-cmd」は、入力値がそのままOSのシェルへ渡される脆弱性を突き、コマンドの連続実行によって目的を果たす問題<br />
<br />
・「一度に複数の命令を出す」というヒントから、セミコロン等の区切り文字を活用する発想が重要<br />
<br />
・問題文やヒントの行間を読み解き、想定された脆弱性アプローチを綺麗にハマらせたときの快感は格別！</li></ul><p>入力値のバリデーションの裏側にある仕組みを想像しながら、ターミナルから一撃で攻略できると本当に気持ちが良いですね。次回のチャレンジもコマンドラインを武器に華麗に攻略していきたいと思います！</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/30/</link>
    <pubDate>Sat, 19 Sep 2026 10:02:39 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/30</guid>
  </item>
    <item>
    <title>【PicoCTF】基本のワークフローで攻略せよ！「I have built my own Git server...」のadd/commit/pushアプローチ</title>
    <description>
    <![CDATA[<p>前回に続き、愛用のM3 MacBook Airのターミナルを相棒に、CyLab Security Academy（旧PicoCTF）の「General Skills（Easy）」カテゴリにある問題<b>「I have built my own Git server with my own rules!」</b>に挑戦しました！</p><br />
<p>今回の問題は、特別な裏技を使うわけではなく、<b><code>add</code>・<code>commit</code>・<code>push</code> というGitの基本ワークフロー</b>を正しく実践することの重要性が試される実践的なテーマでした。どのようなアプローチで謎を解き明かしていったのか、その手順をまとめておきます。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">1. リポジトリのクローンとREADMEの解析</span></h3><p>まずは問題文の指示通り、指定されたSSH経由でGitリポジトリをローカルへクローンします。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #f0f6ff; border-left: 4px solid #0078d4; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・<b>カテゴリ：</b> General Skills（難易度：Easy）<br />
<br />
・<b>初期調査：</b> クローンしたディレクトリを確認すると、中には <code>README.md</code> が1つだけ存在していました。</li></ul><p>その <code>README.md</code> を確認してみると、今回の謎を解く最大の鍵（ルール）が次のように記されていました。</p><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
# MyGit<br />
<br />
### If you want the flag, make sure to push the flag!<br />
<br />
Only flag.txt pushed by root:root@picoctf will be updated with the flag.<br />
<br />
GOOD LUCK!</div><p>過去のコミット履歴を探すのではなく、<b>「指定された条件を満たすファイルを自分で作り、正しい手順でコミットしてプッシュする」</b>という、Gitの基本操作がそのまま鍵になるアプローチです。</p><br />
<br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">2. 基本のワークフローによる条件のクリア</span></h3><p>サーバー側のルール（「<code>root:root@picoctf</code> による <code>flag.txt</code> のプッシュ」）をクリアするため、M3 MacBook Airのターミナル上でGitの基本操作を行います。</p><ul style="list-style: none; padding-left: 0;"><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">1. ユーザー情報の準備とコミット作成</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>git config user.name "root"</code><br />
<br />
<code>git config user.email "root@picoctf"</code><br />
<br />
<code>echo "give me flag" &gt; flag.txt</code><br />
<br />
必要な設定を整えた上で、対象となる <code>flag.txt</code> を作成します。</div></li><li style="background-color: #ffffff; border-left: 4px solid #666666; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0; border: 1px solid #e0e0e0;"><br />
<b style="color: #333333; font-size: 1.05em;">2. add / commit / push の実行</b><div style="font-family: monospace; border: 1px solid #ccc; padding: 10px; background-color: #ffffff; margin-top: 8px; border-radius: 4px; color: #333;"><br />
<code>git add flag.txt</code><br />
<br />
<code>git commit -m "Add flag.txt"</code><br />
<br />
<code>git push origin master</code><br />
<br />
お馴染みのGitワークフローに沿って、変更をステージング、コミットし、リモートサーバーへプッシュします。</div></li></ul><div style="font-family: sans-serif; border: 1px solid #ffeeba; padding: 15px; background-color: #fff9e6; font-size: 0.95em; margin: 15px 0; line-height: 1.6; border-radius: 4px;"><br />
<b style="color: #856404;">【実行結果】</b><br />
プッシュが完了すると、サーバー側の自動フックが条件の一致を検知し、コンソールに無事フラグが表示されました！<br />
<br />
<code>Here's your flag: picoCTF{1mp3rs0n4t4_g17_345y_6877715a}</code></div><br />
<hr style="border: 0; height: 2px; background: linear-gradient(to right, #0078d4, #00bcf2, #0078d4);" /><h3><span style="border-left: 5px solid #0078d4; padding-left: 10px; color: #107c41;">3. まとめ</span></h3><ul style="list-style: none; padding-left: 0;"><li style="background-color: #fff4ce; border-left: 4px solid #ff8c00; padding: 12px 15px; margin-bottom: 12px; border-radius: 0 4px 4px 0;"><br />
・「I have built my own Git server...」は、READMEの仕様を読み解き、適切なGitワークフローを実践する問題<br />
<br />
・日頃の開発でお馴染みの <code>add</code> / <code>commit</code> / <code>push</code> の基本がいかに強力かを再認識できる<br />
<br />
・仕様に沿って正しく操作を完結させ、フラグをゲットできたときの達成感は格別！</li></ul><p>基本に忠実なGit操作を積み上げることで、セキュリティ上の謎を鮮やかに解き明かせるのは本当に面白いですね。次回のチャレンジもコマンドラインを武器に華麗に攻略していきたいと思います！<br />
<br />
<br />
</p>]]>
    </description>
    <category>【PicoCTF】</category>
    <link>http://struts123etc.blog.shinobi.jp/Entry/29/</link>
    <pubDate>Sat, 19 Sep 2026 08:29:42 GMT</pubDate>
    <guid isPermaLink="false">struts123etc.blog.shinobi.jp://entry/29</guid>
  </item>

    </channel>
</rss>