OmniAICreator/Qiita-1.07M huggingface dataset:
セマフォを理解する

「セマフォ」は、並行処理のリソース管理や同期に使用される重要な機能の一つです。

この記事では、Rustのコードを使ってセマフォの概念、使い方、実際の応用例について解説してみます。

## セマフォとは何か

### セマフォの基本概念

セマフォは、共有リソースへのアクセスを制御するための同期プリミティブです。例えると「許可証（パーミット）」の管理システムのようなものです。リソースにアクセスするためには許可証が必要で、利用可能な許可証の数は限られています。

セマフォには以下のような特徴があります：

1. **カウンターの維持**: セマフォは内部でカウンター（許可証の数）を持っています
2. **複数アクセスの許可**: ミューテックスとは異なり、複数の同時アクセスを許可できます
3. **ブロッキング機能**: 利用可能な許可証がない場合、新たに利用可能になるまで待機します

### セマフォが解決する問題

セマフォは以下のような状況で特に有用です：

- **リソース制限**: 同時に実行できるタスクの数を制限したい場合
- **生産者-消費者パターン**: 生産されたアイテムと消費されるアイテムの同期
- **ファイルハンドルやネットワーク接続など限られたリソースの管理**
- **APIsへのリクエスト数の制限（レート制限）**

## Rustにおけるセマフォの実装

Rustでは、標準ライブラリには現在セマフォの実装が含まれていません。かつては`std::sync::Semaphore`が存在していましたが、非推奨となり削除されました。現在は主に以下のクレートでセマフォを利用することができます：

1. `tokio::sync::Semaphore` - 非同期プログラミング向けのセマフォ
2. サードパーティのセマフォ実装（`std-semaphore`や`simple-semaphore`など）

この記事では、最も広く使われている`tokio`のセマフォ実装に焦点を当てます。

## tokio::sync::Semaphoreの基本的な使い方

### セマフォのインスタンス化

まず、セマフォのインスタンスを作成します：

```rust
use tokio::sync::Semaphore;

// 3つの許可証を持つセマフォを作成
let semaphore = Semaphore::new(3);
```

この例では、最大3つのタスクが同時にリソースにアクセスできるセマフォを作成しています。

### 許可証の取得と解放

セマフォから許可証を取得するには以下の方法があります：

```rust
async fn example() {
    let semaphore = Semaphore::new(2);
    
    // 許可証を非同期に取得（利用可能になるまで待機）
    let permit = semaphore.acquire().await.unwrap();
    
    // リソースを使用...
    
    // permitがスコープを抜けると自動的に解放される
    drop(permit); // 明示的に解放することも可能
    
    // 待機せずに許可証を取得（利用可能でなければエラー）
    match semaphore.try_acquire() {
        Ok(permit) => {
            // リソースを使用...
        }
        Err(e) => {
            println!("許可証を取得できませんでした: {:?}", e);
        }
    }
}
```

### 複数の許可証の取得

単一の許可証だけでなく、複数の許可証を一度に取得することも可能です：

```rust
async fn example_multiple() {
    let semaphore = Semaphore::new(5);
    
    // 2つの許可証を一度に取得
    let permit = semaphore.acquire_many(2).await.unwrap();
    
    // 現在利用可能な許可証の数を確認
    println!("利用可能な許可証: {}", semaphore.available_permits());
    
    // permitがスコープを抜けると2つの許可証が解放される
}
```


## セマフォ使用時の注意点

セマフォの注意点：

### デッドロックの防止

セマフォを使用する際は、デッドロック（相互ロック）に注意が必要です。特に以下のような状況に気をつけましょう：

- 複数のセマフォを使用する場合は、常に同じ順序で取得する
- ミューテックス内でセマフォを待つことは、典型的なデッドロックパターンなので避ける

### メモリリーク

非同期処理では、許可証の取得を待っているタスクが何らかの理由でキャンセルされると、セマフォの状態が不整合になる可能性があります。`tokio`のセマフォはキャンセル安全に設計されています。

### 所有権に関する考慮

スレッド間でセマフォを共有する場合、`Arc`（アトミック参照カウンタ）で包む必要があります。また、許可証を別のスレッドに移動する場合は、`acquire_owned`メソッドを使用します：

```rust
let permit = Arc::clone(&semaphore).acquire_owned().await.unwrap();
tokio::spawn(async move {
    // permitを所有するタスク
    // ...
    // タスクが終了するとpermitがドロップされる
});
```

## まとめ

この記事では、Rustにおけるセマフォの基本概念、`tokio::sync::Semaphore`について解説しました。セマフォについて理解が深まれば幸いです。

## 参考リンク

- [tokio::sync::Semaphore ドキュメント](https://docs.rs/tokio/latest/tokio/sync/struct.Semaphore.html)
- [Rustの非同期プログラミングガイド](https://rust-lang.github.io/async-book/)
- [tokioプロジェクト公式サイト](https://tokio.rs/)
【CLI】awkコマンドの使い方


## スペースで区切られたファイルの 5 列目  を表示

```terminal
awk '{print $5}' path/to/file
```

## スペースで区切られたファイルの 「foo」 を含む行の 2 列目を表示

```terminal
awk '/foo/ {print $2}' path/to/file
```


## ファイル内の各行の最後の列を表示

```terminal
awk -F ',' '{print $NF}' path/to/file
```

## ファイルの最初の列の値を合計し、合計を表示

```terminal
awk '{s+=$1}. END {print s}' path/to/file
```

## 最初の行から 3 行目までを表示

```terminal
awk 'NR%3==1' path/to/file
```
Raspiにgit-flowを導入

# Raspiにgit-flowを導入

## 環境
OS : Raspberry Pi OS (32bit)


## git-flowインストール
```bash
sudo apt-get install git-flow
```

## 動作確認
適当なリポジトリをクローンした上で、下記を実行
```bash
git flow init
```
色々確認事項が出るが、特にこだわりがなければEnterを押していく

### git-flowでの初期化が出来ているかの確認
自分がdevelopブランチにいることを確認する
```bash
git branch
```
\
featureブランチの作成
```bash
git flow feature start app
```
\
featureブランチの終了
```bash
git flow feature finish branch
```

ここまで実行できていれば終了
Synology NASのバックアップファイルをAWS S3に移行した話

# Synology NASのバックアップファイルをAWS S3に移行した話【低コスト＆災害対策】

## はじめに

家庭用NASのバックアップ先として、これまでRAID1のみで冗長性を確保していましたが、  
災害（地震・火災・盗難など）リスクには弱いことから、**クラウドへのバックアップ構築を決意**しました。

構築にあたり、**ChatGPT-4oを活用**し、Amazon S3 Glacier Deep Archive への  
**コスト最適かつ安全な自動バックアップ構成を完成**させました。

この記事では、その設定内容・料金・注意点をまとめます。

---

## ✅ 構成概要

| 項目                     | 内容                                        |
|--------------------------|---------------------------------------------|
| NAS機種                  | Synology DS218j                             |
| ディスク構成             | RAID1 → JBOD（実容量を約2倍に拡張）         |
| バックアップ方式         | Synology Hyper Backup（差分・圧縮・暗号化） |
| バックアップ先           | AWS S3（リージョン：us-west-2／オレゴン）   |
| ストレージクラス         | S3 Standard → 自動で Glacier Deep Archive  |
| 容量                     | 約5TB                                       |
| 実行頻度                 | 毎週 月曜 1:00                              |
| バージョン管理           | Smart Recycle（最大10世代）                |
| 整合性チェック           | 毎週 日曜 17:30                             |
| コスト見積（保存）       | 約 \$5.07/月（≒¥740）                        |

---

## ✅ AWSの設定

### IAMユーザー作成

- 「プログラムによるアクセス（API）」を許可
- 以下のカスタムポリシーを割り当て、**バケットの一覧取得と操作を最小限許可**：

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::<バケット名>"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::<バケット名>/*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
      "Resource": "*"
    }
  ]
}
```

> `<バケット名>` は任意の小文字英数字で作成（例：`my-nas-backup-bucket`）

---

### S3バケット設定

- バケット作成リージョン：`us-west-2（オレゴン）`
- プレフィックス：`backup/`（Hyper Backup側で指定）
- ライフサイクルルールを設定：

```text
アクション: アップロードから0日で Glacier Deep Archive に自動移行
```

---

## ✅ Hyper Backupの設定内容

- バックアップ先：S3 カスタムサーバー
- サーバーアドレス：`s3.us-west-2.amazonaws.com`
- バケット名：作成したバケット名を指定（例：`my-nas-backup-bucket`）
- ディレクトリ：`backup`（任意）
- アクセスキー／シークレットキーを入力
- 圧縮：有効化
- 転送時暗号化：有効化（ローカル暗号化は任意）
- スケジュール：毎週月曜 1:00
- 整合性チェック：毎週日曜 17:30
- バージョン管理：Smart Recycle／最大10世代

---

## ✅ コスト試算（5TB想定）

| 内訳                        | 金額（USD） |
|-----------------------------|-------------|
| Glacier Deep Archive保存費   | \$0.00099 × 5120GB = 約 **\$5.07/月** |
| S3 Standard初日分（移行前） | \$0.023 × 5120GB ÷ 30 ≒ 約 **\$3.83（初回のみ）** |

> ✅ 初月のみ合計約 \$ 8.90ドル、それ以降は毎月 \$ 5.07ドル 前後

---

## ✅ なぜGlacier Deep Archiveか？

- 復元には最大12時間かかるが、**災害用バックアップとしては問題なし**
- 月額コストは最安クラス（Standardの約1/20）
- Hyper Backupから直接保存できないため、**S3 Standard → 自動移行**がベストプラクティス

---

## ✅ ChatGPT-4oを使って良かったこと

- IAMポリシーやストレージクラス選定など、**技術的判断が高速でできた**
- NAS・AWS両者の仕様に合わせた設定案内が的確
- 疑問点をその場で解消できるので、**学習しながら構築が進む**

---

## ✅ この構成が向いている人

- NASを自宅で運用しており、災害リスクが気になる
- バックアップ先のコストを最小限にしたい
- 手間をかけず、放置で自動化したい
- 復元に時間がかかっても構わない（≒最終防衛手段）

---

## ✅ おまけ：次に検討してもよいこと

- Hyper Backup Explorer（PC用アプリ）で復元テスト
- AWS請求ダッシュボードの定期確認
- DSM通知設定による成功／失敗通知のメール受信

---

## ✅ まとめ

ChatGPT-4oを活用しつつ、手元のSynology NASから  
**月数百円で災害に強いクラウドバックアップ構成**を作ることができました。

構築が終わってからは完全自動化されており、放っておいても安全にバックアップが継続されています。

同様の構成を考えている方の参考になれば幸いです。
Databricksのカスタム形式のSQL ステートメントを試してみた

## 前提
・利用環境：Databricks

https://www.databricks.com/jp/try-databricks?scid=7018Y000001Fi15QAC&utm_medium=paid+search&utm_source=google&utm_campaign=17377047998&utm_adgroup=138148229998&utm_content=trial&utm_offer=try-databricks&utm_ad=732035937815&utm_term=databricks%20%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB&gad_source=1&gclid=CjwKCAiA8Lu9BhA8EiwAag16b8b3zbkIb3V7gp-8VUwKukXnhtVZRQ-1RY8SbETmGVgNT4bQramYmRoCX5wQAvD_BwE#account

## 参考ドキュメント

https://docs.databricks.com/aws/ja/sql/user/sql-editor/custom-format

## 操作手順（動画）

<iframe width="560" height="315" src="https://www.youtube.com/embed/vSiRIu134EQ?si=ZGsWQhQwb05lzlZC" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
AMIを別アカウントに移行し、起動する方法　

## 概要
AWSの試験でよく出てくるAMIを別アカウントに移行し、起動する手順を書いていきます。
試験では難儀なことするなぁと思っていたのですが、実際やってみたら割とわかりやすかったです。

## 手順
### 移行元での作業

- 移行したいEC2のAMIを取得する
:::note
AMIの取得法については以下記事に記載してます
https://qiita.com/hamada-kc/items/3e424a56bf4acd022291
:::
- 取得したAMIにて、AMI許可を編集をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/f081c817-3a50-48ac-bb1c-0161944cf860.png)
- 移行先でエラーになりますので、下記チェックボックスにチェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/9563a06f-51ec-4f07-8866-fd4d69c2d8fa.png)
- 共有アカウント欄にて、アカウントIDを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/cbd46385-5836-4865-a7ea-8c1036a6ad3e.png)
:::note
設定したらちゃんと一番下にある**変更を保存**をクリックしましょう
最初抜けていて、困惑しました...(´・ω・｀)
:::

### 移行先での作業
- EC2→AMIに進む
- プライベートイメージを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/b065db89-8f66-4336-99c9-c9817206a5b7.png)
- AMIのコピーをする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/6b26d11c-130a-4937-a023-fc00a3ab530a.png)

- 通常通りAMIから起動する
:::note info
AMIから起動する際、キーペアを選択しない場合
移行元で利用していたキーをそのまま使えます
※警告文がでてきますが、無視してください。
:::

## まとめ
AWSの試験ではよく出てくる内容ですが、実際に行ってみると
あ～これね～という感じになりますね。

ちなみに、キーペアを移行先に持ってくる方法も記載してます。
[キーペアを別アカウントに移行する方法](https://qiita.com/hamada-kc/items/9b487b9fdda8ebed0e41)
文字に感情を宿す：Yokimoji.com で顔文字の世界を探求しよう ✨

日々の開発やデザインのコミュニケーションにおいて、テキストだけでは伝えきれない感情やニュアンスを表現したいと感じたことはありませんか？そんな時に活躍するのが、日本発の顔文字（カオモジ）です。Yokimoji.com は、顔文字を活用してコミュニケーションをより豊かにするためのオンラインプラットフォームです

## 🌟 主な機能と特徴
1. AI 顔文字ジェネレーター
キーワードや感情を入力するだけで、適切な顔文字を自動生成します。例えば、「疲れた」と入力すると、(×_×) や (－_－) zzZ などの顔文字が提案されます
2. 感情翻訳ツール
通常のテキストを、かわいらしい顔文字付きのメッセージに変換します。例えば、「忙しい」を入力すると、(ﾉ◕ヮ◕)ﾉ*:･ﾟ✧ 忙しいよ〜 のような表現が得られます
3. 顔文字辞典
複雑な顔文字の意味や使い方を詳しく解説しています。例えば、ヽ(°〇°)ﾉ は驚きやショックを表す顔文字で、強い意外性を伝える際に使用されます。
4. カスタムワークショップ
目、口、動作などを自由に組み合わせて、自分だけのオリジナル顔文字を作成できます。例えば、目 (◕‿◕) + 口 (ᵕ) + 動作 (づ) を組み合わせると、(づ◕‿◕)ᵕ のような顔文字が完成します

## 🎯 活用シーン
ソーシャルチャット：日常会話に彩りを加え、感情を豊かに表現。

恋愛表現：告白や愛情表現を、かわいらしい顔文字で伝える。

謝罪と仲直り：謝罪の気持ちを、柔らかく伝える手段として。

仕事のコミュニケーション：業務連絡に適度な親しみやすさを加える。

ゲーム交流：ゲーム内のチャットで、感情や反応を即座に表現。

クリエイティブな表現：ブログや記事にユーモアや個性をプラス

🔗 今すぐ体験しよう
http://yokimoji.com/ にアクセスして、顔文字の世界を探求してみましょう。あなたのコミュニケーションが、より豊かで魅力的になること間違いなしです
PHPでの継承・委譲の書き方、いつそれらを使うか

# PHPにおける継承・委譲

PHPはもちろん **継承** と **委譲** もできるそうなのでそれらの基礎をまとめました。
そして、それらをいつ使うべきなのか、僕の考えも最後に言及します。

## 継承
PHPでは`extends`を使って継承を表現するみたいです。
なお、多重継承はできません。
以下の例では、DogはAnimalを継承し、speakをオーバーライドしていますね。

```php
class Animal {
  public function speak() {
    echo "Some sound";
  }
}

class Dog extends Animal {
  public function speak() {
    echo "Bark";
  }
}

$dog = new Dog();
$dog->speak(); // "Bark"
```

親クラスのメソッドを呼び出す時は以下のように書けます。

```php
class Dog extends Animal {
  public function speak() {
    parent::speak();
    echo "Bark";
  }
}

$dog = new Dog();
$dog->speak(); // "Some soundBark"
```
## 委譲

委譲はシンプルですね。渡すだけです。
`UserService` はログ出力を `Logger` に **委譲** しています。  
まぁ、自分でLoggerを作ることはない気はするのですが、例えなので許してください。

```php
class Logger {
  public function log(string $message): void {
    echo $message;
  }
}

class UserService {
  private Logger $logger;

  public function __construct(Logger $logger) {
    $this->logger = $logger;
  }

  public function createUser(string $name): void {
    // 省略
    $this->logger->log("Created user: $name");
  }
}
```

interfaceと組み合わせるとUserServiceがあくまでLoggerInterfaceという抽象を使用しているだけなので、より疎結合ですね。

```php
interface LoggerInterface {
  public function log(string $message): void;
}

class FileLogger implements LoggerInterface {
  public function log(string $message): void {
    // ファイルへ書き込み
  }
}

class UserService {
  private LoggerInterface $logger;

  public function __construct(LoggerInterface $logger) {
    $this->logger = $logger;
  }

  public function createUser(string $name): void {
    $this->logger->log("Created user: $name");
  }
}
```
## どちらを使うべきか？(意見)

### アプリケーション固有の知識を含む場合は **委譲**

ビジネスロジックなどアプリ固有の処理は、**委譲** を選ぶのが無難だと思います。
ビジネスロジックというよく変更が加えられるものを最初から正しく継承の階層で表現するのは非常に難しいと考えています。
なので、基本的には継承はあまり使わない方針で良いのかなと。

### 技術的・共通機能の再利用には **継承** を使えるかも？

ビジネスロジックに依存しない、技術のみで完結する要素は継承を使ってもまぁ良いですが、これも使わないほうが無難ではあるかなと。
ファイルローダー等はフレームワークが用意してくれていますし。
ただ、フレームワークで提供されているようなクラスは継承しても良いと考えています。
フレームワーク自体、技術的・共通機能ですから。

## 最後に

常に迷ったら「**継承より委譲**」と考えています。
これはPHPに限った話ではないですが。

また一つ学びが増えました。
デザインパターン　singleton

昔少し学んだデザインパターンを復習、当時より深堀してみる。
復習初回は「singleton」。

## パターン概要　一言でいうと。
クラスのインスタンスを1つしか作成できないようにする設計思想

## もう少し詳細
### クラス図
![空白の図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4082377/c3276f0b-4e92-405d-afeb-cbd783f2965f.png)

### ポイント
* コンストラクタがprivateであること
* 生成したインスタンスを取得するためのpublicな関数がいること
  当該クラスを使用したい場合は、getInstance()経由でインスタンスを取得し、使用するしかない

インスタンスの生成方法については、複数の方法が各所で紹介されている。
1. getInstance()の中でインスタンスを生成し、関数の呼び元に返す。
   または既に生成済の状態でgetInstance()が実行された場合は、生成済のインスタンスを呼び元に返す。
```cpp:取得関数実行時にインスタンス生成するケース
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
```


2.メンバー変数をstaticで定義し、インスタンス生成時にnewするケース
```cpp:メンバー変数をstaticで定義し、インスタンス生成時にnewするケース
private static Singleton singleton = new Singleton();
```

### 課題
* 単体テストに耐えられないケースが存在する
行ったテストでクラス内の情報が変わってしまうような場合に、
インスタンスの初期状態ではなくなるため、実行するテストの順序によっては、
期待したインスタンスの状態でなく、テストが正しく動作しないケースがある。

* メンバー変数を多く持つようなクラスには適さない
唯一のインスタンスに対して、複数の個所でクラス内の情報を更新することになるため、
インスタンスの情報更新について、処理を追い辛く、不具合が発生しやすい状態となる。

* 本クラスを継承した、子クラスを作成するための一苦労が必要
コンストラクタをprivateにしたクラスは基本継承できないため。
picoCTF Easy Cryptography全問

# hashcrack
適当なLinuxターミナルで問題文のncコマンドを実行するとハッシュが提示される。
ハッシュは一方向性であるため、平文に戻すことはできない。
しかし、著名なハッシュ値はレインボーテーブルに載っている。
有名なレインボーテーブルはCrackStation。
3つのハッシュが提示されるが、すべてこちらに載っている。

https://crackstation.net/


# EVEN RSA CAN BE BROKEN???
ぼくにはすうがくわからない


# interencdec
ファイル内にはBASE64でエンコードされたであろう文字列が。
~~~
YidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclh6ZzVNR3N5TXpjNWZRPT0nCg==
~~~
CyberChefでデコードしてみる
~~~
b'd3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrXzg5MGsyMzc5fQ=='
~~~
またまた、BASE64でエンコードらしき文字列。
BASE64には含まれることのない不自然な```b'``` ```'```を除去して
~~~
wpjvJAM{jhlzhy_k3jy9wa3k_890k2379}
~~~
文字を一定文字数分ずらして頭をpicoCTF{で始まるように19文字分ずらして
~~~
picoCTF{caesar_d3cr9pt3d_890d2379}
~~~

# Mod26
ROT13で13文字分ずらすだけ

# The Numbers
画像ファイルには以下の文字列が書いてある。
~~~
16 9 3 15 3 20 6 { 20 8 5 14 21 13 2 5 18 19 13 1 19 15 14 }
~~~
アルファベット順に1-->a 2-->bのように置換していき、
~~~
picoctf{thenumbersmason}
~~~
フラグ形式picoCTF{***}に合わせて
~~~
picoctf{thenumbersmason}
~~~

# 13
ROT13するだけ
正規表現でよく使うr文字列の必要性とツールによる違いを理解する

# ▼背景
私はr文字列は「正規表現書くときに''の前に付けるやつ」くらいに認識していた
今回は、このr文字列の意味をr文字列を使わなかった場合と比較して理解することを試みた。
正規表現エンジンはBigQueryにおいて使われているものを想定した。

# ▼結論

**r文字列とは、バックスラッシュ（`\`）をエスケープとして処理せず、そのままの文字列として扱う「生の文字列（raw string）」のこと**

正規表現ではバックスラッシュ（`\`）をよく使うため、バックスラッシュ（`\`）をエスケープとして扱わないr文字列を利用することで正規表現を書きやすくしている。

ex) r文字列を使わないと正規表現を書く際に`\\d`, `\\w`, `\\s`などのようにバックスラッシュ（`\`）を2個並べる必要が出てきて手間になる。

:::note warn
※ツール(正規表現エンジン)によってバックスラッシュ（`\`）をエスケープとみなすかが異なる。使用するツールなどによって確認する必要がある
:::

# ▼r文字列を使った場合と使っていない場合の比較にて理解を試みる

例えば以下のように、数字2桁にマッチさせたいとする。

### r文字列なし

```
pattern = "\d\d"
```

この場合、バックスラッシュ（`\`）はエスケープだと判断される。そのため、正規表現エンジンは以下のように認識することになる。
`pattern = "エスケープ +　d +　エスケープ + d`
これは数字を表す`\d`とは認識されないため、正しい正規表現としては処理されない。

これを正しい正規表現に直すと以下。
```
pattern = "\\d\\d"
```

1個目の`\`によって2個目の`\`がエスケープされて正しく`\d`だと認識されるようになる。

しかし、正規表現内でよく使うバックスラッシュ（`\`）を毎回`\\d`のように2個並べるのは面倒だし可読性も悪い。

:::note info
そこで便利なのがr文字列
:::

### r文字列を使った場合

```
pattern = r"\d\d"
```

この正規表現は正しく数字2つと認識される。
なぜなら、r文字列を使うことによりバックスラッシュ（`\`）がエスケープ文字だと判断されなくなるから。

以上のように、r文字列を使うことで正規表現を扱う際にエスケープ文字であるバックスラッシュ（`\`）を気にする必要がなくなる。

# ▼ツール別エスケープ（バックスラッシュ）の扱い比較

本記事はBigQueryにて使われている正規表現エンジンを想定して説明を行った。しかし、ツールによってはr文字列を使わずともバックスラッシュ（`\`）をエスケープ文字だと認識しないことがある。表にまとめる

| ツール・環境              | 正規表現で `\d` を書く方法 | 説明 |
|---------------------------|-----------------------------|------|
| **GA4（条件設定など）**   | `\d`                        | バックスラッシュはそのまま使える（`\\d` にする必要なし）|
| **Google Apps Script**    | `"\\d"`                     | エスケープ必要(r文字列は使えないが不要な方法もあり) |
| **Looker Studio**         | `"\\d"` または `r"\d"`                        | エスケープ必要(r文字列使えば不要) |
| **BigQuery**              | `"\\d"` または `r"\d"`     | エスケープ必要(r文字列使えば不要) |
| **Python**       | `"\\d"` または `r"\d"`                      | エスケープ必要(r文字列使えば不要)  |

使用するツールがどの正規表現エンジンを使っているかを理解した上で正規表現を記述する必要がありそうだ
「手探りでCUI OS作成に挑む」実装篇　ブートローダー作成

## 「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。

## ブートローダー及び読み込まれるコード
次回からkernel.asmの中でOSを実装していきます。
```boot.asm
; 第2セクタを読み込み、実行するブートローダー
org 0x7C00

start:
    ; セグメント初期化
    xor ax, ax
    mov ds, ax
    mov es, ax

    ; スタック設定
    mov ss, ax
    mov sp, 0x7C00

    ; ディスクから第2セクタを 0x7E00 に読み込む
    mov ah, 0x02        ; INT 13h サービス 2: 読み込み
    mov al, 1           ; 読み込むセクタ数 = 1
    mov ch, 0           ; シリンダ = 0
    mov cl, 2           ; セクタ番号 = 2（1始まり）
    mov dh, 0           ; ヘッド = 0
    mov dl, 0           ; ドライブ番号
    mov bx, 0x7E00      ; 読み込み先アドレス
    int 0x13
    jc disk_error       ; エラー時に無限ループ

    ; 読み込んだコードへ跳ぶ（第2セクタ）
    jmp 0x0000:0x7E00

disk_error:
    jmp $

times 510-($-$$) db 0
dw 0xAA55

```
第2セクタに格納され、`boot.asm`から読み込まれて実行される簡単なコードです。
```kernel.asm
org 0x7E00

    ; セグメント初期化
    xor ax, ax
    mov ds, ax

    ; 文字列表示
    mov si, msg
.print:
    lodsb
    test al, al
    jz .halt
    mov ah, 0x0E
    int 0x10
    jmp .print

.halt:
    jmp $

msg db 'Hello from kernel (2nd sector)!', 0x0D, 0x0A, 0

times 512-($-$$) db 0
```

## 動作確認
```
nasm boot.asm -o boot.bin          # コンパイル
nasm kernel.asm -o kernel.bin
cat boot.bin kernel.bin > os.img   # 結合
qemu-system-i386 -fda os.img       # 起動
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/9fe62e2d-5f8f-4edb-91eb-657d92e56209.png)
Node.jsで静的Webサイトを丸ごと保存するツールを作った（axios + cheerio）

Web制作やCMSの移行作業をしていると、「もうこのサイト編集できないけど、内容は残したい」「WordPressをやめたいけど、静的に残したい」といった場面がありますよね。

そんなときに役立つ、Node.js + axios + cheerioで構築した静的Webサイト保存ツールを作りました。
対象のURLを指定するだけで、HTML/CSS/JS/画像/動画などのアセットを構造を保ったままローカルに保存できます。

## ✅ このツールでできること
- URL構造に沿ってHTMLをローカルディレクトリに保存
- CSS・JS・画像・音声・動画ファイルを再帰的にダウンロード
- CSS内部の background-image: url(...) なども正規表現で抽出・取得
- `<a href="...">` の内部リンクをたどって再帰的に保存
- BASE_URL を変えるだけで他サイトにもそのまま使い回せる

## 🛠 環境と前提
- Node.js 環境（v18.xなどで確認済）
- ファイル保存先はローカルディスクを想定
- 必要なnpmパッケージは axios と cheerio

## 🔧 インストール
まずは必要なライブラリをインストールします。

```bash
npm install axios cheerio
```

### 環境依存の注意点：
- ESM構文（import形式）で組んでいると url, fs, path の扱いが異なる場合があります
- `require('url')` が失敗する場合は、以下で補完インストールしてください：

```bash
npm install url
```

### ⚙️ 設定
スクリプト内の以下2点を自分の環境に合わせて書き換えてください。

```js
const BASE_URL = 'https://example.com/';
const BACKUP_FOLDER = 'D:/your/backup/folder';
```

### ▶️ 実行方法
```bash
node scraper.js
```

実行すると BACKUP_FOLDER にHTMLファイルと各種アセットが保存され、
元サイトの階層構造をそのまま再現した形でバックアップされます。

### 🌍 このツールの用途例
- Web制作時の他社実績サイトの構造研究（ローカルで静的確認）
- WordPressなどの古いCMSからの脱出用バックアップ
- 定期的なアーカイブ用途（更新停止サイトなど）

### 📁 リポジトリ（GitHub）
https://github.com/msfactory1103/scraping-tools

### 📝 今後の予定・構想
- GUI対応バージョンの作成（Electron or Web UI）
- ページ間リンクの相対変換（オフライン化強化）
- クローラー側の除外ルール（robots.txt風）

### ✒️ 最後に
このツールは「業務でちょっと困った」をきっかけに、最小構成で実用性を優先して作っています。
同じような状況で困っている方の参考になれば幸いです。

バグ・改善案・プルリクなど歓迎です！

## 📄 Related Articles
- Zenn: [静的Webサイトを丸ごと保存するNode.jsツール](https://zenn.dev/msfactory/articles/45035ba0a4293f)
メール通信の仕組み 〜プロトコルで読み解くメールの流れ〜

# メール通信の仕組み 〜プロトコルで読み解くメールの流れ〜

私たちが毎日使っている「メール」ですが、その裏側では複雑なプロトコル同士が連携して正確にやりとりを行っています。
ここでは、以下の図の流れに沿って「メールはどうやって送られて、どうやって届くのか？」を具体例とともに、視覚的にもわかりやすく解説します。

![How-Email-Works.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125746/d8cab140-d179-40b2-b082-996aed4417fe.jpeg)
---

## 📬 メール送受信の全体フロー（簡易図解）

```
[PC/スマホ]       [送信サーバ]      [受信サーバ]       [受信端末]
   ↓                  ↓                  ↓                  ↓
┌────────┐   ┌────────────┐   ┌────────────┐   ┌────────┐
│Gmail等の  │⇒⇒│SMTP転送処理  │⇒⇒│IMAP/POPで取得│⇒⇒│Outlook等│
│メール送信  │   │DNS/MX参照等  │   │セキュリティ検証│   │メーラー   │
└────────┘   └────────────┘   └────────────┘   └────────┘
```

---

## ステップ別に解説

### ① クライアントから送信リクエスト（SMTP）

あなたがメールをGmailなどのクライアントから送信すると、まずはSMTP（Simple Mail Transfer Protocol）が使われます。

**例）あなたのメールアドレスが `you@example.com`、宛先が `friend@othermail.com` の場合：**

```
Gmailクライアント → SMTPサーバへ接続（ポート587や465）
```

このSMTPサーバは、次の宛先にメールを転送する必要があるため、DNSに「MXレコード（Mail eXchange）」を問い合わせます。

---

### ② DNSで宛先サーバを調べる（MXレコード）

```
example.com → DNS → MXレコードを問い合わせ
⇒ mail.othermail.com のIPアドレスを取得
```

これで、宛先のメールサーバのIPが分かり、接続可能になります。

---

### ③ SMTPでメールを送信

取得した受信側メールサーバに対して、SMTPがメールを送信します。
この時、次のような情報も一緒に送られます：

* 宛先アドレス
* 件名・本文（MIMEエンコーディング）
* 添付ファイル
* セキュリティ署名（DKIMなど）

```
you@example.com → friend@othermail.com
件名: こんにちは
本文: 今夜飲みに行きませんか？
```

---

### ④ メールは一時保存される（Queue）

受信側サーバでは、すぐに相手の受信クライアントが取りに来るとは限らないため、いったん「メールキュー（Queue）」に保管します。

---

### ⑤ クライアントがメールを取得（POP3またはIMAP）

宛先の相手（[friend@othermail.com](mailto:friend@othermail.com)）が、Outlookなどのメールクライアントを起動すると、以下のようにサーバと通信します：

* **POP3（ポート110）**：メールをダウンロードしてサーバから削除（スマホ向き）
* **IMAP（ポート143）**：サーバ上のメールを同期（PC・スマホ両用に便利）

```
Outlook → IMAP接続 → メール一覧取得 → メール本文を表示
```

---

## 🔐 セキュリティプロトコルも活躍！

メールは非常に攻撃されやすい通信手段なので、以下のプロトコルが安全性を保っています：

* **SPF**：この送信者は正規ドメインか？
* **DKIM**：メールは改ざんされていないか？
* **DMARC**：SPF/DKIMを満たさない場合、どうするか？

たとえば、Gmailで送ったメールには「DKIM署名」が付き、受信側サーバで「改ざんがないか」が検証されます。

---

## 🌐 使用される主なポート番号まとめ

| プロトコル             | 用途              | ポート番号                |
| ----------------- | --------------- | -------------------- |
| SMTP              | 送信              | 25 / 587 / 465 (SSL) |
| POP3              | 受信（DL）          | 110                  |
| IMAP              | 受信（同期）          | 143                  |
| SMTPS/IMAPS/POP3S | セキュア通信（SSL/TLS） | 465/993/995          |

---

## 📌 まとめ：メールはこうやって届く！

* メール送信はSMTP、受信はPOP3またはIMAP
* DNSでMXレコードを参照し、宛先のメールサーバを探す
* セキュリティ対策も多数組み込まれている（SPF/DKIM/DMARC）
* プロトコルごとに通信ポートや用途が異なる

---

## 📚 おまけ：実際のSMTPセッション（コマンド例）

```bash
telnet mail.example.com 25

HELO mydomain.com
MAIL FROM:<you@example.com>
RCPT TO:<friend@othermail.com>
DATA
Subject: Hello
This is a test email.
.
QUIT
```

---
未来におけるアセンブリ：不滅か、消滅か



> _"低レイヤを捨ててまで、我々は抽象に安住すべきか？"_  

アセンブリ言語——それは、ソフトウェアとハードウェアの間に横たわる、**最も細く、最も鋭い接点**であった。  
だが今日、ほとんどの開発者はその存在を意識することすらなく、  
コードは高級化し、抽象は重なり、最下層は“透明な基盤”として振る舞っている。

この章では、**アセンブリという言語が今後も必要とされるのか、それとも静かに役割を終えていくのか**を、  
現代的技術潮流・設計倫理・人間の可視性限界と照らし合わせて考察する。

---

## 自動化の進展と「アセンブリ不要論」

AIによるコード生成、LLVMベースの最適化、eBPFのような“中間層実行”、  
そしてJIT/仮想マシン技術の成熟により、現代開発はこう宣言する：

> **「アセンブリを直接書く必要など、もはやない」**

- ハードはブラックボックス化し  
- オペレーティングシステムが抽象化し  
- 高級言語とライブラリが細部を吸収する

→ “細かい制御”は、**無視されることが合理とされる時代**に突入している。

---

## だがそれは、本当に“制御の放棄”なのか？

人類が宇宙開発や医療用デバイス、リアルタイム制御システムを作るとき、  
それでもなお、アセンブリは使われ続けている。

- **バイナリサイズ制限**（ブートローダ、マイコン）  
- **実行時間保証**（リアルタイムOS、航空制御）  
- **ハードウェア制御**（レジスタ叩き込み）  
- **逆解析・脆弱性調査・マルウェア解析**  
- **AIモデルの低レイヤ最適化（SIMD/AVX）**

つまり、**「アセンブリは必要だが、誰もが触れない構造へと沈みつつある」**

---

## 消滅するのは“言語”か、“書き手”か？

アセンブリが不要になる未来とは、  
- 自動最適化がすべてを置き換え  
- 意図は高級言語で完結し  
- 安全も速度も仮想層で吸収できる世界

しかし、仮想化やAIがいかに高度化しても、  
**“機械語は依然として存在”し続ける。**

ならばアセンブリは消えない。  
ただし、それを「書く」人間がいなくなるだけだ。

---

## “不滅”としてのアセンブリ：思想の遺伝子として

アセンブリは単なる言語ではない。  
それは「構造と実行の関係」を思考する、**設計上のリテラシー**である。

たとえば：

- アセンブリを知る人は、メモリレイアウトを意識する  
- 関数呼び出しの裏側を想像できる  
- 安全性と最適化のトレードオフを数値ではなく命令列で理解できる

→ アセンブリは“書くため”のものから、**“考えるため”の道具**へと役割を変える。

---

## 「見えない層」をどう伝承するか

アセンブリを知らずに育った世代は、  
ブラックボックスをブラックボックスとして受け入れる。

それは必ずしも悪ではない。  
だが、設計やセキュリティの深部において、  
**「なぜこう動くのか」を語れる者の数は確実に減少する。**

→ よってアセンブリは、未来において**「暗黙知を保管する記憶装置」**としての価値を帯びる。

---

## 結語：アセンブリとは、沈黙のなかにある設計の言語である

アセンブリは、もはや主役ではない。  
それを書く者も、読む者も、日に日に少なくなるだろう。

だがそれでも、  
- AIが自動でコードを吐くとき  
- 予期しない挙動をデバッグするとき  
- ハードウェアが例外を吐き出すとき  
- セキュリティが崩れたとき

**最後に残るのは、命令列である。**

それを読める者が存在する限り、  
そしてそれを“意味”として再構成できる者がいる限り、  
アセンブリは消えない。

> _"アセンブリは死なない。なぜならそれは、コードの最下層ではなく、思考の最下層にあるからだ。"_
ハードウェアに書き込まれた思想を読む



> _"マシンは語らない。だがその構造は、設計者の信念を沈黙のうちに語っている。"_  

我々が日々使うコンピュータ、その最深部に存在するのがハードウェアである。  
だがそれは、単なる物理的な装置ではない。**“ある設計思想を具現化した構造物”**である。

本章では、命令セットアーキテクチャ（ISA）やバス構造、レジスタ設計といった  
**コンピュータの物理的構成のなかに刻まれた哲学的選択**を読み解き、  
「なぜその構造であるのか」を問うことで、**ハードウェアが持つ“無言の設計言語”**を浮き彫りにする。

---

## 命令セットは哲学である

アーキテクチャは、**「どのような命令を、どのように与えるか」**を決定する。

たとえば：

- **x86**：命令長可変、複雑な演算、メモリアクセスと演算の混合  
- **ARM**：命令長固定、条件実行、低消費電力重視  
- **RISC-V**：極端なミニマリズム、拡張前提のオープン設計

これらはすべて、**「計算とは何か」「効率とは何か」**に対する違う答えを持つ。

---

## レジスタ構造に見る“抽象と物理の融合”

### x86系：

- `eax`, `ebx`, `ecx`, `edx` … という**歴史的な名前付きレジスタ**  
- 一部は特定命令にしか使えず、**文法的拘束を残す**  
- 節約と継承の象徴

### RISC系：

- `x0`〜`x31` など、**均質で機械的なレジスタ名**  
- 機能による制限がなく、**設計者の裁量が広い**  
- 構造の対称性と理想的な設計空間の象徴

→ レジスタの設計は、**制御と自由、過去と未来への態度**そのものである。

---

## メモリモデルは「空間に対する哲学」である

- **セグメント方式**（x86）  
  → 過去の制約を受け入れた上での「分断的記憶」  
  → 機能ごとの空間分離という「意図的区画化」

- **フラットアドレス空間**（RISC-V, ARM）  
  → 単純性と論理一貫性への信頼  
  → 空間を抽象化せず、**完全な“連続する構造”として捉える**

→ 記憶をどう扱うかは、**「情報をどう保存するか」という文化的選択**である。

---

## キャッシュとパイプライン：時間を設計する装置

現代CPUは、単に命令を実行するだけではなく、**「時間を分割し、重ねる」**ことを設計目標としている。

- パイプライン：命令を“段階的に分業処理”  
- スーパースカラー：複数命令を同時処理  
- キャッシュ：アクセス時間差を“予測によって補う”

これらは、**「どこまで未来を想定するか」**という問いへの工学的回答である。

→ ハードウェアは、**時間と空間の予測不能性に対して、“秩序の戦略”を仕掛ける哲学装置**なのだ。

---

## ハードウェアの進化は妥協と戦略の記録である

- x86の複雑さは、「互換性」という呪いと美徳の両面を孕む  
- ARMの普及は、「効率と可搬性」という現代的価値への適応  
- RISC-Vの躍進は、「最小から始める」という構築的理想の証明

→ どのISAも、技術的な最適化の前に、**設計思想の“選択と放棄”をしている**

---

## ハードウェアを見るということは、設計者の思考を読むということ

逆アセンブルをして命令を読む。  
命令を辿れば、制御の流れが現れる。  
制御の流れを観察すれば、**そこには“こう書いてほしい”というマシンの意図**が見える。

それは設計者が書いた“仕様”ではない。  
**設計者が書き込んだ“制約”と“余地”の配列**である。

---

## 結語：構造とは、思想の物理的残響である

ハードウェアを読むという行為は、  
それ自体が**過去の設計者との対話**であり、  
未来の設計者としての想像力のトレーニングでもある。

命令の配列、バスの幅、レジスタの数、キャッシュの階層。  
それら一つひとつが、**「どう在るべきか」という思想の破片**だ。

> _"コードは構文を持つ。だがハードウェアは構文を持たない。  
設計思想そのものが、構造としてそこに立ち上がっている。"_
仮想マシンとネイティブコードの哲学的断絶



> _"抽象化は自由を与える。だがその自由は、物理との断絶によって成立している。"_  

コードは動作する。  
だが「何の上で動作するか」によって、その意味はまるで異なる。

本章では、仮想マシン（VM）とネイティブコードという**二つの実行モデルの対立構造**を通じて、  
抽象と物理、可搬性と即時性、そして**ソフトウェアにおける実在の層構造**を捉え直す。

---

## 仮想マシンとは何か？

仮想マシン（VM）は、**“もう一つの抽象的コンピュータ”をソフトウェア上に再現した実行基盤**である。

代表例：

- JVM（Java Virtual Machine）  
- CLR（.NET Common Language Runtime）  
- WASM（WebAssembly Runtime）  
- V8（JavaScript エンジン）  
- Lua VM、BEAM（Erlang）など

特徴：

- 実マシンと独立した命令セット（Bytecode）  
- 抽象化された型、GC、例外機構を保持  
- **中間層による安全性と可搬性の保証**

---

## ネイティブコードとは何か？

ネイティブコードとは、**直接CPUの命令セットに対応する命令列**で構成されるコードである。

- x86, ARM, RISC-Vなどアーキテクチャ依存  
- 実行速度は極めて高い（中間抽象なし）  
- 安全性や整合性の保証は**完全に開発者の責任**

例：

```nasm
mov eax, 1
int 0x80  ; Linuxシステムコール（exit）
```

→ **OSカーネル、ドライバ、ゲームエンジンの一部、ブートローダなどに多用される**

---

## 哲学的断絶：実行環境の“存在論”の違い

| 概念             | 仮想マシン                                 | ネイティブコード                              |
|------------------|--------------------------------------------|-----------------------------------------------|
| 実行単位         | 抽象命令（bytecode）                       | 機械語命令（machine code）                    |
| ハード依存性     | 低い（VMが抽象化）                         | 高い（アーキテクチャに直結）                 |
| 安全性           | 管理・制御された環境                       | 非管理環境、任意アクセス可能                 |
| 動作原理         | シミュレーションまたはJITによる逐次変換    | 直接解釈（fetch-decode-execute）             |
| 哲学的構造       | 抽象的・階層的・設計思想的                 | 物理的・直截的・装置論的                     |

→ 仮想マシンは**「動作の理想を設計する」**ための構造、  
ネイティブコードは**「動作そのものを制御する」**ための構造。

---

## 抽象化の代償：制御の喪失と意味の遅延

VMによる実行は、以下のものを代償にしている：

- **即時性**：動作は抽象解釈を経て遅延される  
- **制御性**：メモリ管理、割り込み、CPU制御にアクセスできない  
- **物理性**：キャッシュ挙動、命令列最適化などへの介入が困難

しかしそれによって得られるものもある：

- **安全性**：例外、型、GCなどの構造的保証  
- **移植性**：アーキテクチャ非依存のコード実行  
- **記述の自由**：高レベル言語との親和性

---

## ネイティブコードの「存在の重さ」

ネイティブコードは、抽象を剥いだ実行形態である。  
それゆえに、あらゆる命令が**“即時に現実と接続”**する。

- `in`, `out` 命令でデバイスを直接制御  
- `hlt` 命令でCPUの停止を宣言  
- セグメントレジスタやページテーブルの操作による、**現実世界との構造的連結**

→ ネイティブコードは、**コードというより“硬直化された構造体”であり、  
動作そのものが機械の延長である。**

---

## 仮想マシンは「世界をもう一度設計する」

仮想マシンは、OSの上にもう一つの“言語宇宙”を作る行為である。  
JVMは型とオブジェクトと例外のある世界を定義し、  
WASMはWebにおける命令最小単位の宇宙を再設計する。

→ それは、ハードウェアではなく、**“設計思想が支配する世界”**である。

---

## どちらが「本物」なのか？

この問いは無意味である。  
仮想マシンもネイティブコードも、**「何に最適化されているか」が異なるだけ**である。

- ネイティブ：現実との直接性と効率性  
- 仮想：安全性、移植性、開発速度、分散実行

ただし一つ確かなのは、  
**仮想マシンは世界の“記述”を、ネイティブコードは世界の“実在”を扱っている**という点だ。

---

## 結語：抽象と物理は、対立ではなく対話のためにある

仮想マシンとネイティブコードは、二項対立ではない。  
それは**実装者の意図と設計哲学の現れ方が異なるだけ**である。

- 記述の自由を取るか  
- 実在の即時性を取るか  
- 可搬性を取るか  
- 制御の絶対性を取るか

いずれを選ぶにせよ、**その構造を理解することは、“コードが動くとは何か”を問うことに他ならない。**

> _"仮想マシンは思想を動かし、ネイティブコードは物質を動かす。コードとは、両者のあいだを彷徨う存在である。"_
構文なしの世界：機械語と向き合う



> _"構文が消えたとき、残るのは数値か、それとも構造か？"_  

人間は言語を通じて思考し、構文を通じて構造を理解する。  
しかし、最終的にCPUが解釈するのは、**構文ではない。**  
それは1と0の世界——**命令のビット列としての“機械語”**である。

この章では、アセンブリすら持たない純粋な機械語の世界に降り立ち、  
**抽象なきコードがいかにして動作を記述し、構造を内包しているのか**を見つめ直す。

---

## アセンブリ vs 機械語：翻訳と対話の境界線

アセンブリは機械語の**ニーモニック表現（記号化）**である。  
たとえば、以下の命令：

```nasm
mov eax, 1
```

は、x86アーキテクチャではおおよそ：

```hex
B8 01 00 00 00
```

というバイト列になる。

- `B8` は「EAXに即値をロードせよ」  
- `01 00 00 00` は32bitのリトルエンディアンで1

ここには既に、**構文は存在しない。あるのは命令の形式と意味の符号化**だけである。

---

## 機械語の読み解き：構文なき解析

### 問題：

```hex
55 8B EC 83 EC 10 89 4D FC
```

これは人間にとってはただの数値列。  
だがCPUにとっては「意味ある命令列」である。

### デコード（x86）：

```
55             → push ebp  
8B EC          → mov ebp, esp  
83 EC 10       → sub esp, 0x10  
89 4D FC       → mov [ebp-0x4], ecx
```

→ 一連の関数プロローグが姿を現す。

### ポイント：

- **構文がなくても、構造は存在する。**  
- それを読むには、**構文ではなく構造との「照合」**が必要。

---

## 構文がない世界では、意味はどこに宿るのか？

### 答え：**形式と位置**に宿る

- `0xB8` は EAX 即値ロードであることを約束する  
- `0x55`（`push ebp`）は、関数の始まりとして慣習的に現れる  
- `0xC3`（`ret`）は、終わりの記号である

→ 意味とは、キーワードではなく、**符号と順序に染み出す構造**である。

---

## 意図を超える機械語：ポリコード・自己変形・ガベージ命令

機械語は、設計者の意図を裏切ることもある。

### 例1：ポリコード（polycode）

```hex
C3 90 90 90 90
```

→ `ret`（終了）に続く`nop`（何もしない）命令  
→ 検出を回避するための難読化。**意味は“存在しないように見せかける”**

### 例2：自己変形コード

命令自身が次の命令を変更する：

```nasm
mov [eax], 0x90C3  ; 上書きして `nop; ret` を生成
jmp eax            ; 動的に実行
```

→ この場合、「構文」は途中で書き換わる。  
→ **意味は、時系列の中で動的に変化する。**

---

## 人間は構文を通じて意味を得る。CPUは形式を通じて命令を得る。

この断絶は、セキュリティと最適化にとって重要な意味を持つ。

- **セキュリティ**：構文レベルで意味が見えなくても、実行可能な意味が隠れている（shellcode, ROP）  
- **最適化**：機械語の並びを変えることで、キャッシュヒット率やパイプライン効率が変わる  
- **教育**：初心者が“読める”のは構文まで。だが、プロセッサが“解釈する”のは形式だけ

→ よって、**最下層の理解には、構文を剥ぎ取り、形式だけを見つめる必要がある。**

---

## 「読む」から「デコードする」へ

アセンブリは読める。  
機械語は読めない。**だが、解読はできる。**

### 構文なき世界での理解の鍵：

- オペコード表（命令一覧）  
- エンディアン性（リトル／ビッグ）  
- アーキテクチャ特性（命令長、命令整列）  
- 規則性の再構築能力（プロローグ・エピローグの型）

→ 理解は、「構文」を媒介にしなくても可能である。  
それは、**純粋な構造読解**という、形式的知性の鍛錬でもある。

---

## 結語：構文が消えても、構造は生きている

アセンブリを超えた世界には、文字も名前もない。  
あるのは、数字の列と位置だけだ。だがそこには、  
**構文を超えた次元で設計者の意図が残響している。**

> _"構文は人のためにある。機械は構文を知らない。だが、構造だけが両者の間に橋を架ける。"_
バイナリから意味を取り戻す



> _"構文は消えても、意味は残る。読み取るのではない。再構築するのだ。"_  

コードがバイナリになるとき、それは一度「意味」を手放す。  
関数名も、変数名も、制御構造も、人間のために存在したすべての補助線が、剥ぎ取られていく。  

だが、アセンブリレベルで構造を読み解く者にとって、そこには依然として**復元可能な“構造の痕跡”**がある。  
本稿では、バイナリという“意味を失った物質”に、いかにして**再び意味を与えるのか**という知的行為を、  
構造復元、リバース技術、形式的手法を通して論じていく。

---

## 意味が失われる瞬間：バイナリの生成とは何か？

プログラムが `.c` や `.rs` から `.exe` や `.elf` になる過程は、  
**翻訳ではなく“変換”**である。

- コメント → 消える  
- シンボル → リンク時に解決・削除  
- ロジックのまとまり → 最適化により潰れる  
- ソースコードの時間的順序 → 物理命令の配置に置き換えられる

結果、バイナリは**完全な命令列であるが、“人間が読むための構造”を一切持たない。**

---

## では、何を頼りに意味を取り戻すのか？

### 1. 命令そのものの並び方  
→ `push`, `mov`, `call` の組み合わせから関数構造を推定

### 2. スタック操作とレジスタ利用パターン  
→ ローカル変数の配置・引数の受け渡しが見えてくる

### 3. API呼び出しや文字列  
→ 機能の“外との接続点”が明確化される

### 4. 分岐構造  
→ `cmp` + `jne` のパターンが、if文やswitch文を連想させる

→ これらすべてを“読む”のではなく、**“組み合わせて推測し、文法と構造を復元する”**という再構築の技術が必要となる。

---

## 事例：構造なきバイナリからの構文再構築

### バイナリ列：

```nasm
mov eax, [ebp+8]
cmp eax, 5
jne loc_40102A
mov eax, 1
jmp loc_401030
loc_40102A:
mov eax, 0
loc_401030:
ret
```

### 推定される高級構文：

```c
int f(int x) {
  if (x == 5) return 1;
  else return 0;
}
```

### ポイント：

- `[ebp+8]` → 引数  
- `jne/jmp` → 分岐制御  
- `ret` の直前に `eax` → 戻り値

→ **ロジックは、構文を失っても再発見できる。**

---

## GhidraやIDAが行う「自動意味構築」の仕組み

逆コンパイラは、バイナリを次の段階で解釈する：

1. **命令の分解（disassembly）**：コード領域のスキャンと命令単位への変換  
2. **制御フロー構築（CFG）**：ジャンプ命令からグラフ構造を再構成  
3. **シンボル推定と命名**：文字列/システムコール/パターンマッチによる関数名付与  
4. **高級言語変換**：if/while/関数呼び出しに戻す

→ これはまさに、**言語を剥がされた構造に“言語を再び与える”作業**である。

---

## 意味を取り戻すとはどういうことか？

- 単なる“出力の一致”ではない  
- **設計者の意図、時間構造、論理的構成の解釈を再生成する**こと  
- “この関数はこう動く”ではなく、“なぜこの構造にしたのか”を復元すること

→ それは**認知的・構造的・倫理的にコードと対話する技術**である。

---

## 限界と美しさ

逆コンパイルは完全ではない。

- オブフスケーション（難読化）  
- セルフ変形（self-modifying code）  
- ジャンプテーブルによる複雑な分岐構造  
- アセンブリ最適化による意図の喪失

→ それでも、そこから意味を再構成しようとする試み自体が、  
**ソフトウェアにおける構造的敬意の表れである。**

---

## 結語：意味は書かれているのではない。読まれることで成立する。

バイナリは、死んだ構文の集積ではない。  
それは、設計の残響であり、構造の地層であり、  
**意味を剥がされながらも、その奥に何かを訴え続ける静かな記号の群れ**である。

アセンブリを通じてバイナリと向き合うとは、  
構造を愛し、意味を想像し、そして再構成する**“読む”という最も人間的な技術の再発見**である。

> _"意味は保存されない。だが、意味は再構成できる。バイナリは無言ではない。沈黙の奥で、すべてを語っている。"_
アセンブリにおける「意味」と「最適」の分断



> _"最適とは、常に正しいのか？ 意味は、速度に従属すべきか？"_  

アセンブリは、命令の羅列でありながらも、**“意図を表現する言語”**である。  
だがその最適化は、しばしば“意図”を無視し、**構文的・機械的な効率性**を優先する。

この章では、「意味」と「最適」が**アセンブリという低レベル言語においていかに衝突しうるか**を掘り下げる。  
そして、最適化されたコードが**なぜときに人間にとって不可読となり、意図を逸脱してしまうのか**、  
その哲学的・技術的乖離を考察する。

---

## 命令は意図の痕跡である

アセンブリコードの命令は、単なる計算や分岐ではない。

```nasm
mov eax, 0
loop:
  add eax, 1
  cmp eax, 10
  jl loop
```

このループには、**人間の“カウントする”という行為の構造が埋め込まれている**。  
`eax`に対する加算は「累積」、`cmp`と`jl`は「上限の判断」、`loop`は「再評価の意思」だ。

### だが最適化されると？

```nasm
mov eax, 10
```

これで済む。**意味は残らない。**

---

## 最適化のジレンマ：効率化は構造を破壊する

最適化コンパイラやJITは、構文の意味を読み取るわけではない。  
**動作が等価であれば、すべてを置き換える。**

- ループを数式に  
- 関数呼び出しをインライン化  
- 演算を先取りしてキャッシュ  
- 条件分岐を論理操作に変換

こうして「意図」は削ぎ落とされ、**“計算結果の一致”だけが残る。**

→ だが開発者が読むべきものは、**結果ではなく意図である。**

---

## 読解不能なアセンブリ：意味喪失の果て

例：人間が書いたコード

```nasm
push ebp
mov ebp, esp
sub esp, 0x10
mov [ebp-4], 0
```

→ 明確な関数フレーム。変数の初期化。

### 最適化後のコード（`-O3`など）

```nasm
xor eax, eax
ret
```

→ **関数の構造は見えず、変数も消え、フローも断片化する。**

つまり、**最適化が強くなるほど、「読み解くための構造」が消える。**

---

## 最適 ≠ 意味の保持

この乖離は特にセキュリティ・逆解析・教育・ドキュメント生成の場で問題になる。

- バイナリ解析では、**何をしているか**を読みたい  
- セキュリティ研究では、**意図的挙動**を見抜きたい  
- 初学者教育では、**構文と意味の対応**を学ばせたい

しかし最適化アセンブリは、**それらすべてを破壊する方向に進む。**

---

## 意図を含んだ最適化は可能か？

### 一部存在する技法：

- **シンボリック最適化**：構文情報を保持したままの変形（Rust MIRなど）  
- **構造保存型SSA変換**：ループや条件の構文を保った中間表現最適化  
- **可読性優先のアセンブリ生成**：教育やドキュメント用（e.g., Compiler Explorer）

→ しかし、いずれも**人間中心設計を意識した“特殊な最適化”**であり、  
コンパイラの本質は依然として「意味ではなく効率」を重視する。

---

## 「意味」はどこで失われるのか？

- 関数呼び出しが消える：意味単位が分解される  
- 変数名が消える：文脈が消失する  
- ジャンプが並び替えられる：因果関係が曖昧になる  
- 複数の命令が1命令に潰される：**時間構造が消える**

→ 最適化とは、**意味の圧縮**ではなく、**意味の“蒸発”**である。

---

## 設計者の選択：読むか、速さを取るか

### 教育や保守を重視するなら：

- 最適化レベルを落とす  
- アセンブリ生成に注釈を付ける  
- ソースマップやデバッグ情報を埋め込む

### 性能を追求するなら：

- 意味の犠牲を許容する  
- 計算効率とキャッシュ挙動を優先  
- 可読性の低下と、構造喪失を受け入れる

→ **最適化とは、速度と意味のトレードオフである。**

---

## 結語：アセンブリは意図と結果のあいだに揺らぐ

アセンブリは透明な言語だ。  
だがそれは、**書かれたままであれば、の話である。**

最適化されたアセンブリは、  
しばしば**「機械だけが理解可能な世界」へと変質する**。

そして我々が問い続けなければならないのは：

> _「その構造は、誰のために存在しているのか？」_

最適化とは、終着点ではない。  
**意味と速度のあいだで、構造を選び取る哲学的決断の過程**なのだ。

> _"最適とは、機械にとっての答えである。意味とは、人間にとっての問いである。アセンブリはその両方を同時に含む唯一の言語である。"_
バイナリ解析とリバースエンジニアリング技法



> _"構文が失われても、意味は残る。バイナリとは、言語の死骸ではなく、構造の化石である。"_  

プログラムがコンパイルされ、最適化され、リンクされ、  
やがて `.exe` や `.elf` や `.bin` といった**バイナリファイル**に変わるとき、  
そこにはもはや変数名も関数名も、コメントも存在しない。

だがその内部には、**意味が、構造が、意図が、消えずに残っている。**

本章では、「リバースエンジニアリングとは何か」を問い直しながら、  
バイナリという**言語を持たない存在から、いかにして意味を再構成するか**を、  
技法・思考法・設計倫理の視点から掘り下げていく。

---

## バイナリ解析とは何か？

バイナリ解析とは、コンパイル済み・最適化済みのコードを逆方向に辿り、  
- **構造を明らかにする**  
- **挙動を理解する**  
- **時に再実装や修正、パッチを当てる**

ための**思考的作業と技術的手続きの総称**である。

これは単なる「バイナリを読む」行為ではない。  
**意図の痕跡を集め、構造へと再構成する“意味の考古学”**である。

---

## リバースエンジニアリングのモチベーション

- ドキュメントのないライブラリの挙動把握  
- 廃止されたシステムやソフトのメンテナンス  
- セキュリティ検査（脆弱性分析、マルウェア解析）  
- 古いゲームやアプリのMOD・翻訳・移植  
- 知的探究と構造理解そのもの

→ 共通しているのは、「**表面からでは辿り着けない構造に触れる行為**」という点にある。

---

## 使用される代表的ツールと手法

### 静的解析

- `Ghidra`：NSA製、逆コンパイル支援・構造解析が強力  
- `IDA Pro`：業界標準、シンボル推定・関数ツリー構成に優れる  
- `radare2` / `Cutter`：CLIベース、柔軟なカスタム解析が可能

### 動的解析

- `x64dbg`：Windowsバイナリの動作確認に最適  
- `gdb`：UNIX系での実行中割り込み・ステップ実行  
- `Frida`：動的インジェクションによる関数フックやシステムAPI監視

### 補助技術

- Hex Editor（Hiew, 010 Editor）  
- `strace` / `ltrace`：システムコール・ライブラリ呼出の追跡  
- バイナリ差分ツール（BinDiff等）

---

## アセンブリの“構文なき構造”を読む

アセンブリによって逆解析されたコードには：

- 関数名 → `_sub_401000`  
- 変数名 → `[ebp-0xC]`  
- 文字列 → `.rodata`セクションから参照されるポインタ

というように、**人間が読むべき「意味」がすべて剥がれている。**

ここで求められるのは、**構造の再構築能力**である。

---

## 技法1：命令の流れから関数構造を推定する

```nasm
push ebp
mov ebp, esp
sub esp, 0x20
...
leave
ret
```

→ これは関数プロローグ／エピローグの典型構造  
→ **関数の開始と終了をマーカーとして特定し、機能単位を切り出す**

---

## 技法2：ジャンプ・ループ・比較からロジックを復元する

```nasm
cmp eax, ebx
jge .label1
call _exit
```

→ `if (a < b) exit();` のような構造が想定される  
→ 条件分岐パターンとラベルの関係性から**高級言語的ロジックを再構成**する

---

## 技法3：文字列やシステムAPIから用途を想像する

```nasm
mov eax, offset aOpenFile ; "open_file"
call _fopen
```

→ ソースコードが無くとも、関数名や定数文字列の意味から  
**“何をしている関数なのか”を帰納的に構築**できる。

---

## 実際のリバース事例：シリアル検証バイナリ

例：プロダクトキーを入力して認証するEXE

手順：

1. 入力処理をフックして、入力値を観察  
2. `strcmp`や`memcmp`などの呼び出しを探し、条件ジャンプを追う  
3. 比較対象（正解キー）がバイナリ内に露出していれば抽出  
4. 演算処理を逆算して、**“鍵の生成アルゴリズム”を再構築**

→ **数学・論理・構文解析が融合した知的アクション**

---

## 倫理的側面とグレーゾーン

### 正当性があるケース：

- セキュリティ研究（自己所有バイナリ）  
- OSSでなくなったアーカイブソフトの延命  
- 社内ソフトウェアの仕様解析

### 問題があるケース：

- 不正な複製・違法なクラックパッチ  
- 著作権を明示的に侵害する再配布

→ リバースとは「技法」ではなく、**目的と態度によって意味づけられる行為**である。

---

## 結語：読むべきものは、構文ではなく構造である

バイナリとは、構文を失ったコードだ。  
だが、構造は依然としてそこにある。

それを読み、再構成し、語り直す技法として、リバースエンジニアリングがある。  
それは破壊ではなく、**設計への共感と、意味の復元という再創造行為**なのだ。

> _"コードが黙っていても、構造は語る。アセンブリはその声を聞き取るための最も精密な言語である。"_
LLVMと中間表現：アセンブリを抽象化する試み



> _"構造の自由は、構造を抽象化したときに初めて獲得される。"_  

アセンブリはハードウェアに最も近い言語であり、  
最適化・制御・構造の記述において比類なき透明性を持つ。  

だが、その極端な具体性ゆえに、**言語間共通性の獲得や再利用性、移植性において限界**があった。  
そのジレンマに対するひとつの回答が、**LLVM Intermediate Representation（IR）**である。

この章では、LLVMという**抽象的アセンブリのような構造**がいかにして成立し、  
**低レイヤ制御を保持しつつ、アセンブリの柔軟性を拡張可能な形に再定義**しようとしているのかを紐解く。

---

## LLVMとは何か？

LLVMは、元々「Low-Level Virtual Machine」の略であったが、現在ではその意味を超え、  
**コンパイラ構築のためのモジュラーフレームワーク**として定義されている。

その中心は「LLVM IR（Intermediate Representation）」と呼ばれる**中間表現**にある。

このIRは：

- **アセンブリに近い命令セット**  
- **SSA（静的単一代入形式）ベースの構造**  
- **ターゲット非依存**（ARM, x86, RISC-V すべてに変換可能）  
- **高度な最適化パスを内包**

→ それはつまり、**“アセンブリの抽象構文化”**である。

---

## LLVM IRはアセンブリなのか？

### ある意味では「Yes」

- `add`, `sub`, `load`, `store`, `br` など、**命令は非常にプリミティブで汎用的**  
- メモリモデル、レジスタ代替（仮想レジスタ）、分岐命令なども保持

### だが本質的には「構造抽象記述言語」である

- 型情報が必須：`i32`, `float`, `ptr` などが静的に付与  
- SSA構造により、**すべての変数は一度しか代入されない**（最適化容易）  
- 実行不可：**最終的にネイティブコードにトランスレートされることが前提**

---

## LLVM IRの構造：例と比較

### Cコード：
```c
int add(int a, int b) {
    return a + b;
}
```

### LLVM IR：
```llvm
define i32 @add(i32 %a, i32 %b) {
entry:
  %sum = add i32 %a, %b
  ret i32 %sum
}
```

ここで注目すべきは：

- `define`：関数定義  
- `i32`：明示的な型付け  
- `%sum`：SSA形式による単一代入  
- `add`：**機能的にアセンブリのADD命令に対応するが、文脈に柔軟性を持つ**

---

## LLVMの最適化パイプライン：構造変換の哲学

LLVMは以下のような“Pass”によって、IRに対して**段階的かつ柔軟な最適化**を行う：

- Constant Folding  
- Dead Code Elimination  
- Loop-Invariant Code Motion  
- Inlining  
- Vectorization  
- Memory-to-Register Promotion

→ すべてのパスは**アセンブリ命令ではなく、“構文構造”に対して作用する**。

→ これはつまり、**意味的構造の再構成により性能を向上させる試み**である。

---

## なぜ“中間”である必要があるのか？

### 問題：

- 高級言語（C, Rust, Swiftなど）は多種多様  
- アーキテクチャ（x86, ARM, WebAssembly）も多様

### 解決策：

- 中間表現を**中立かつ機能的な媒介層**とすることで、  
  - 前段階（言語からの変換）と  
  - 後段階（命令セットへの射影）を分離可能にする

→ これにより、**「意味の構造を保ったまま、任意のマシン語に変換可能」**という柔構造が実現する。

---

## アセンブリとの距離：違いと接続性

| 項目 | アセンブリ | LLVM IR |
|------|------------|---------|
| ハードウェア依存性 | 強い | 弱い（抽象化） |
| 実行可能性 | 直接実行可 | 実行には変換必要 |
| 最適化自由度 | 手動 | 自動（passによる） |
| 可搬性 | 極端に低い | 高い |
| 構文構造 | 命令列重視 | SSA構造・型重視 |

→ LLVM IRは「抽象アセンブリ」とも言えるが、  
**むしろ“意味の構造を保持した可変アセンブリ”として捉えるほうが正確**かもしれない。

---

## LLVMのもたらした思想的転換

LLVMは、アセンブリが持っていた：

- 高い表現力  
- 制御構造への完全なアクセス  
- 命令粒度の精緻な制御

という利点を残しつつ、以下を加えた：

- 抽象構造の再利用可能性  
- 意味論的最適化の統合  
- マルチアーキテクチャ対応の柔構成

つまり、**アセンブリの“構文的限界”を乗り越える試み**である。

---

## 結語：中間表現とは、意味を保持したまま再構成可能な構造である

アセンブリが「具体的すぎた」なら、  
LLVM IRは「構造の自由を手にしたアセンブリ」である。

LLVMの登場により、アセンブリは“消える”のではなく、  
**より広い文脈で再利用されうる設計単位として昇華された**。

> _"中間であること。それは妥協ではなく、あらゆる意味をつなぐための設計思想である。"_
フロントUI_Chrome134

## カスタマイズ可能なselectタグ
appearance: base-select を付けると、ボタンやリストを好きなデザインに。
::picker(select) / ::picker-icon / ::checkmark など新しい疑似要素で細部まで装飾でき、
imgタグやdivタグも中に入れられるように
![selectタグ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740465/e65ee408-c3ac-4e7f-a9b0-9fcecb584697.gif)


## dialogタグのclosedby属性
ダイアログのクローズ動作を細かく制御できる新しい属性。ユーザーがどのような操作でダイアログを閉じられるかを指定できます。

![dialog_closeby.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740465/5f5d3286-c679-4750-a4c1-014582ae88c3.gif)
BluetoothでAndroid→Macにファイル送信ができない!

# はじめに
これは参考文献のページを抜粋しただけの激薄で簡単な記事です。
備忘録的なものです。

# 端末情報
Mac: Mac Book Air
OS: macOS Monterey(12.7.6)

Android: OPPO Reno 5A
OS: ColorOS12, Android12

# 問題
Android側からMacにファイルや写真を転送したいが、毎回失敗する。
ペアリングはできている。
なのに何故...?

# 解決
Macの設定/共有/BlueTooth共有をONにするだけ。
(英語なのはイキってるだけ、ゆるして)
![共有アイコン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233141/6da26e24-0346-4dbb-be45-1eedc8544f93.png)
![共有の設定の、BlueTooth共有画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233141/bcd4d486-c955-4431-9c5a-0bd88b496f3c.png)

最新バージョンとは設定画面のUIも全く違うが、まあ、これに該当しそうな場所に行けばある。
ここをONにして、BlueTooth共有をすると、すぐに完了した。
**これだけ**のせいでどんだけ苦労したと思ってるの...

# 参考文献
MacからBluetooth接続でデータは送信できるのに受信できない時の対処法, MICOS DESIGN CAFE
https://micos-design.com/mac-bluetooth/ (閲覧日: 2025-05-13)
【はじめまして】非IT企業からSalesforceエンジニアを目指す人の話

# 自己紹介
はじめまして、とりあしです！



現在は非IT企業でSalesforceとはまったく関係のない業務を担当しつつ、
社内でのSalesforce導入・推進を二足のわらじでやっています。

2023年頃にSalesforceと出会い、社内の業務改善がきっかけでSalesforceの可能性に気づき
資格取得やSalesforceの勉強を始めました。

今ではSalesforceを推進するメンバーとして社内アプリ開発を担当しながら、
日々、試行錯誤しつつスキルアップに励んでいます！

※情報系の専門学校卒 → 一時期プログラマ経験あり
「完全未経験」というわけではありません・・・がブランクはある状態です。


# 資格とこれからの目標
■ 取得済み資格（Salesforce）2025年5月時点：
- アドミニストレーター
- Platformアプリケーションビルダー
- Platformデベロッパー
- Dataアーキテクト
- Sharing and Visibilityアーキテクト
- アプリケーションアーキテクト

■ 今後の取得予定：
- システムアーキテクト
- SalesCloudコンサルタント

■ 将来の目標：
- 非IT業界からSalesforceエンジニアとして転職し、キャリアを確立すること。
- 設計・構築・導入支援など幅広く対応できるSalesforceのスペシャリストを目指しています。
- Salesforceでお金を稼いで、たくさんお肉を食べること🍖


# 今後書く予定の内容
こんな記事を今後投稿予定です：
- Salesforce資格ごとの勉強法と体験談
- Salesforceの学んだことのアウトプット
- 開発時の困りごと、解決方法など

# 最後にひとこと
Salesforceに挑戦している方、これから学び始める方、
どなたでも気軽にコメント・フォローしてもらえると嬉しいです

よろしくお願いします！
「手探りでCUI OS作成に挑む」関数説明篇　to_upper（小文字→大文字変換）

## 「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。

## 目的
文字列に含まれている小文字を大文字へ変換する。

## 検証コード
```boot.asm
[org 0x7C00]
[bits 16]

start:
    ; 画面クリア
    mov ax, 0x0003
    int 0x10
    
    ; 変換前の文字列を表示
    mov si, original_msg
    call print_string
    mov si, test_str
    call print_string
    call new_line
    
    ; 変換関数呼び出し
    mov si, test_str
    call to_upper
    
    ; 変換後の文字列を表示
    mov si, converted_msg
    call print_string
    mov si, test_str
    call print_string
    
    hlt

; 大文字変換関数の実装
to_upper:
    pusha
.loop:
    lodsb
    test al, al
    jz .done
    cmp al, 'a'
    jb .next        ;al < 'a' → 小文字より前 → 除外（.nextへ）
    cmp al, 'z'
    ja .next        ;al > 'z' → 小文字より後 → 除外（.nextへ）
    sub al, 0x20    ;大文字のASCIIコードから16進数で20を引くと大文字になる
    mov [si-1], al
.next:
    jmp .loop
.done:
    popa
    ret

; 改行
new_line:
    mov ah, 0x0E
    mov al, 0x0D
    int 0x10
    mov al, 0x0A
    int 0x10
    ret

print_string:
    pusha
    mov ah, 0x0E
    mov bh, 0
.print_loop:
    lodsb
    test al, al
    jz .done
    int 0x10
    jmp .print_loop
.done:
    popa
    ret

; 测试数据
test_str       db 'Hello, World!',0
original_msg   db 'Original: ',0
converted_msg  db 'Converted: ',0

times 510-($-$$) db 0
dw 0xAA55
```
小文字から16進数で20を引くと大文字となる
| 小文字 | ASCII(16進) | ASCII(10進) | 対応大文字 | ASCII(16進) | ASCII(10進) |
|--------|-------------|-------------|--------------|-------------|-------------|
| 'a'    | 0x61        | 97          | 'A'          | 0x41        | 65          |
| 'b'    | 0x62        | 98          | 'B'          | 0x42        | 66          |

## 動作確認
```
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/8c58fe77-03cb-4d52-af0f-6557e492641b.png)
あ

import streamlit as st
import pdfplumber
import pandas as pd
import re
import mistune  # 高速Markdownパーサ

st.set_page_config(page_title="PDF → Markdown 抽出ツール", layout="wide")
st.title("📄 PDFをMarkdownに変換してテキスト・表を抽出")

# Markdownに整形する関数
def text_to_markdown(text):
    lines = text.split('\n')
    md_lines = []

    for line in lines:
        line = line.strip()
        if not line:
            continue

        # セクションっぽい行
        if re.match(r"^[0-9０-９]+[\.\．、)]\s*", line):
            md_lines.append(f"## {line}")
        # 表っぽい行（スペース or タブ区切り）
        elif '\t' in line or re.search(r'\s{2,}', line):
            cells = re.split(r'\t+|\s{2,}', line)
            md_lines.append('| ' + ' | '.join(c.strip() for c in cells) + ' |')
        else:
            md_lines.append(line)

    return '\n'.join(md_lines)


# Markdown ASTからテーブルとテキストを分離
def parse_markdown(md_text):
    markdown = mistune.create_markdown(renderer=mistune.AstRenderer())
    ast = markdown(md_text)

    tables = []
    texts = []

    for block in ast:
        if block['type'] == 'table':
            headers = [h['text'] for h in block['header']]
            rows = []
            for row in block['cells']:
                rows.append([cell['text'] for cell in row])
            df = pd.DataFrame(rows, columns=headers)
            tables.append(df)
        elif block['type'] in ['paragraph', 'heading']:
            texts.append(block['text'])

    return texts, tables


# メイン処理
uploaded_file = st.file_uploader("PDFファイルをアップロードしてください", type=["pdf"])

if uploaded_file:
    uploaded_file.seek(0)
    all_text = ""
    with pdfplumber.open(uploaded_file) as pdf:
        for page in pdf.pages:
            page_text = page.extract_text()
            if page_text:
                all_text += page_text + '\n'

    if not all_text.strip():
        st.warning("PDFからテキストを抽出できませんでした。画像型PDFの可能性があります。")
    else:
        md_text = text_to_markdown(all_text)
        st.subheader("📝 Markdown形式に変換されたテキスト")
        st.code(md_text, language="markdown")

        st.download_button(
            "Markdownをダウンロード",
            data=md_text,
            file_name="extracted.md",
            mime="text/markdown"
        )

        # Markdownパースして表示
        st.subheader("📃 テキスト抽出結果")
        texts, tables = parse_markdown(md_text)

        for i, txt in enumerate(texts):
            st.markdown(f"**段落 {i+1}**\n\n{txt}")

        st.subheader("📊 表抽出結果")
        if tables:
            for i, df in enumerate(tables):
                st.markdown(f"**表 {i+1}**")
                st.dataframe(df)
                csv = df.to_csv(index=False).encode("utf-8-sig")
                st.download_button(
                    f"表 {i+1} をCSVでダウンロード",
                    data=csv,
                    file_name=f"table_{i+1}.csv",
                    mime="text/csv",
                )
        else:
            st.info("表は見つかりませんでした。")
「手探りでCUI OS作成に挑む」関数説明篇　print_string（文字列表示）

## 「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。

## 目的
db命令で設定された文字列を画面上に表示する。

## 検証コード
```boot.asm
[org 0x7C00]
[bits 16]

start:
    ;レジスタの初期化
    xor ax, ax
    mov ds, ax
    mov es, ax

    
    mov si, msg1      ;siをmsg1に登録された文字列の一文字目`h`の番地を入れる
    call print_string
    
    mov si, msg2
    call print_string

    ;CPU停止
    cli
    hlt

print_string:
    pusha
    mov ah, 0x0E     ;1文字出力
    mov bh, 0
.print_loop:
    lodsb            ;SIの示すアドレスから1バイトをALに読み込み、SIを+1（次の文字へ）
    test al, al      ;alが0かどうかを確認する
    jz .done         ;文字が 0 か（＝終端記号か）を確認。※'hello',0　文字列の最後に目印の0を入れている
    int 0x10         ;BIOS割り込みで AL の文字を表示
    jmp .print_loop
.done:
    popa
    ret

msg1 db 'hello',0
msg2 db 'world',0

times 510-($-$$) db 0
dw 0xAA55

```

## 動作確認
```
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/8ffc0cff-4c81-47bb-8f93-0a4f5d48dabf.png)
ショート動画多すぎ

# 普通の動画がみたいんです！

最近って訳でもないですが、ショート動画多いですよね。
特に、AI関連の動画を２４時間以内の新規動画とかで検索するとAIでつくったショート動画が死ぬほど引っかかります。
長さでフィルターすればよいのかもと思わないでもないんですがフィルターも微妙に使い勝手が悪いです。

しょうがないので、ショート動画をフィルタするプラグインを作ってみました。


https://github.com/chaftta/YoutubeShortBlocker

ショート動画っぽいタグ検索して、非表示にするだけなので特に開設する部分もありません。
あっ、そういえばyoutubeの表示言語を日本語表示している必要があるかもです。（雑

自分用に作ったものですので、細かいところは気にしない作りなっているのはお許しください。
「手探りでCUI OS作成に挑む」関数説明篇　clear_screen（画面クリア）

## 「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。


## 目的
この関数は、画面を真っ白にしたい時に使う基本命令です。

## 検証コード
テキストモード80x25を設定するとBIOSが画面を初期化するので、現在表示されている文字が全て消去される。
```
[org 0x7C00]
[bits 16]

start:
    call clear_screen  ; 関数呼び出し
    hlt               ; CPU停止

clear_screen:
    mov ax, 0x0003    ; 80x25テキストモード
    int 0x10
    ret

times 510-($-$$) db 0
dw 0xAA55
```

## 動作確認
```
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/6c66cb8a-eba1-4eff-a526-5917789f7508.png)