OmniAICreator/Qiita-1.07M huggingface dataset:
JWT (JSON Web Token) とは？（メモ）

## はじめに

✅ **JWT (JSON Web Token)** は、**ユーザーの認証情報を含むデータを安全にやり取りするためのトークン形式** です。  
✅ **Cognito では、ユーザー認証後に JWT トークン (AccessToken, IDToken, RefreshToken) を発行します。**

---

## **🔹 JWT トークンの構造**
JWT は以下の **3つの部分** で構成されます。

```
eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzMGE4ZTQ4NyJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZSIsImlhdCI6MTUxNjIzOTAyMn0
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```
📌 **3つの部分**
| **部分** | **説明** |
|---------|---------|
| **1. ヘッダー (Header)** | 使用するアルゴリズムやトークンの種類を定義 |
| **2. ペイロード (Payload)** | ユーザー情報や権限 (claims) を含む |
| **3. 署名 (Signature)** | トークンの改ざんを防ぐための署名 |

---

## **🔹 Cognito で発行される JWT トークンの種類**
### **1️⃣ AccessToken**
- API Gateway で認証するときに使用
- Cognito ユーザープールで発行される
- 有効期限 **(デフォルト: 1時間)**

### **2️⃣ IDToken**
- ユーザー情報 (メール, 名前など) を含む
- フロントエンドアプリでユーザー情報を取得するときに使用

### **3️⃣ RefreshToken**
- アクセストークンの有効期限が切れた際に、新しいトークンを取得するために使用
- 有効期限 **最大 30日**

---

## **🔹 JWT トークンの内容を確認**
Cognito で取得した **AccessToken** をデコードすると、以下のような情報が含まれています。

### **📌 JWT デコード方法 (コマンドライン)**
```sh
echo $ACCESS_TOKEN | awk -F. '{print $2}' | base64 -d | jq .
```

### **📌 JWT デコード結果 (例)**
```json
{
  "sub": "1234567890",
  "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXX",
  "client_id": "4rap65b59one3tf6j36ec4b21d",
  "username": "example_user",
  "exp": 1742310338,
  "iat": 1742306738
}
```

**ポイント**
- `"sub"` → ユーザーID
- `"iss"` → トークン発行元 (Cognito の URL)
- `"client_id"` → このトークンが発行されたクライアント ID
- `"exp"` → トークンの有効期限 (UNIX 時間)
- `"iat"` → トークンが発行された時間 (UNIX 時間)

---

## **🔹 Cognito で JWT トークンを取得**
### **1️⃣ ユーザーログインして `AccessToken` を取得**
```sh
ACCESS_TOKEN=$(curl -X POST \
    -H "Content-Type: application/x-amz-json-1.1" \
    -H "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \
    --data @- https://cognito-idp.ap-northeast-1.amazonaws.com/ <<EOF | jq -r '.AuthenticationResult.AccessToken'
{
    "AuthFlow": "USER_PASSWORD_AUTH",
    "ClientId": "your-app-client-id",
    "AuthParameters": {
        "USERNAME": "your_username",
        "PASSWORD": "your_password"
    }
}
EOF
)
```

### **2️⃣ `AccessToken` を API Gateway に送信**
```sh
curl -X POST \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"action": "convert"}' \
    https://your-api-id.execute-api.ap-northeast-1.amazonaws.com/Prod/convert
```

---

## **🔹 JWT トークンのメリット**
✅ **トークンの検証だけでユーザーを認証できる (データベース不要)**  
✅ **トークンの改ざんができない (署名付き)**  
✅ **異なるサービス間 (API Gateway, Lambda) で統一した認証を実装できる**  

---

## **🚀 まとめ**
| **項目** | **説明** |
|----------|---------|
| **JWT とは？** | 認証情報を含むセキュアなトークン |
| **トークンの構造** | `Header.Payload.Signature` の 3つの部分で構成 |
| **AccessToken の用途** | API Gateway で認証に使用 |
| **トークンの取得方法** | Cognito にログインして取得 |
| **API にトークンを送信** | `Authorization: Bearer <TOKEN>` をヘッダーに設定 |
【AWK】特定のフィールドの値を取得する方法

## 特定のフィールドの値を取得する方法

以下のようなコマンドを実行すると、`sample.txt`内の空白をフィールドの区切り文字として2番目のフィールドの値を取得できます。

```terminal
awk '{print $2}' sample.txt
```

- `$1`：1番目のフィールド
- `$2`：2番目のフィールド
- `$3`：3番目のフィールド
- 以降同様

## 例

以下のようなサンプルデータを含むファイル `data.txt` を用意します。

```text:data.txt
Alice 25 Engineer
Bob 30 Designer
Charlie 22 Developer
```

## 各行の2番目のフィールドを取得

次のコマンドを実行して、各行の2番目のフィールド（年齢）を取得します。

```terminal
$ awk '{print $2}' data.txt
25
30
22
```

- `awk`：AWKコマンドを呼び出す
- `'{print $2}'`：各行の2番目のフィールドを出力する
- `data.txt`：処理対象のファイル名

## 複数フィールドの取得

複数のフィールドを取得することも可能です。例えば、名前と年齢を取得する場合は次のようにします。

```terminal
$ awk '{print $1, $2}' data.txt
Alice 25
Bob 30
Charlie 22
```

## 別の区切り文字を使用する

もしデータがカンマで区切られている場合、`-F`オプションを使用して区切り文字を指定できます。

```text:data.txt
Alice,25,Engineer
Bob,30,Designer
Charlie,22,Developer
```

```terminal
$ awk -F',' '{print $2}' data.txt
25
30
22
```
【Write Up】 picoCTF 2025 hash-only-1

# 問題

あるサーバー上でroot権限が付与されてるコードを使って権限昇格をしてみよう

# 解き方

ssh接続して、`flaghasher`という実行ファイルがあるので、まずこの実行ファイルを解析します。
ghidra等でデコンパイルを行うと、

[Web上でデコンパイル行ってくれるサイト](https://dogbolt.org/)

```shell
/bin/bash -c 'md5sum /root/flag'
```

これをsystem関数使って実行しているらしい

なんとなくmd5sumの権限を確認してみると、

![Screenshot_20250319_000007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/900d19c6-5a16-4aca-8305-0c7ae6ede09a.png)

<h3>なんで書き込み権限あんねんwww<h3>

`md5sum`を`cat`に置き換えたら

![Screenshot_20250319_000214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/7822392f-bab2-46d2-9ef7-2e76171183d8.png)

いけました
[Arch Linux] Elecomの古いwireless mouseを使う。

Elecomの古い2.4GHｚ帯ワイアレスマウスがあったので、x11を設定してみた。
マウスのモデルは、M-FIR08DRです。

/etc/X11/xorg.conf.d/30-mouse.confあたりに入れておきます。

```30-mouse.conf
Section "InputClass"
    Identifier "Wireless Mouse"
    MatchIsPointer "on"
    Driver "libinput"
    Option "AccelProfile" "flat"
    Option "AccelerationScheme" "none"
    Option "AccelSpeed" "0"
    Option "AccelerationNumerator" "2"
    Option "AccelerationDenominator" "1"
    Option "AccelerationThreshold" "4"
EndSection
```

そのままでは、コピーアンドペーストのコピーに選択範囲が自由にできなかったので、~/.Xresourcesに以下を書きます。

```~/.Xresources
*selectToClipboard: true
```

これで、動きました、
SFTPについて調べてみました！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/e645c2db-d4fb-4cef-853a-2db14b522c10.png)
こんにちは！
急ですが、SFTPとFTPSの違いって皆さん説明できますか？
私はできませんでした……。

そこで今回は、SFTPとFTPSの違いにも焦点を当てつつ、SFTPについて詳しく調べてみました！

# SFTPとは
SFTP（SSH File Transfer Protocol）は、エンドツーエンド暗号化された通信プロトコルで、安全なファイル転送を可能にします。FTPと同等の機能を持ちつつも、SSHトンネルを使用してデータ転送を保護します。インターネット上でファイルとデータを安全に送受信するための標準的な手段です。

<b>主な特徴は下記ですね。

- SSHを利用した安全なファイル転送 
- 単一ポートで動作（ポート22）
- 認証方式が豊富
- FTPとはコマンドやデータ転送のプロセスが統合されている異なる仕組み

# SFTPとFTPSの違い

次に、SFTPとFTPSの違いを整理してみましょう。
こう見ると結構違いがあることがわかります。

| 項目  | SFTP (SSH File Transfer Protocol) | FTPS (FTP Secure) |
|--------|--------------------------------|---------------------------|
| **基盤となる技術** | SSH (Secure Shell) | FTP + SSL/TLS |
| **使用ポート** | 22番ポートのみ | 21番ポート + 動的ポート |
| **データ暗号化** | SSHによる完全暗号化 | SSL/TLSによる暗号化 |
| **認証方法** | パスワード認証 / SSH鍵認証 | パスワード認証 / クライアント証明書 |
| **ファイアウォール設定** | シンプル（22番ポートのみ） | 複雑（PASVモードで動的ポート開放が必要） |
| **セキュリティ** | 高い（SSHのセキュリティ機能を利用） | 高いが、設定によっては脆弱性あり |


# SFTPをちょっとだけ触ってみる

それではSFTPをちょっとだけUbuntsで試してみようと思います。
FTPSは過去の記事で触ったのでスキップとします。
興味ある方は下記の記事を読んでみてください
https://qiita.com/keitakei777/items/a7a4ef912612be894503

### 1. SSHのインストール確認

基本、SSHは多くの環境で既存でインストール済みかと思います！
下記コマンドでインストールの確認をします。
```bash
sudo systemctl status ssh
```
Activeになっていたら問題ないのですが、見当たらないといわれたら下記でSSHインストールしましょう

```bash
sudo apt update
sudo apt install -y openssh-server
```


### 2. 接続テスト

WINSCPアプリを使用して接続確認をしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/0419d2ed-c577-48ac-8272-ffdb693f4290.png)

ログインしてみるとアクセスできました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/84ab16c4-5436-4957-9980-db8cc35bbea8.png)

SSHをインストールしただけですが、SFTPでアクセスできましたね！

# まとめ
SFTPをまとめてみました！
ファイル転送はシステムにおいて必ず必要なものであり、セキュアでなければなりませんね！ そんな中で今回紹介した、SFTPおよび過去に紹介したFTPSの選択は欠かせないものなので理解しておいて損はないかと思います！
[Write Up] picoCTF 2025 SSTI1

# SSTI 1 Write Up

## 問題

Formになにかメッセージいれるとh1タグでメッセージが表示されるWebSiteを攻撃する問題です。

![Screenshot_20250318_231510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/82b09ea5-2bca-4758-b1f7-560ed16c409a.png)

![Screenshot_20250318_231712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/e2405223-d20a-4d43-b6a4-25f7039cbc54.png)


## 解き方

まず、XSSを試しました。

```html
<script>alert();</script>
```

すると、このようにXSSが通るのでXSSを使って攻撃します。
![Screenshot_20250318_232001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/74c904df-62d9-4964-8883-40132b55b5e9.png)

問題文にSSTIとあったので、SSTIについて色々調べるとこのようなツールを見つけたので試しました。

- いろいろなツールの情報をまとめたやつ
[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md?ref=sec.stealthcopter.com)
- 今回使ったツール
[SSTIMap](https://github.com/vladko312/SSTImap)

```bash
python3 ./sstimap.py -M POST -u "http://rescued-float.picoctf.net:61219/" -d "content=hello" -s
```

| option | data |
|--------|--------|
| -M | Method |
| -u | URL |
| -d | data_column=data |
| -s | get a shell |

![Screenshot_20250318_233832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/880776dd-dd82-4d42-a49a-da1e6f59a6f1.png)


はい、このようにShellをgetできたのでとりあえずlsしたらflagがあったので終わりです。
![Screenshot_20250318_234143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079586/e949d3d0-2c08-4d8c-b2c1-e9e60b193d64.png)
[Blender]謎のクラッシュはこれで解決するかも？

# 概要
前までちゃんと使えていたアドオンが急にクラッシュするようになった:thinking:そんな時は以下の手順で解決するかもしれないです。

:::note warn
設定を全部リセットして初期状態にします。覚悟のある人だけやってください！
:::

# 解決方法

Edit > Preferences > 左下のボタン > Load Factory Preferences

![スクリーンショット 2025-03-19 191758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5eaf7539-1b04-4e0b-bee3-725cea462796.png)
統計検定準１級は2級＋αの努力で合格できる　~２級合格10日後に準１級を合格した話~

# はじめに
本記事では**統計検定2級取得者または同程度の知識を持つ方が、＋αの努力で準1級を最速で取得する方法**を解説します。統計検定2級自体の取得方法は他の方々の合格体験記を参考にしてください。

**私は統計検定2級にギリギリで合格してから10日後に準1級にギリギリで合格しました。**

![スクリーンショット 2025-03-18 222718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012527/745924eb-bcf4-409d-9116-d7fdab2cfa61.png)

![スクリーンショット 2025-03-18 222541.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012527/5b7f9d50-da5f-407a-8d4e-0d61fbc9d797.png)



どちらもギリギリで受かっていることから、”元々準１レベルの実力者が短期間で両方受けて受かっただけ”、ではありません。


ではどのようにしてこれを達成したのか？以下にポイントを列挙していきます

- **1. 準1級の問題は難易度の差が激しいと気付く**
- **2. 確実に解けるもの、何もわからないもの、半々で解けるもので 5 : 3 : 2にわける**
- **3. 簡単な前半で稼ぎ切り、後半は逃げる**

# 1. 準1級の問題は難易度の差が激しいと気付く

統計検定準１級では下記のワークブックをやり込むことが王道とされ、あらゆる体験記で紹介されています。
実際に自分も受けると決めてから速攻で購入しました。

**[日本統計学会公式認定 統計検定準1級対応 統計学実践ワークブック](https://amzn.asia/d/gBvihTJ)**


しかしながら、**あまりにも難しすぎる。...本番の試験と比べても。**

**バリマックス回転？** **Mステップ？** 
行間が端折られた説明が次から次へと情報の洪水のように流れてきます。
やはり準１級のハードルは高いか.... そう思うのは時期尚早です。

**先に準１級の過去問を一年分解いてください。**

そして、あなたは気付くはずです。

**そもそも問題によって難易度の差がデカすぎでは..?**


そうです。その通りです。

そして、後述の2.にて説明しますが、解ける問題を解き、解けない問題を飛ばし、残った問題の選択肢を半分に絞れば、**期待値上、合格点60点を超えることができます。**

また、難しい問題については、普段の練習で理解をしていたとしても結局本番で緊張して解ける可能性は低いため、コスパが非常に悪いです。

**そもそも本物の統計力を身に着けるためには長い修練が必要です。資格勉強においては所詮は資格と割り切って最短期間でコスパよく勉強していきましょう。**

# 2. 確実に解けるもの、何もわからないもの、半々で解けるもので 5 : 3 : 2にわける

**５割が解ける問題、3割が何もわからない問題、2割が半々で解けそうな問題なら、期待値的には60点で合格点60点ピッタリです。**

また近年の準一級の問題は選択式なので、何もわからないといってもまぐれで数問は当てることができるでしょう。

なので65点ぐらいはこの方針で獲れるはずです。

まさに自分も67点で合格しているので、このケースに該当します。

繰り返しますが**全体の半分は2級でも出てくるような問題**です。

あなたが既に2級を合格している場合、第一関門は突破しています。

あとは**いかに残りの半分の問題を、何もわからない問題から半々で解けそうな問題に変えていくかだけ**です。
それも40%さえ達成できれば、0.5×0.4 = 0.20で20%の半々で解ける問題を手に入れることができます。

逆に**解ける問題が全体の4割以下しかない場合、シンプルに２級レベルの地力が欠けている可能性が高い**
ので、準１級ではなく２級の過去問に戻って問題演習を繰り返しましょう。


# 3. 簡単な前半で稼ぎ切り、後半は逃げる。
私の合格結果を見てください。セクション1,2の得点率はどちらも80%以上、セクション3,4の得点率はどちらも60%未満です。芸術的ですね。

**試験では難問を解けることより解けるはずの問題を落とさずに解き切ることの方が100倍重要です。**

後半の問題に時間を使い過ぎないでください。前半の問題にケアレスミスがないかを何回も何回も計算して確かめてください。


これらの戦略で、あなたもきっとコスパよく準１級を取得することができるはずです。
Java。文字列の改行コードをCRLFからLFに変換

null の場合は例外を発生させず、空文字 "" を返す。
replace("\r\n", "\n") を使用して CRLF を LF に変換。

```java
public class LineSeparatorConverter {
    public static String convertCRLFtoLF(String input) {
        if (input == null) {
            return ""; // nullを空文字列に変換
        }
        return input.replace("\r\n", "\n");
    }

    public static void main(String[] args) {
        String test1 = "Hello\r\nWorld\r\n!";
        String test2 = null;

        System.out.println("Converted String 1:");
        System.out.println(convertCRLFtoLF(test1));

        System.out.println("Converted String 2:");
        System.out.println("[" + convertCRLFtoLF(test2) + "]"); // 空文字で囲んで表示
    }
}
```
"管理"に潜む３つの性質


私は "管理" という単語が好きではありません。
あまりにも便利に、気軽に、都合よく解釈されてしまうからです。

"管理"という単語の裏に隠れている性質を整理してみます。

それは

* **Administration（アドミニストレーション）**
* **Control（コントロール）**
* **Management（マネジメント）**

です。

---

### **1. Administration（アドミニストレーション）**

**目的**
定められたプロセスやルールを遂行すること。運営・事務管理。

**主な特徴**
- プロジェクトの **手続きやルールに従い、計画通りに業務を遂行** することに焦点を当てる
- 一般的に、**書類管理、スケジュール調整、会議運営、契約管理** など、決められたプロセスの実施やサポートを指す
- **創造的な意思決定や問題解決というより、既存のルールの実行が中心。**

**例**
- プロジェクトの進捗報告書を定期的に作成し、関係者に提出する
- 予算の支払い処理や契約書管理を行う
- 事務手続き（例: メンバーの出張手配、会議の調整）を行う

---

### **2. Control（コントロール）**

**目的**
状況を監視し、計画と実績のズレを是正（問題発生時の修正）すること。

**主な特徴**
- プロジェクトが計画通りに進んでいるかを **監視・測定し、必要に応じて修正** することに重点を置く
- 事前に定めた基準や KPI（Key Performance Indicators）と比較し、問題があれば **修正アクションを実行** する
- 事後対応ではなく、**リスクを未然に防ぐための監視** も含む

**例**
- 進捗状況を確認し、遅延が発生している場合は対策を講じる
- 予算の消費状況をモニタリングし、オーバーしそうな場合はコスト削減策を実施する
- 品質基準に沿っているか検査し、不合格なら是正処置を指示する

---

### **3. Management（マネジメント）**
**目的**
目標達成のために意思決定し、リソースを最適に活用し、不確実な状況をなんとかすること。

**主な特徴**
- 目標を達成するために、**計画・調整・指揮・意思決定・改善を行う**
- 事務的な作業（Administration）や状況の監視・修正（Control）を含みつつ、**戦略的に方向性を決めることが主な役割**
- **リソースの最適化**（人材、予算、スケジュールの調整）、**優先順位の決定**、**リスクマネジメント** などを含む

**例**
- プロジェクトの方向性を決め、関係者と合意形成を行う
- 突発的な問題（予算不足・要件変更）が発生した際、解決策を決定する
- チームのモチベーションを管理し、生産性を高める施策を考える

---

### **3つの違いのまとめ**
| 項目 | 役割 | 具体的な活動 | 例 |
|------|------|------------|----|
| **Administration（アドミニストレーション）** | ルールに従い運営・事務処理を遂行 | 書類管理、スケジュール調整、契約管理 | 進捗報告書作成、会議設定、支払い処理 |
| **Control（コントロール）** | 状況を監視し、計画と実績のズレを是正 | 進捗・コスト・品質のモニタリング、修正措置 | 遅延対応、品質基準チェック、コスト調整 |
| **Management（マネジメント）** | 目標達成のための意思決定と最適化 | 計画、調整、意思決定、戦略策定 | 目標設定、リスク管理、組織調整 |

---

### **プロジェクトマネジメントの視点での関係性**
1. **Administration** は、プロジェクトを円滑に進めるための「オペレーション（事務・運営）」
2. **Control** は、プロジェクトの状況を監視し、計画とズレたら修正する「チェック（モニタリング・監視）と調整」
3. **Management** は、プロジェクト全体の目標を達成するために「不確実な状況を戦略的に意思決定しながらなんとかする」する役割

---

### **結論**
**「マネジメント」は単なる事務処理（Administration）でもなく、計画通りに進めるための監視（Control）だけでもなく、**  
**最終的な目的達成のために、計画・実行・調整・意思決定を含む包括的な活動である。**

この違いを理解すると、「マネジメント」が単なる管理業務ではなく、**価値を生み出すためのリーダーシップと意思決定のプロセス** であることが明確になります。

自戒のため。
【React Jest】react-routerでLinkの遷移テストが成功しない場合の解決方法について

# はじめに
ReactのテストでLinkの画面遷移テストが上手くいかなかったため、解決方法について共有させていただきます。


# バージョン
react v19.0.0
react-router v7.3.0
testing-library/react v16.2.0
jest v29.7.0

# エラー内容

遷移できていないようです。
```.tarminal
 expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: "/cards/register"

    Number of calls: 0

    Ignored nodes: comments, script, style

     150 |     // 新規名刺登録ページに遷移したことを期待する
      151 |     await waitFor(() => {
    > 152 |       expect(mockNavigate).toHaveBeenCalledWith("/cards/register");
          |                            ^
      153 |     });

```

コード内容抜粋
```.spec.tsx

const mockNavigate = jest.fn();
jest.mock('react-router', () => ({
  ...jest.requireActual('react-router'), // 元のモジュール内容を展開
  useNavigate: () => mockNavigate, // useNavigate だけを上書き
}));


describe("Home Component", () => {

  it("新規登録はこちらを押すと/cards/registerに遷移する", async () => {
    render(
      <BrowserRouter>
        <Home />
        <Register />
      </BrowserRouter>
    );
   
    
    // Loading...が消えるのを待つ
    await waitFor(() =>
      expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
    );
  
    // Linkを取得
    const registerLink = screen.getByRole("link", { name: "新規登録はこちら" });
   
    // Link先が正しいことを確認
    expect(registerLink).toHaveAttribute('href', '/cards/register');

    // リンクをクリック
    await userEvent.click(registerLink);

    // 新規名刺登録ページに遷移したことを期待する
    await waitFor(() => {
      expect(mockNavigate).toHaveBeenCalledWith("/cards/register");
    });
  });

});

```

# 解決方法
MemoryRouterを使用する

```.spec.tsx

const mockNavigate = jest.fn();
jest.mock('react-router', () => ({
  ...jest.requireActual('react-router'), // 元のモジュール内容を展開
  useNavigate: () => mockNavigate, // useNavigate だけを上書き
}));


describe("Home Component", () => {

  it("新規登録はこちらを押すと/cards/registerに遷移する", async () => {
    
    render(
      <MemoryRouter initialEntries={['/']}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/cards/register" element={<Register />} />
        </Routes>
      </MemoryRouter>
    )
    
    // Loading...が消えるのを待つ
    await waitFor(() =>
      expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
    );
  
    // Linkを取得
    const registerLink = screen.getByRole("link", { name: "新規登録はこちら" });
   
    // Link先が正しいことを確認
    expect(registerLink).toHaveAttribute('href', '/cards/register');

    // リンクをクリック
    await userEvent.click(registerLink);

    // 新規名刺登録ページに遷移したことを期待する
    await waitFor(() => {
      expect(screen.getByTestId('register-page')).toBeInTheDocument();
    });
  });
  
});

```

# 参考
https://reactrouter.com/6.30.0/router-components/memory-router


# おわりに
MemoryRouter便利ですね。

<br>

[<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3707255/8bfacf61-7d8d-6d27-cb07-98d1f8f27fcd.png"  width=100%>](https://projisou.jp)
ASTERIA Warp フローデザイナー画面構成

### フローデザイナー画面構成について
※フローデザイナー2206バージョンです。
![2025-03-18_214731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/68ec1165-24c6-4421-aa8a-b5efc85be65e.png)

![2025-03-18_222312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/62c0b57e-fffb-4350-ad11-9b220e83504a.png)


#### コンポーネント
コンポーネントとは、フローの中である特定の機能を持って処理を行う単位で、フローデザイナーではアイコンで表示されます。処理手順どおりにそれを線で連結していき、設計・開発を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/4e1959ba-634f-446c-9317-65444d29848f.png)



#### コンポーネントのプロパティ
コンポーネントで処理するために必要な情報のことをコンポーネントプロパティといい、フローデザイナーのインスペクタで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/23d6a10e-57a2-4d2e-a2fb-5f891e13242c.png)


#### ストリーム
ストリームとは、フロー上を実際に流れるデータです。フローサービス独自のストリーム型と呼ばれるフォーマットは以下の９種類です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/1709160c-ed3f-4b1b-9121-c37f0b786aac.png)


```
XML / CSV / FixedLength / Record / ParameterList / MIME / HTML / TEXT / Binary
```


#### マッパー
データのマッピングに特化したMapperコンポーネントのことをマッパーといいます。フローデザイナーでマッパーをダブルクリックするとマッピングウィンドウが表示され、マッピングウィンドウ上で入力ストリームと出力ストリームのそれぞれのフィールドをグラフィカルにつなぐことで、データの差し込みの設計ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/efed5fca-13fe-4738-8d76-6323ebaa41e2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/cb2b0f0d-63c4-4ce3-902c-c02708ae16b0.png)

![2025-03-18_222710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/421d091a-0920-4140-aa84-90fdc823e107.png)

![2025-03-18_223714.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/1e051309-5582-4528-90e6-c3770438347e.png)


#### マッパー関数
マッパー関数とは、マッパーの中である特定の機能を持って処理を行う単位で、マッピングウィンドウではアイコンで表示されます。入力のデータに対して、文字列の操作、数値の演算、日付の操作、条件判断、整形などのデータ変換を行った結果を出力のデータとすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/4fa04dc1-b1df-44fa-8e98-d84f8987d216.png)

#### 関数プロパティ
マッパー関数で処理するために必要な情報のことを関数プロパティといい、フローデザイナーのインスペクタで設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463540/3e780aaf-17f3-4ad6-bee7-3d3d8390df12.png)




参考資料

https://help.asteria.com/documentation/warp/ja/4.9/flow/designer/flowservice/flow.html#flow_component

https://asteria.jp/documentation/files/ASTERIA_WARP_tutorial.pdf
記事を書いてみようと思ったことについて

## きっかけ
本サイトにて記事を書いていこうと思い立ったきっかけは、純粋に未経験エンジニアとしてもう1年が過ぎようとしているということです。

私は24卒の新卒として未経験でエンジニアとして就職し、ありがたいこと日々開発などを行えております。

最近25卒の内定者の方々との交流の機会があり、「もうあっという間に1年も経ってしまったのか...」と危機感を覚えました。

自分自身の今後のキャリアのために **「強くなりたい！」** という気持ちが非常に強くなって来ました。

資格を取ったりなどの行動は少しこなしたりはしていましたが、具体的にもっと基本的で基礎的な内容を固められたらなと、自分の目的と行動がずれているという感覚も感じていました。

そんななか、中途で入って来た後輩？（おそらく年上な方を後輩と呼ぶにはむずむずするが）のコードレビューをする機会が増えて来た。

そのレビューで感じたのは、自分がなんとなくで頭の中に入れている知識を　**「自分の言葉で言語化する」** という経験は自分自身を成長させるのに非常に有用であるということでした。

これらのこともあり、本サイトにて、日々私が学んだことを、自分なりの言葉で言語化していこうと思い立ち、最初の記事を書いているという状況になります。

---

### 具体的にどうしていくか

こういった行動をしていくにあたって、「１週間に3本投稿！」といったような目標を立てると、本来の目的と手段を勘違いしてしまうことになりかねません。

私自身gitに草を生やそうと目標を立てたところ、それが目的になってしまい、結局うっすい内容のコミットを日付が変わるギリギリに毎日行う落ち雨なんとも本末転倒な結果になってしまった過去があります。

ですので、特段ペースやノルマを決めることなく、自分自身の強さへの渇望をモチベーションに思いつきで書いていこうと思います。

今この記事を書いていても思うのですが、先達の方々は非常に読みやすい記事を書いてるのだなと実感しています。
そういった面でもなるべく成長していけたらう良いなと思うので、この読みにくさも味と考えてみてくださる方がいらっしゃったら幸いです。
Windows入門：`icacls` コマンドで `.pem` ファイルのアクセス権を設定する方法について

## はじめに
Windows で `.pem` ファイルを扱う際、適切なアクセス権を設定しないと、セキュリティ上のリスクが発生する可能性があります。

:::note warn
**特に、秘密鍵ファイルは第三者に漏洩すると重大な問題を引き起こすため、適切な権限設定が重要です。**
:::

本記事では、`icacls` コマンドを使用して `.pem` ファイルのアクセス権を適切に管理する方法を解説します。

## 書こうと思ったきっかけ
Windows で `.pem` ファイルの適切なアクセス権を設定する方法を調べている際に、`icacls` コマンドを活用することでセキュリティを強化できることを知りました。

:::note info
**同様の課題に直面する人のために、具体的な手順と注意点を整理しようと思いました。**
:::

また、コマンドの意味を理解することで、安全なファイル管理ができるようになります。

本記事では、

```
icacls xxx.pem /inheritance:r /grant:r "$($env:USERNAME):R"
```

の意味とその用途について解説します。

## コマンドの解説
このコマンドは、Windows のアクセス制御リスト（ACL）を管理する `icacls` を用いて、`.pem` ファイルのアクセス権を設定するものです。

- **`icacls xxx.pem`**
  - `xxx.pem` ファイルのアクセス権を変更する。
- **`/inheritance:r`**
  - 親フォルダからのアクセス権の継承を無効にする。
  - これにより、セキュリティを強化し、特定のユーザーのみに権限を付与できるようにする。
- **`/grant:r "$($env:USERNAME):R"`**
  - 現在ログインしているユーザー（`$env:USERNAME`）に **読み取り（R）** 権限のみを付与する。
  - `:R` の部分は「読み取り専用」を示しており、書き込みや変更ができない設定となる。

## コマンドの目的
このコマンドの目的は、
1. `.pem` ファイルのアクセス権限を制限し、不要なユーザーがアクセスできないようにする。
2. `.pem` ファイルの権限をログインユーザーのみに制限し、他のユーザーやシステムプロセスがアクセスできないようにする。

## 実行方法
1. **管理者権限の PowerShell を開く**
   - `Win + X` → `Windows ターミナル (管理者)` または `PowerShell (管理者)` を選択
2. **コマンドを実行する**
   - `.pem` ファイルのあるディレクトリに移動し、コマンドを実行
   ```powershell
   icacls xxx.pem /inheritance:r /grant:r "$($env:USERNAME):R"
   ```

## 注意点
- `.pem` ファイルは秘密鍵などの機密情報を含む場合が多いため、不適切なアクセス権設定はセキュリティリスクにつながる。
- **管理者権限で実行しないと適用されない場合がある。**
- 他のユーザーがこの `.pem` ファイルを使用する必要がある場合は、適切な権限を追加で設定する必要がある。

## まとめ
`icacls` コマンドを使用することで、`.pem` ファイルのアクセス権を制限し、セキュリティを向上させることができます。

特に、SSH やクラウドの認証に使用する `.pem` ファイルは、適切なアクセス制御を行うことで、不正アクセスのリスクを最小限に抑えることができます。

***今回の備忘録のまとめが、どなたかの技術の支えになれば幸いです！***
【クラウド技術】Azureのリソース概要について

　AmazonのAWSのようなクラウドの学習が多かったのでMicroSoftのAzureについても、簡単に整理してみます。

## Azureアカウント
Azureでは、**Azureアカウント**と呼ばれるリソースを管理するユーザアカウントがある。
Azureアカウントには
　- マイクロソフトアカウント
　- 組織アカウント
の二つがある。


## Azureの管理レイヤー
　Azureは、下記のようにレイヤーの構造のように、論理的な階層構造になっている。
　- リソース
　- リソースグループ
　- サブスクリプション
　- 管理グループ

ここで、リソースとはAzureでのサービス(例えば、Azure FUnction、仮想マシン、Azure SQL Database)と1対1で紐づいている管理エンティティです。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381629/d3dd5e68-300f-4ddf-9561-f2a235378cf6.png)


## 代表的なストレージサービス
　AWSと同じようにAzureにもいくつかのインターネット経由で使用できるストレージサービスが存在する。ここではAWSのオブジェクトストレージである「S3」と類似のサービスである「**Azure Blob Storage**」について見ていきたい。
 ### Azure Blob Storage
 　Azure Blob Storageはクラウド用のオブジェうとストレージで、テキストファイルや、画像/動画のバイナリデータなどあらゆるファイルを保存するのに適している。
  保存されるデータは**ブロックBLOB**と呼び、入れ物を**コンテナ**と呼ぶ。特徴としては、
  - インターネット経由で世界中からアクセス可能
  - Azure Blob Storageの階層的構造
      - ホットアクセス層
      - クールアクセス層
      - アーカイブアクセス層

    で構成される。

## 最後に
　AWSにもオブジェクトストレージとして「**S3**」のようなサービスがありますが、AzureのBlobストレージもアクセス頻度に応じて複数のストレージ層が選択できたり、インターネット経由(HTTP、HTTPS)でAzure Blobのオブジェクトにアクセスできたりするなどサービスとして類似点が多いな(当たり前ですが・・)と思った次第です。もう少し踏み込んで実際のさーびすをみていければとおもいｍ
【試験対策】ランサムウェア攻撃とは？手口・被害・対策を徹底解説！

✅ はじめに

近年、ランサムウェア攻撃が急増し、企業や自治体が業務停止に追い込まれる 事例が多発しています。
応用情報技術者試験でも、「ランサムウェアの仕組みや対策」が問われることがあり、試験対策として重要なテーマです。

本記事では、
✅ ランサムウェアとは何か？
✅ どのように感染するのか？
✅ 被害の影響
✅ 具体的な対策方法
✅ 応用情報技術者試験での出題ポイント
を整理しました。

試験対策だけでなく、実務でも役立つ内容なので、ぜひ最後まで読んでください！

⸻

📌 ランサムウェアとは？
🔹 攻撃の概要
ランサムウェア（Ransomware） とは、感染したPCやサーバーのデータを暗号化し、復旧のために身代金（Ransom）を要求する マルウェアの一種です。
「身代金型ウイルス」とも呼ばれ、データを人質に取ることで金銭を要求する のが特徴です。

🔹 代表的なランサムウェアの種類
| 種類 | 特徴 |
|:-:|:-:|
| Crypto型  | ファイルを暗号化し、復号キーと引き換えに身代金を要求  |
| Locker型  |OSやシステム自体をロックし、使用できなくする   |
|Double Extortion型   | 暗号化＋データ窃取 を行い、身代金を払わない場合に情報を公開すると脅迫  |
| RaaS（Ransomware as a Service）  | ランサムウェアの攻撃手法を「サービス」として提供し、誰でも攻撃可能にする |

特にDouble Extortion型が増えており、「バックアップがあっても情報漏えいを防げない」という点が脅威です。


⸻
📌 ランサムウェアの感染経路
🔹 代表的な感染手口
|感染経路  | 詳細 |
|:-:|:-:|
| メール（フィッシング詐欺）  |不審な添付ファイルを開いたり、偽サイトに誘導されてマルウェアをダウンロード   |
| リモートデスクトップ（RDP）攻撃  |  脆弱なパスワード のRDP（リモートデスクトップ接続）を突破し、ランサムウェアを仕込む |
| ソフトウェアの脆弱性  |未修正の脆弱性 を悪用し、侵入してランサムウェアを展開   |
|USBメモリ・外部デバイス   |感染したUSBメモリ からマルウェアが拡散   |
| サプライチェーン攻撃  |取引先のシステムを経由して感染（2021年のKaseya攻撃が有名）|

最近は 「VPNやRDPの脆弱性を狙った侵入」 が増えており、強固なパスワードと多要素認証（MFA）の導入 が不可欠です。

⸻
📌 ランサムウェア攻撃の影響
ランサムウェア攻撃を受けると、企業の業務が停止し、深刻な被害 が発生します。
|被害内容  | 影響 |
|:-:|:-:|
| 業務停止・システムダウン  | 企業や自治体の業務がストップし、復旧に数週間かかるケースも |
|金銭的損害   |身代金（数百万〜数十億円）を要求される   |
| データ消失  | バックアップがなければデータが復旧できない  |
|情報漏えい（Double Extortion型）   | データが暗号化されるだけでなく、攻撃者に流出  |
|社会的信用の低下   | 顧客情報が流出し、企業の信頼が失墜  |

特に 「医療機関」や「インフラ関連企業」 では、業務停止が直接人命に関わるため、リスクが非常に大きいです。
⸻
📌 具体的な対策方法
🔹 1. バックアップの強化
✅ 定期的に重要データをバックアップする
	•	オフラインバックアップ（物理ディスク）を用意 し、攻撃者がアクセスできないようにする
	•	クラウドバックアップを活用し、多重バックアップ を実施

🔹 2. メール・フィッシング対策
✅ 不審なメールを開かせない仕組みを作る
	•	メールフィルタリングを強化 し、怪しい添付ファイルをブロック
	•	従業員向けセキュリティ教育を実施（怪しいメールを開かない習慣を徹底）

🔹 3. リモートアクセス（RDP/VPN）の強化
✅ RDPやVPNを安全に運用する
	•	強固なパスワードを設定し、MFA（多要素認証）を導入
	•	不要なRDPポートを閉じ、アクセス制限をかける

🔹 4. ソフトウェアの脆弱性対策
✅ OS・ソフトウェアを常に最新に保つ
	•	Windowsやアプリの更新を定期的に実施（特にVPNやRDP関連の脆弱性に注意）
	•	EDR（Endpoint Detection and Response）を導入し、異常な動きを検知

🔹 5. ランサムウェア対策ソフトの導入
✅ 次世代アンチウイルス（NGAV）を活用
	•	振る舞い検知機能 を持つNGAVを導入し、ランサムウェアの挙動を阻止

⸻

📌 試験での出題ポイント

✅ 記述問題の対策
午後試験では、「ランサムウェアの手口・影響・対策」を論理的に説明できるかが問われます。
以下のような問題が出る可能性が高い ため、事前に練習しておきましょう。

Q1. ランサムウェアの特徴と攻撃手法を説明せよ。
解答例:
ランサムウェアは、感染したPCのファイルを暗号化し、復号キーと引き換えに身代金を要求するマルウェアの一種である。
主な感染経路には、フィッシングメール、リモートデスクトップの脆弱性、ソフトウェアの脆弱性を悪用した攻撃 などがある。

Q2. ランサムウェアの被害を防ぐための具体的な対策を2つ挙げ、それぞれの理由を説明せよ。
解答例:
	1.	オフラインバックアップを実施する
	•	ランサムウェアはシステム全体を暗号化するため、攻撃後にデータを復旧する手段が必要となる。
	2.	RDPのアクセス制限を行う
	•	攻撃者は脆弱なRDPを悪用してランサムウェアを仕掛けるため、強固なパスワードと多要素認証を導入することでリスクを低減できる。

⸻

✅ まとめ
	•	ランサムウェアはデータを暗号化し、復旧のために身代金を要求するマルウェア
	•	感染経路は「メール」「RDP攻撃」「脆弱性攻撃」などが多い
	•	「バックアップ・RDP対策・フィッシング対策・脆弱性管理」が重要な防御策
	•	試験では「感染手口・影響・対策」をセットで理解し、記述問題に備える！
【Vue3】ライフサイクルについて

# そもそもライフサイクルとは
オブジェクトやコンポーネントの生まれてから消えるまでの流れ。考え方は他のフレームワークにも共通している。

Vueでは、コンポーネントが生まれてから消えるまでの流れの中で、好きなタイミングで処理を差し込める。

# Vue3のライフサイクルの流れ
コンポーネントは 「作られる」 → 「表示される」 → 「更新される」 → 「消える」 という流れを持っている。

1. 作られる（beforeCreate → created）
1. 表示される（beforeMount → mounted）
1. 更新される（beforeUpdate → updated）
1. 消える（beforeUnmount → unmounted）

| ライフサイクルフック | タイミング | 使い所 |
|:-:|:-:|:-:|
| beforeCreate | Vueインスタンスが作られる | ほぼ使わない |
| created | Vueのデータが準備される | 初期データの取得（API通信など） |
| beforeMount | DOMに表示される前 | ほぼ使わない|
| mounted | 実際に画面に表示された後 | DOM操作、API通信、タイマー設定など |
| beforeUpdate | データが変わったけど、画面が更新される前 | 更新前のデータをチェックしたい時 |
| updated | データが変わり、画面が更新された後 | 更新後のDOMをチェックしたい時 |
| beforeUnmount | コンポーネントが消える前 | タイマーやイベントリスナーの解除 |
| unmounted | コンポーネントが完全に削除された後 | クリーンアップ処理 |

# よく使うライフサイクル
## 1. `mounted`（画面に表示された後）
```vue 
<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  console.log('コンポーネントが表示された');
});
</script>

```

## 2. `onUnmounted`（コンポーネントが消えるとき）
```vue
<script setup>
import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  console.log('コンポーネントが表示された');
});

onUnmounted(() => {
  console.log('コンポーネントが削除された');
});
</script>

```

# ライフサイクルの使い道

ライフサイクルを使うと、Vueのコンポーネントが **「表示される前」「表示された後」「更新された時」「削除される前」** というタイミングで、特定の処理を実行できる。

## 例① `mounted` で 画面に表示された後にAPIからデータを取得する
```vue
<script setup>
import { ref, onMounted } from 'vue';

const message = ref('');

onMounted(() => {
  console.log('✅ コンポーネントが表示された！（mounted）');
  // コンポーネントが表示されたらAPIを叩く
  setTimeout(() => {
    message.value = 'データを取得しました！';
  }, 2000);
});
</script>

<template>
  <div>
    <h2>ライフサイクルテスト</h2>
    <p>{{ message || 'データ取得中...' }}</p>
  </div>
</template>
```

## 例② `onUnmounted` でコンポーネントが削除された後にタイマーを止める
``` vue
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const count = ref(0);
let timer;

onMounted(() => {
  console.log('⏳ カウント開始！（mounted）');
  timer = setInterval(() => {
    count.value++;
  }, 1000);
});

onUnmounted(() => {
  console.log('⏹️ タイマー停止！（unmounted）');
  clearInterval(timer);
});
</script>

<template>
  <div>
    <h2>カウント: {{ count }}</h2>
  </div>
</template>
```

:::note info
- `onMounted` で カウントを1秒ごとに増やすタイマーをセット
- `onUnmounted` で コンポーネントが消える時にタイマーを止める
:::

**こうすることで、無駄な処理が残らずメモリリークを防げる**
JacksonでJSONのキー名をキー名の変換マップで変換

Java 17

HashMap<String, String> を作成し、キー名の変換ルールを定義。
ObjectMapper を使い JSON を JsonNode に変換。
fields() で JSON のキーと値を取得し、HashMap で対応するキー名に変換。
変換後のデータを ObjectNode に追加し、JSON 文字列に変換。

```java
String jsonStr = "{\"user.name\": \"Alice\", \"user.age\": 25, \"address.city\": \"Tokyo\"}";

// キー名の変換マップ
Map<String, String> keyMap = new HashMap<>();
keyMap.put("user.name", "username");
keyMap.put("user.age", "userAge");
keyMap.put("address.city", "city");

ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = null;
try {
	rootNode = mapper.readTree(jsonStr);
} catch (JsonProcessingException e) {
    // 実際のコードでは、例外スローして上位のクラスでキャッチしてログ出力などをすること
	// TODO Auto-generated catch block
	e.printStackTrace();
}

// 新しいオブジェクトに変換後のキーを格納
ObjectNode newRoot = mapper.createObjectNode();

Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
while (fields.hasNext()) {
    Map.Entry<String, JsonNode> entry = fields.next();
    String newKey = keyMap.getOrDefault(entry.getKey(), entry.getKey()); // マップにある場合は変換
    newRoot.set(newKey, entry.getValue());
}

// 新しいJSON文字列に変換
String newJsonStr = null;
try {
	newJsonStr = mapper.writeValueAsString(newRoot);
} catch (JsonProcessingException e) {
    // 実際のコードでは、例外スローして上位のクラスでキャッチしてログ出力などをすること
    // TODO Auto-generated catch block
	e.printStackTrace();
}
System.out.println("newJsonStr:" + newJsonStr);
```

```sh
newJsonStr:{"username":"Alice","userAge":25,"city":"Tokyo"}
```


複雑なJSONに対応する場合は以下のページ方法で実装すること
[JavaのJacksonライブラリを使い、再帰的にJSONのキーを変換](https://qiita.com/rururu_kenken/items/99ef363a31315e14ecc7)
JacksonでJSONキーの「.」だけ削除

Java 17

## 解説
ObjectMapper を使って JSON 文字列を JsonNode に変換。
fields() メソッドでキーと値のペアを取得。
replaceAll("\\.", "") を使ってキーの「.」を削除。
新しい ObjectNode に変更後のキーと値をセット。
writeValueAsString で JSON 文字列に変換。

## ポイント

replaceAll("\\.", "") で正規表現を使い、全ての「.」を削除。
ObjectNode を使い、新しい JSON を構築。


```java
String jsonStr = "{\"user.name\": \"Alice\", \"user.age\": 25, \"address.city\": \"Tokyo\"}";

ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = null;
try {
	rootNode = mapper.readTree(jsonStr);
} catch (JsonProcessingException e) {
    // 実際のコードでは、例外スローして上位のクラスでキャッチしてログ出力などをすること
	// TODO Auto-generated catch block
	e.printStackTrace();
}

// 新しいオブジェクトに変更後のキーを格納
ObjectNode newRoot = mapper.createObjectNode();

Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
while (fields.hasNext()) {
    Map.Entry<String, JsonNode> entry = fields.next();
    String newKey = entry.getKey().replaceAll("\\.", ""); // ドットを削除
    newRoot.set(newKey, entry.getValue());
}

// 新しいJSON文字列に変換
String newJsonStr = null;
try {
	newJsonStr = mapper.writeValueAsString(newRoot);
} catch (JsonProcessingException e) {
    // 実際のコードでは、例外スローして上位のクラスでキャッチしてログ出力などをすること
	// TODO Auto-generated catch block
	e.printStackTrace();
}
System.out.println("newJsonStr : " + newJsonStr);
```

実行例
```sh
newJsonStr : {"username":"Alice","userage":25,"addresscity":"Tokyo"}
```
ネスペ勉強メモ：IGMPスヌーピングとフラッディング

## IGMPとは
+ （Internet Group Management Protocol）の略で、マルチキャストを行うためのプロトコル
+ 受信側の複数端末をまとめてグループアドレスを設定し、端末ごとに個別IPアドレスを設定
+ 受信側(レシーバ)がデータ取得する場合は、取得したい送信側のIPやMACを含めて参加表明(Join)を行うことでデータが取得できる

## IGMPスヌーピングとは
+ IGMP Joinメッセージを盗み見て、どのレシーバーがマルチキャストパケットを要求しているか確認し適切に転送できる機能
+ Macアドレステーブルに受信側のポートと宛先MACアドレスを登録する
## フラッディングとは
+ L2スイッチがマルチキャストパケットを受信した際、同一セグメントのすべてのポートに対して転送を行うこと。
+ トラフィック量が増えてしまい通信処理等に影響が出てしまう
+ スヌーピングを行うことにより防ぐ

### 参考サイト
https://www.infraexpert.com/study/multicastz12.html

https://panasonic.co.jp/ew/pewnw/product/column/008.html
Rancher Desktop経由でインストールしたkubectlやdockerのPathがzshで通っていない時は

Macでコンテナ環境構築するためにRancher Desktopを採用した。
Rancher DesktopはMacの場合、Homebrewからインストールが可能。
```
brew install --cask rancher
```

# 問題
kubectl, dockerコマンドが使用できることを確認するためバージョン表示を試みたが失敗。
(シェルにはzshを使用。)
```
 % kubectl verion
zsh: command not found: kubectl
% docker --version
zsh: command not found: docker
```

# 解決策
[公式ドキュメント](https://docs.rancherdesktop.io/troubleshooting-tips/#q-how-do-i-fix-kubectl-command-not-found-issue-on-linux)には、以下を実行するように回答があった。
```
echo "export PATH=\$PATH:/home/$(whoami)/.local/bin" >> ~/.bashrc
```
このコマンドでは`.bashrc`にパスを通している。Rancher Desktopのインストール時も使用しているシェルがbashの想定で行われており、zsh向けの設定がされていないのではないかと推測。
推測通り、`~/.bashrc`に下記のような内容が記載されていた。
```
### MANAGED BY RANCHER DESKTOP START (DO NOT EDIT)
export PATH="/Users/username/.rd/bin:$PATH"
### MANAGED BY RANCHER DESKTOP END (DO NOT EDIT)
```

`.zshrc`に上記内容を転記して、`source ~/.zshrc`を実行。
コマンドが実行できるようになっていることを確認。

```
% kubectl version  
Client Version: v1.32.3
Kustomize Version: v5.5.0
Server Version: v1.31.6+k3s1

% docker --version 
Docker version 27.5.1-rd, build 0c97515
```
airmon-ngでモニターモードに変更する

今回の記事はこの記事でセットアップとWi-Fiクライアントモードになっているところから始めます。

セットアップ方法とクライアントモード設定方法を知りたい方は[こちら](https://qiita.com/shunagas42/items/9f12b9a9cf5dd3cc9382)から

:::note  alert
この記事で記載する内容は全て学習のために自分自身のネットワークを使うことを徹底してください。
他人のネットワークに対して無断で行うことは法的に禁止されています。
:::
モニターモードへの変更方法を２つ示します。
結論から言うと、２つ目の方法を推奨します。

## モニターモードに変更 ツールなし
現状を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/02b7f7b9-a842-44c5-b3af-c6bbff00c8f0.png)
`Mode:Managed`と管理モードになっていることを確認します。

一度インターフェースを落とします。
```
sudo ip link set wlan0 down
```
`iwconfig`コマンドで状況を確認すると、`ESSID:off/any`となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/ce140218-1216-4fa1-b36a-dcbff954c4ff.png)

しばらく経つと自動的に再接続されることがありますので、もう一度インターフェースを落とします。

OFFになっていることを確認できたら、モニターモードに変更します。

```
sudo iwconfig wlan0 mode monitor
```

変更されているか確認します。もう一度起動してから確認します。
```
sudo ip link set wlan0 up
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/b6489632-f4c5-4325-875e-3a89c438ad25.png)

`Mode:Monitor`になっていればモニターモードに変更完了です。

## モニターモードに変更 airmon-ng
現在モニターモードになっている場合は、管理モードに戻してください。
モニターモードにした逆をやればOKです。

二つ目の方法はaircrack-ngスイートのairmon-ngを使います。

aircrack-ngスイートとはKali Linuxにはデフォルトで入っているWi-Fiパケットキャプチャ、解析をするハッキングツールです。

その中で、airmon-ngはモニターモードに変更するツールです。

以下コマンドを実行します。
```
sudo airmon-ng check kill
```
このコマンドはネットワークマネジャー、DHCPクライアントやWPA_Supplicantを停止し、干渉を防ぐものです。

先ほど、インターフェースをオフにした後、自動的に繋がることがあると話しましたが、それはバックヤードで作動しており、WPA_SupplicantやDHCPクライアントが自動的に再接続をしたことが考えられます。

また、一つ目の方法だと、モニターモードに変更後、干渉によって管理モードへ自動的に戻ることもあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/c86c3e3d-d326-4cbb-8e41-aa1ec368893d.png)

それでは、airmon-ngを起動します。
```
sudo airmon-ng start wlan0
```
使用しているWi-Fiアダプタやカーネルドライバに応じた適切な設定を自動で行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/ad9216d3-2bd5-4f28-9024-b3742930f76e.png)

それでは、モニターモードになっているか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/203a6293-19bd-4b5b-b429-52d7526c348b.png)
`Mode:Monitor`になっているのでOKです。

しかし、一つ目の方法と少し違います。
`wlan0`が`wlan0mon`に変わっています。

これは仮想インターフェースであり、`wlan0mon`が新たに作られています。
そのため、`wlan0`に直接変更は加えられません。

一つ目の方法は`wlan0`に直接変更をしてました。

これでモニターモード変更は完了です。

最後に戻す方法をお伝えします。
```
sudo airmon-ng stop wlan0mon
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/771053da-f618-4d54-8544-d81f160c6c8a.png)
管理モードに戻り、`wlan0`に戻っていることが確認できました。

先ほど、ネットワークマネジャーを切断したので、再起動しておきます。
```
sudo systemctl restart NetworkManager
```
```
systemctl status NetworkManager
```
これでアクティブになっていることが確認できればOKです。

今日のところは以上です。
バーコードにはJANとPLUがあるらしい👀

## はじめに

商品には必ず付いている(であろう)バーコード。

実はこのバーコード、色々とあるみたいなんです。

今回はこのバーコードについてお話し出来たらと思います。

## JANって？

バーコードと聞くと**JAN**という単語を思い浮かべる方もいらっしゃると思います。

JANとは、『Japanese Article Number』の略語からなり、

このバーコードの中に商品情報が内含されています。

このJANもバーコードの一つではあるのですが、

バーコードにはどうやらJAN以外の呼び名もあるみたいです👀

## PLUって？

では、それ以外の呼び名には何があるかと言いますと、

その一つが**PLU**になります。

PLUとは『Price Look Up』の略語なのですが、

このPLUは上述のJANと何が違うのかと言いますと、

PLUには『バーコードに商品価格が入っていることを明示する』ために使われています。

正確にはDB上に商品価格データがあり、

バーコードを介してそれを取得出来るようになっています。

* 単に『これはバーコードだ』ということだけを示したいのであれば**JAN**

* それに**価格情報**が入っていることまでを明示したいのであれば**PLU**

このような使用シーンに応じた違いがあるみたいです。

### PLUにも違いがある

そんなPLUなのですが、このPLUにも違いがあるみたいです。

それが**Non PLU**です。

PLUとNon PLUの違いは、

PLUはDB上にある商品の価格を参照するタイプのバーコードであるのに対し、

Non PLUはバーコード自体に商品価格が印字されており、DBを参照せずとも価格情報を取得出来るようになっています。

お肉などの量り売りで売られている商品に付与されることが多いみたいです。



## 参照
[一般財団法人流通システム開発センター 公式](https://www.gs1jp.org/code/jan/about_jan.html)
[JANコードとPLUコードの違いとは？：実は”レベル感”が違う言葉です](https://www.gixo.jp/blog/548/)
[CASIO公式](https://support.casio.jp/answer.php?cid=006010003001&qid=122600&num=3)
[スマレジ公式チャンネル](https://www.youtube.com/watch?v=Zi_o9E7A5mQ)
gpedit.msc で「リソースが見つからない」エラー発生！Windows Server 2022 での解決策


Azure で Windows Server 2022 を構築し、`gpedit.msc`（ローカルグループポリシーエディタ）を開いた際、以下のようなエラーが表示された。  


![スクリーンショット 2025-03-18 22.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/5476d0b0-2a13-475c-97ba-50896d8899e6.png)

---

## **🛠 エラーの原因**
このエラーは、**Windows のポリシーファイル（ADMX）と対応する言語ファイル（ADML）の不整合** によって発生する。  

### **🔍 ADMX ファイルとは？**
✅ ADMX（Administrative Template XML）は、Windows のポリシー設定を定義するファイル。  
✅ `C:\Windows\PolicyDefinitions\` に格納される。  
✅ これがないと、グループポリシーエディタで適切に設定を適用できない。  

### **🔍 ADML ファイルとは？**
✅ ADML（Administrative Template Language）は、ADMX の言語翻訳ファイル。  
✅ `C:\Windows\PolicyDefinitions\ja-JP\` に格納される。  
✅ **ADMX のポリシー情報を日本語化するためのファイル。**  

ADMX の新しい定義に対して、ADML の翻訳が追いついていない場合、**「リソースが見つからない」** というエラーが発生する。  
特に **Windows の言語パックを後からインストールした場合** に起こりやすい。  

---

## **✅ 解決策**
### **1️⃣ Windows Update を実行**
1. **[Win + I]** を押して **「設定」** を開く  
2. **「更新とセキュリティ」** → **「Windows Update」** を開く  
3. **「更新プログラムのチェック」** をクリック  
4. **最新のアップデートを適用し、再起動する**  

![スクリーンショット 2025-03-18 22.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/54504a2b-a674-4168-ae5e-d1e794b30099.png)


---

## **💡 エラー解消後**
Windows Update を適用後、もう一度 `gpedit.msc` を開いたところ、エラーは解消された。  

![スクリーンショット 2025-03-18 22.03.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/4cc79503-c55f-4b13-9d4d-8367a1ec9dc7.png)
1%のユーザーのために長時間化していたSQLの改善方法


SQLを作る際に、要件や用途が同じでも、SQLを分けた方が良いケースがあることを学んだので備忘録として書いておきます。(仕事で書くドキュメントっぽくなってしまいました)

### 発端

ある SELECT 文のパフォーマンスが悪く、他のSQLと比べて実行時間が非常に長いという問題が発生しました。調査したところ、SQL内で大量のレコードを JOIN していることが原因でした。

### 問題の背景

このSQLは、ユーザーのサービスの契約状態を見て、それに適合したレコードを表示するという要件を満たすためのものでした。

しかし、対象となるサービスの中には、大量のレコードを見なければならないものが含まれていました。

### 改善案

問題のサービスは、ごく一部のユーザー（全体の約1%）しか契約しないものだったため、以下のような対応を行うことにしました
•	SQLを発行する前に、サービスの契約状態を条件分岐で判定する。
•	条件分岐の結果に応じて、異なるSQLを発行するように変更する。

### なぜこの対応が有効か？
•	大多数のユーザー（約99%）に対して無駄な JOIN を行わなくて済む。
•	大多数のユーザーにとっての処理が効率化されることで、全体的なパフォーマンスが向上。

### 実施結果

問題となっていた JOIN や WHERE 句を減らしたSQLを別に作成したところ、
パフォーマンスが大幅に改善されました。めでたしめでたし。

### まとめ

サービスの契約状況が特定のユーザーに偏っている場合、
SQLを一つにまとめるのではなく、状況に応じてSQLを分けるアプローチが有効であると学びました。
3/15 tecHub（IT交流会）を秋葉原で開催しました！

![img_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670233/6473291f-6d75-4282-88a3-dd8314adddf2.png)


まだ少しだけ寒さが残る3月。
久しぶりに秋葉原でIT交流会を開催しました！

**目次▼**
<INS>[2025年3月のtecHubを開催しました！](#2025年3月のtechubを開催しました)</INS>
<INS>[tecHubは毎月イベント開催しています！](#techubは毎月イベント開催しています)</INS>
<INS>[参加者の声](#参加者の声)</INS>
<INS>[Discord（tecHubコミュニティ）を運営しています](#discordtechubコミュニティを運営しています)</INS>
<INS>[次回の開催](#次回の開催)</INS>

<h3>2025年3月のtecHubを開催しました！</h3>

![img_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670233/f63e60c3-334d-4742-8d68-0162e56d0c11.png)


3/15にtecHubを秋葉原で開催しました。
参加者は71名となり、大盛況でした。

日付：3/15(土)　14:00～16:30
場所：LIFORK 秋葉原
参加者：71名
内容：IT交流会


<h3>tecHubは毎月イベント開催しています！</h3>

毎月60〜80名ほどの方が参加している人気のイベントです。

・3ヶ月に1度：LT（ライトニングトーク）と懇親会の2部構成イベント

・その他：リアルでIT交流会イベント

LT＋懇親会では、前半は「働き方」をテーマにLT・プレゼンテーションを、後半は懇親会で自由に交流の時間を設けています。
LTでは、外部スピーカーをゲストに招くこともあります。

懇親会にはスピーカーも参加し、発表内容をさらに掘り下げてディスカッションすることも可能です！
色々な方が自由に意見・情報交換をできる場となっています。

<h3>参加者の声</h3>

![img_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670233/61913fbe-1d18-4685-8e8e-8db781d5c0ed.png)

今回も会社員やフリーランス、法人化と様々な働き方をしているITエンジニアが参加しました。
また、エンジニアへの転職を検討している人、Webデザインやシステム開発などの副業に興味を持つ人も参加していました。

「今後のキャリアアップをどうするか？」
「フリーランスの働き方は、実際どんな感じなのか？」
など、幅広い分野と色々なキャリアのトークは、異なる視点や考え方を知る機会になっていました。

参加者からは、
**「業務経験豊富なエンジニアから話を聞けてよかった」
「フリーランスのWebデザイナーの話が参考になった」
「フロントエンドだけでなく、バックエンドにも興味が湧いた」**
などの声をいただいています。

tecHubは、ITエンジニアがより活躍し、理想のキャリアを切り拓けるようにコミュニティを運営します。
また、今後もイベントを毎月開催していきます。

<h3>Discord（tecHubコミュニティ）を運営しています</h3>

■キャリアアップ
・キャリア相談／キャリアプランサポート
・スキルシート査定／レビュー
・転職・フリーランス転向サポート

■システム開発
・開発案件への参画
・スペシャリストに技術相談
・もくもく会などサブイベントへの参加

Discordの参加はこちらから。

https://discord.com/invite/9eFWdAzuf5

<h3>次回の開催</h3>

次回の開催は、以下の日程を予定しております。
日時：4/19(土)　14:00～16:30
場所：LIFORK 秋葉原
内容：IT交流会
Dockerコンテナ内でX11 GUIアプリを起動するときDISPLAY=:0でいいとは限らない

# 結論
devcontainerを使うのが一番楽．それ以外であれば，GUIアプリ起動時のエラー`Error: Can't open display: :0`を回避するために`DISPLAY=<ホストのDISPLAY>`として合わせるのがいい．ただしホストがWindowsだと`DISPLAY=host.docker.internal:<ホストのDISPLAY変数>`とする必要がある．

:::note
devcontainerの場合はDISPLAY環境変数や/tmp/.X11-unixのマウントなどはすべてdevcontainerがやってくれるので本記事の手順は不要です．ソースなどは[こちら](https://qiita.com/sin471/items/f4d470372c7070c288ab)に書いたので飛んで参照してください．
:::

# 環境
1. Ubuntu  20.04.6 LTS, Docker 28.0.1
2. Windows 11 Pro(24H2), Docker Desktop 4.36.0 

# DISPLAY=:0とすると起こること
たとえばGUIアプリケーションのxeyesを起動しようとすると，
```
$ xeyes
Error: Can't open display: :0
```
とエラーになる．

## 対処法(Windowsホスト)
前提として，以下のサイトのようにVcXsrvの設定と起動までを済ませておきます．

https://itsec-arekore.blogspot.com/2021/05/windowsdockergui-vcxsrv-windows-x-server.html

自分の環境では，この状態でコンテナ内の`DISPLAY=:0`だと上述のエラーを吐きました．

理由は，Windowsホストの場合は，DISPLAY変数に`:0`だけでなくホストのIPも指定してやる必要があるからです．なので，コンテナ内の`DISPLAY`環境変数を`:0`ではなく`host.docker.internal:0`と設定します[^1]．

なお，VcXsrvで設定したディスプレイ番号と`DISPLAY`変数に設定したディスプレイ番号が異なる場合もエラーになります．VcXsrvの設定のdisplay numberを-1にするとVcXsrvが自動でディスプレイ番号を決定しますが，今回の場合はDISPLAY環境変数と一致しないと困るのでVcXsrvの設定で0に固定しておくとよいです．

## 対処法(Ubuntuホスト)
Ubuntuホストでコンテナ内の`DISPLAY`環境変数を`:0`にした場合も上述のエラーが出ました．これは，自分の環境ではホストのディスプレイ番号とコンテナ内の`DISPLAY`環境変数の不一致が原因でした．

実際，ホスト上で`who`コマンドを打ってディスプレイ番号を確認すると，
```
$ who
hoge :1  2025-03-18 09:16 (:1) 
```
のようになったため，ディスプレイ番号は`:1`とわかります．

したがってこの場合は，コンテナ内で`DISPLAY=:1`と設定すると正常に動作します．

# その他参考サイト

https://zenn.dev/collabostyle/articles/1152b59484107b

https://askubuntu.com/questions/1108934/xhost-unable-to-open-display-0

[^1]: `host.docker.internal`はホストのIPアドレスを指す特別な名前です．ただし，Desktop版のDockerでしか動作しないので注意が必要です．https://docs.docker.jp/desktop/networking.html#desktop-networking-i-want-to-connect-from-a-container-to-a-service-on-the-host
How I Set Up Docker for My Project

🛠 Introduction
In this post, I will show you how to quickly and easily set up Docker for your project to make development and deployment easier.

🎯 Why use Docker?
Environment isolation: code runs the same on any machine.
Ease of deployment: launch a project with a single command.
Time saving: no need to manually install dependencies.

🔧 Installing Docker
Download and install Docker from the <a href="https://allessay.org/">official website>

Let's check that everything is installed:
docker --version

🏗 Creating a Dockerfile

Let's create a Dockerfile in the root of the project:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]

What's going on here?
FROM — take the Node.js image.
WORKDIR — set the working directory.
COPY — copy files.
RUN — install dependencies.
CMD — run the project.

🔥 Building and running the container
Now let's build the image and run the container:
docker build -t my-app .
docker run -p 3000:3000 my-app

🎉 Summary
Now your project is running in a Docker container! 🚀
@GeneratedValueを使用するエンティティで主キー(idなど)を持つコンストラクタを作るとエラー

エンティティクラスでidなどの主キーに@GeneratedValueを使用する場合、JPAがIDの自動生成を管理するためデフォルトコンストラクタを必要としてエラーが発生する場合がある。

エンティティクラスで@GeneratedValueを使用する場合、以下のように対応する必要がある。

<h3>1. 全フィールドのコンストラクタを作らない</h3>
修正前


```
@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String author;
    
    public Book(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }
}
```


修正後


 ```
 @Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String author;

    // デフォルトコンストラクタ（JPA 用）
    protected Book() {}

    // ID を含まないコンストラクタ
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }
}
 ```

 <h3>2. Lombok を使う場合</h3>
Lombok の @AllArgsConstructor を使うと ID を含むコンストラクタが生成されてしまうので、代わりに @NoArgsConstructor と @RequiredArgsConstructor を組み合わせます


```
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Setter
@NoArgsConstructor // デフォルトコンストラクタ
@RequiredArgsConstructor // 必須フィールドのみを持つコンストラクタ
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NonNull
    private String title;

    @NonNull
    private String author;
}
```
Powershell_CSV操作のtips

### 背景
会社でのディレクトリ管理に困ってた時のTips
いろんなお客さんとのやり取りを、
* みんなで1つのディレクトリ配下に格納しよう！
* 命名規則もこうしてね！

みたいなお作法があった。これが不便。


例:
0001_A12345_<和名>
0002_B32899_<和名>
0003_Q77791_<和名>
※これが200個以上ある...

<ナンバー>_<顧客コード>_<顧客コードに対する和名>みたいな感じ。
これだと、目的の顧客コードがどの辺にあるのかスクロールして探していくのが、毎回億劫で...

要するに、
**「顧客コードが先行して分かっているが、フォルダのナンバーは分からん」**
なシチュエーションで困ってた。

:::note info
なお現状、この顧客コードとナンバーの対応表が存在するのだが、それをわざわざ開いて検索して～の流れも手間なので、何か楽ちんなやり方無いかな～のTips
:::
### DNSチックにコマンドぽちーでレコード出せないかな？
という事で考えてみた。
顧客コードをPowershellに入力したら、ナンバー返してくれる結果を目指す！
といっても、会社PCにリゾルバをインストールして...てやるとセキュリティの管理も大変なので、標準機能だけで代替できる事考えてみた

### 結果
できました。全レコードのリストと、個別のリストを出すパターンですね。


~~~
PS C:\Users\USER> $source | format-table

num  name   flag  text
---  ----   ----  ----
0001 A12345 TRUE  Last Update by Tanaka
0002 B32899 FALSE Deleted
0003 Q77791 TRUE  Don't Edit


PS C:\Users\USER> $source | Where-Object {$_.name -match "A12345"}

num  name   flag text
---  ----   ---- ----
0001 A12345 TRUE Last Update by Tanaka

PS C:\Users\USER>
~~~

じつは事前に以下で変数を宣言しておく必要があります。
~~~
PS C:\Users\USER> $path = "$env:USERPROFILE\Documents\list.csv"
PS C:\Users\USER> $source = Import-Csv $path -Encoding UTF8
~~~
:::note info
※今回のサンプルでは、documents配下にリストを配置しており、これを参照しております。リストのヘッダーとして後述の4要素を追加しております。
:::

### 今後の話
実は、以下もPowershellからぽちっとcsv操作できるが、一旦次回にまわす。
・レコードを新しく追加する。
・レコードを編集する。
(CSV開いて追記すればいいじゃん は、一旦なしで)

後は備忘録です。

~~~
$path = "$env:USERPROFILE\Documents\list.csv"
~~~
これ、ダブルクォーテーションでくくらないとエラーが出ます。
後に打つコマンドによっては問題なく動作しますが


ヘッダーについて
~~~
$source = Import-Csv $path -Encoding UTF8
$headers = @("num","name","flag","text")
$record = New-Object psobject | Select-Object $headers
$var = @()
~~~
レコードを追加するときに、こんな感じで入れてます。

`$source` でリストをインポートして、`$headers = @()`でヘッダーを追加し、`$record`にこの後値を登録していきます。
既存のファイルを操作するときは必要ないです。
また、`$record`の中身は`$var`に入れてから最終的にエクスポート。

~~~
PS C:\Users\USER> $record."num" = "0001"
PS C:\Users\USER> $record."name" = "A12345"
PS C:\Users\USER> $record."flag" = "TRUE"
PS C:\Users\USER> $record."text" = "Last Update by Tanaka"
PS C:\Users\USER> $record

num  name   flag text
---  ----   ---- ----
0001 A12345 TRUE Last Update by Tanaka
~~~
こんな感じで登録されます。

次に`$var`の使い道ですが、
~~~
PS C:\Users\USER> $var += $record
PS C:\Users\USER> $var

num  name   flag text
---  ----   ---- ----
0001 A12345 TRUE Last Update by Tanaka

PS C:\Users\USER> $record = New-Object psobject | Select-Object $headers
*ここからはまた$recordに次の値を入れていく*
~~~
こうすれば、`$record`にはまた次の値が上書きされますが、`$var`にデータは逃げているので問題ないです。

~~~
PS C:\Users\USER> $var

num  name   flag  text
---  ----   ----  ----
0001 A12345 TRUE  Last Update by Tanaka
0002 B32899 FALSE Deleted
0003 Q77791 TRUE  Don't Edit


PS C:\Users\USER> $var | export-csv -path $path -NoTypeInformation -Encoding UTF8 -append
~~~
最後に`$var`をもとのリストに追記すれば完了！

:::note warn
最後のオプション -append を付けないと、`$var`の値が上書きされ、いままでのデータが消えます。
:::

`-notypeinformation`ですが、これ無いと勝手にヘッダーが作成され、作ったヘッダーはレコードの1つのように扱われます。

最終的には.ps1のファイルにまとめたいですね。
サーバーのOSとは

## はじめに
　サーバーをはじめとして、一般的なパソコンにも必ず搭載されているものが**オペレーティングシステム**(**OS**)です。OSは、人が機器の管理・制御を行うためのインターフェースやハードウェア管理機能、機器上で動作するソフトウェア群が共通して利用する基本的な機能などを実装したソフトウェアです。
　一般的な家庭用パソコンでは主にWindowsやmacOS、スマートフォンではAndroidやiOSが利用されていますが、サーバーとして利用される機器では主に**Linux**や**Windows Server**が利用されます。

## Linux
　LinuxはWindowsやmacOSと違い、無料かつオープンソースなソフトウェアなので、誰でも自由に開発、配布を行えます。そのため、大元のLinuxカーネルと呼ばれるソフトウェアを基本とし、様々な企業や団体が独自に開発を加えたOSを**Linuxディストリビューション**として提供しています。
　次表は代表的なLinuxディストリビューションの一覧です。もしLinuxを利用してサーバー構築を行うのであれば、これらのディストリビューションから目的に合ったものを選択するところから構築が始まります。

### 代表的なLinuxディストリビューション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/64c2378a-f711-4565-ac7c-53d8e4fc220d.png)
上記の代表的なディストリビューションはAWSサービスのEC2でも利用可能なOSとして提供されており、自由に選択を行うことが可能です。

## Windows Server
　Windows Serverは、Windowsを提供しているマイクロソフトからリリースされているサーバー用OSです。Linuxとは違い、利用にはOS自体のライセンスやCAL(Client Access License)と呼ばれるサーバー利用ライセンスの購入が必要となります。
　Windows Serverの大きな特徴のひとつに、GUI(Graphical User Interface)操作であり一般的に利用されているWindowsとUIや使い方が似ていることが挙げられます。基本的にCUI(Character User Interface)操作となるLinuxディストリビューションと比べて利用しやすいといえます。
　また、マイクロソフト製品であるため、その他のマイクロソフト製品との親和性の高さやAD(Active Directory)との連携、充実したサポートなど、様々なメリットがあります。

 ## OSごとの比較
　LinuxとWindows Serverの特徴について簡単にまとめると次表のようになります。どちらにも優れている点があるので、費用や利用したい機能を考慮して選択する必要があります。

### LinuxとWindows Serverの比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/ed0b5b5b-d073-4fc8-9cac-fcd643295a55.png)

## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・図解 Amazon Web Servicesの仕組みとサービスがたった1日でよくわかる 単行本（ソフトカバー） – 2022/2/2
NRIネットコム株式会社 (著), 上野 史瑛 (著), 小林 恭平 (著), 尾澤 公亮 (著), 高梨 友之 (著)
p.54-55