OmniAICreator/Qiita-1.07M huggingface dataset:
強化学習で上昇気流を捉える６

# 背景
[前回](https://qiita.com/goichiya/items/c2c303abec1cd703016d)からの続き。
作ったモデルを実際に試験するためのツールを作ってゆく

# 作りたいもの
- 飛行の状態を音声で知らせてくれる
- サーマルを捕まえ続けるように進行方向を教えてくれる

# ハードウェア
1. [ラズパイゼロ](https://amzn.to/3Owclsu)にいろいろ繋げてゆく（LinuxベースでPythonも使えて勝手がよさそう）
1. 温度、湿度、気圧を[BME280](https://amzn.to/3yjLlXQ)から取得
1. GPSはUSBで接続（[ublox7](https://amzn.to/39RTR6U)）
1. スピーカはBlueToothで接続　([MIFA A1スピーカ](https://amzn.to/3brVHfn))
1. ~~各種捜査のボタンと確認用のLEDを付加~~ pHAT追加で解決(20220814)
1. [UPS HAT](https://amzn.to/3SZAzyq) を追加してモバイルバッテリいらずに (20220814)
1. [BUTTON SHIM](https://www.switch-science.com/catalog/3669/)でボタンやLEDのはんだ付けいらず(20220814)

![20220624_回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/0f349873-8db2-d27b-c154-3a2d83bdc8a4.png)

**苦労した点**
- ラズパイゼロとスピーカの接続が安定しない（Bullseye上でのBluetooth接続の情報があまりない。VNCをしようしてGUIで設定することで比較的安定）
- ラズパイとパーツの接続が良く外れる（自分でデュポン接続端子をかしめて作るようにした）
- 裸だと持ち歩いてテストしにくい。（3Dプリンタで専用の箱を作った）

# 筐体
[tinkercad](https://www.tinkercad.com/)を使用して筐体を設計し、STL出力して3Dプリンターのアプリに食べさせる。  
気圧を測る場合、筐体を密閉するとよろしくないと聞いたので、必要な穴はあけたままにしておく。  
![CENTER_0002_BURST20220525092739992.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/f1653ac5-0075-88bb-df99-b00030c12744.jpeg)

おおむね良さそうなので、あれこれ積んでゆく
![DSC_0461.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/bf59397d-164b-24f6-db41-c2a620c18d0b.jpeg)
なんて醜い配線取り回しなんだろう、、、
しかしこれであまり気を遣わずにバッグの中に放り込めるようになった！

**苦労した点**
- PETGだと恐ろしく糸を引くのと小さい穴などがつぶれてしまった。（ABSでちょうどよかった）
- ラズパイの穴の位置を記載している資料にたどり着くのに苦労した（結局公式内を探すのが早かった）
- 打ち出してから「穴が小さい」「穴が足りない」などちょっとした調整を思いつく（経験値を上げてゆく所存）

# ソフトウェア  
## 前準備  
- 公式のツールを使って最新のBullsEyeをSDカードに書き込み
## 構成
```
home  
    ├start_voice.sh (起動時に実行するシェル。switch.pyが実行される)  
    ├Vario  
    │   └log  
    │   │   ├logger.log  
    │   │   └  
    │   ├bme280.py  
    │   ├nblox7.py  
    │   ├switch.py  
    │   ├data_log_out.py  
    │   ├event_check.py  
    │   ├voice_out.py  
    │   ├system_log_out.py  
    │   ├sys_mode.csv(実行時パラメタ)  
    │  
    └Music  
    │    └各種音源(voice_out.pyより呼び出される)  
    ├jtalk.sh(動的に音声合成する際に使用)  

```
**苦労した点**
- Bluetoot接続のスピーカに安定して音声出力するための情報が少なかった。古い情報と新しい情報が混在していてBullsEyeにあった設定が何かわからなかった。（VNCを使用してGUIで設定した）
- GPSとスピーカを同時に接続するのが厳しかった（ラズパイゼロに音声出力端子がなく、BluetootとGPSを[同時に使用することもうまくゆかず](https://mirahouse.jp/n10/blog/2019/07/)、GPSはUSB接続にすることで対応）
- 遅い（不要なプロセスを切るなどする。が、[HWのスペックが上がる](https://amzn.to/3OkuBFC)とよくなると信じている。品薄にしても高すぎる、、）
- 画面がないと設定や確認が不便な時がある（flaskを使用してウェブアプリを作った）
- 実際に外に持ってゆくとセンサやバッテリが外付けでぶら下がっている構成は取り扱いが面倒（下手なところに入れると動いたときに抜ける）(20220814)
- 動きがあるとはんだ付け部分の通電が不安定になる？はんだ付けの腕の問題かもしれないが、構成をコンパクトにするためにもpHAT追加で解決(20220814)
# テスト

データが取れるようになった！
外で使ってみよう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/0abcf022-1d2f-d8c9-68cf-b9343c3b852b.png)

# この後
- 外で使ってデータが取れるか？データの精度は？確認して調整
~~- いつの日か実際の距離感に合わせてみたい~~
- 強化学習モデルを搭載してテストする
- そしてさらにいつの日か携帯デバイスとして飛びながらベストな方向を教えてくれるようにしたい

# その他
朝霧に行ったら同じようなデバイスを自作している人がいた。  
きっとまだ他にも同志がいるに違いない
お金はかかるが全体構成をコンパクトにするためにpHATを使用するのは結局ペイすると気づいた。GPIOの競合は留意が必要なのでできるだけ購入前に[確認](https://pinout.xyz/)した(20220814)
SQLの基礎

実務でSQLをよく使用するので、
もう一度SQLの基礎を学習したのでまとめます。

・where句(なぜ？）
 = 等しい
 > より大きい
 >=　以上
 < より小さい
 <= 以下
 <> ! 等しくない
 in ()、 ()にある値がセット内に含まれているか？
 not in, ()にある値がセット内に含まれていないか？

 (例)select (抽出したいカラム) from　テーブル名 where (条件指定)

・group句　DBのカラムの同じ数値の値を抽出する。

select (抽出したいカラム) from テーブル名 group by (抽出したいカラム);

・having句
group句の後の集約結果をさらに絞り込む。(group by句の後に記入)
絞り込み条件はwhere句で使用した
=　や　> を記述する。

select (抽出したいカラム) from テーブル名 group by (抽出したいカラム) having (抽出条件);

・order by句 列(カラム)の並び替え
 asc 　昇順(小さい順)
 desc　降順(大きい順)

select (抽出したいカラム) from テーブル名 order by (asc or desc);

・limit句　取得条件を制限できる。
select (テーブル名) users limit 10;
plunkerでjsencrypt

# 概要

plunkerで、jsencryptやってみた。
rsaの暗号化、復号してみた。

# サンプルコード

```
document.querySelector("#encrypt").addEventListener("click", function() {
  const encrypt = new JSEncrypt();
  encrypt.setPublicKey(document.querySelector("#pubkey").value);
  const result = encrypt.encrypt(document.querySelector("#input").value);
  document.querySelector("#encrypted").value = result;
});

document.querySelector("#decrypt").addEventListener("click", function() {
  const decrypt = new JSEncrypt();
  decrypt.setPrivateKey(document.querySelector("#privkey").value);
  const text = decrypt.decrypt(document.querySelector("#encrypted").value);
  document.querySelector("#decrypted").value = text;
});
```

# 成果物

https://embed.plnkr.co/plunk/IsJfeC0HH5ybD4YP

以上。
C# 拡張メソッド(メソッドチェーン)


```C#
/// <summary>
/// 文字列を数字に変換する
/// 文字列に数字以外が入っていたら null を返す
/// </summary>
/// <param name="message">数字の文字列</param>
/// <returns>文字列が数字であればその値を int で返す そうでなければ null を返す</returns>
public static int? ToInt(this string message)
{
    return int.TryParse(message, out var result) ? result : null;
}
//------別のScript
void Start(){
    string message = "123456";
    var num1 = message.ToInt();
    Debug.Log(num1);//123456
    message = "1234a";
    var num2 = message.ToInt();
    Debug.Log(num2);//null
}
```

```
public static int? ToInt(this string message)
```
引数で`this`をつけることで拡張メソッドとして扱うことができる

```C#
/// <summary>
/// int型の数値にint型の引数を掛けた値をセットする
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void Mul(this ref int x,int y)
{
    x = x * y;
}
//------別のScript
void Start(){
    int i = 2;
    i.Mul(4);
    Debug.Log(i);//8
}
```

```
public static void Mul(this ref int x,int y)
```
引数を2つ以上つけることもできる

[拡張メソッド](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/extension-methods)
【UiPath】データテーブルの操作（5）並べ替え

# はじめに

この投稿は、RPAツール「UiPath」での 実装例 について記事です。
以前にも同様の記事を書いていましたが、内容が古かったので新しく記事にしました。

「UiPath Friends もくもく会 2022年06月開催 2022-06-25（土）9:00 - 12:00」で書きました。

https://uipath-friends.doorkeeper.jp/events/138022

# データテーブルの操作 シリーズ
DataTable の操作方法について記載した記事が、他にもあります。参考まで。

https://qiita.com/miya_gis/items/6c0dd40378db702bd4b2

https://qiita.com/miya_gis/items/edc3557f3dc7cf6b3cfd

https://qiita.com/miya_gis/items/171b3d12775c95f722c4

https://qiita.com/miya_gis/items/cde6c1eb3c33378d9718

https://qiita.com/miya_gis/items/966113ce9732cb112c49

https://qiita.com/miya_gis/items/f45b67fbc2575f0d6d77

https://qiita.com/miya_gis/items/67eac96071aa7d7d24dd

# データテーブルの行を並び替えたい

データテーブルの行を「特定の列」で並び替える方法は以下の「４つ」あります。

```
1. 標準アクティビティの「データテーブルを並び替え」で実施
2. DataTableの「Select」メソッドの第２引数で で並び替え
3. Dataview で並び替え
4. LINQ で並び替え
```

# 1. 標準アクティビティの「データテーブルを並び替え」で実施

UiPath標準で、並び替え用のアクティビティ「データテーブルを並び替え」が提供されています。

「並び替えに指定する列」と「順序（Ascending（昇順）、Descending（降順））」を指定できます。

このアクティビティでは **「並び替えに指定できる列は１つのみ」** です。（2022年06月現在）

例えば、DataTableの「A」列で「降順」並び替えたい場合は、以下のように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/f2ca0c28-597d-1eab-7ab4-8ac0e8b6f12e.png)

https://docs.uipath.com/activities/lang-ja/docs/sort-data-table


# 2. DataTableの「Select」メソッドの第２引数で で並び替え

DataTableには「Select」というメソッドが有り、第１引数で「絞り込み条件」、第２引数で「並び替え」を指定できます。`第１引数に何も指定しなければ、絞り込みはされない` ので、並び替えだけをすることも出来ます。

※ 標準アクティビティでは出来なかった「複数の列を指定して並び替え」も出来ます。

``` VB
'// ageが高い順に並び替え
dt_selected = dt.Select("","age desc").CopyToDataTable
'// teamごとに、ageが高い順に並び替え
dt_selected = dt.Select("","team, age desc").CopyToDataTable
```

https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datatable.select?view=net-6.0


# 3. DataView で並び替え

DataTable には「DataView」という「並べ替え、フィルター処理、検索、編集」ができる機能があり、これを利用してデータを並び替えることが出来ます。SQL の「order by」に近いイメージです。

※ 標準アクティビティでは出来なかった「複数の列を指定して並び替え」も出来ます。

https://docs.microsoft.com/ja-jp/dotnet/api/system.data.dataview

実装イメージはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/41ecc070-7911-cc72-87be-5421df9ca1f4.png)

System.Data.DataView 型の変数を用意して「New Dataview(元のデータテーブル変数)」でセットし「.Sort」で並び替えの指定（Order by指定）を書きます。


# 4. LINQ で並び替え

.NET にはLINQ（リンク）という「並び替え」や「連続処理」を行うための機能があり、UiPath でも使用できます。

実装イメージはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/3b2e5950-96f1-0e9e-8dea-20fcd7e6d4da.png)

「.OrderBy／OrderByDescending」で並び替え列の指定を指定し、複数の列で並び替えたい場合は、「.ThenBy／.ThenByDescending」で繋げていきます。

上記画像の例でいうと、以下のように記述しています。

``` VB
'// Team で昇順、Point で降順に並び替え
Dt_Before.AsEnumerable().OrderBy(Function(r) r("Team")).ThenByDescending(Function(r) r("Point")).CopyToDataTable()
```

# 終わりに

いかがでしたでしょうか。実装時に役立てば幸いです。
この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。
cscの作法 その212

# 概要
cscの作法、調べてみた。
BouncyCastle.Crypto.dll使ってみた。
練習問題やってみた。

# 練習問題
暗号を復号せよ。

# 方針
平文は、「hogehoge2」。
rsaで作る。
秘密鍵、公開鍵の両方で、やる。

# サンプルコード

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;

namespace ConsoleExample
{
	class Program {
		static void Main(string[] args) {
			var myenc = File.ReadAllText("myenc.txt");
			var encrypted = Convert.FromBase64String(myenc);
			var privateKeyPem = new StreamReader(@"myprivatekey.pem", Encoding.ASCII);
			var privateKeyReader = new PemReader(privateKeyPem);
			var keyPair = (AsymmetricCipherKeyPair) privateKeyReader.ReadObject();
			var rsa = new Pkcs1Encoding(new RsaEngine());
			rsa.Init(false, keyPair.Private);
			byte[] decrypted = rsa.ProcessBlock(encrypted, 0, encrypted.Length);
			Console.WriteLine("decrypted: " + Encoding.UTF8.GetString(decrypted));

			var myenc2 = File.ReadAllText("myenc2.txt");
			var encrypted2 = Convert.FromBase64String(myenc2);
			var publicKeyPem = new StreamReader(@"mypublickey.pem", Encoding.ASCII);
			var publicKeyReader = new PemReader(publicKeyPem);
			var publicKeyParam = (AsymmetricKeyParameter) publicKeyReader.ReadObject();
			var rsa2 = new Pkcs1Encoding(new RsaEngine());
			rsa2.Init(false, publicKeyParam);
			byte[] decrypted2 = rsa2.ProcessBlock(encrypted2, 0, encrypted.Length);
			Console.WriteLine("decrypted: " + Encoding.UTF8.GetString(decrypted2));

		}
	}
}

```

# 実行結果


```
>bc11
decrypted: hogehoge2
decrypted: hogehoge2

```

以上。
mintでインストール実行時に "/Users/ユーザー名/.mint/bin must be added to your $PATH if you wish..." と表示されるときの対処法

## はじめに
mintでKuriというツールをインストールした際に下記の警告が表示されました。

```
/Users/ユーザー名/.mint/bin must be added to your $PATH if you wish to run this package outside of mint
```

これはいわゆる**パスが通ってない**という状態です。

## 解消方法
まず、シェルが何なのかを確認します。
ターミナルで下記を実行してください。
```
echo $SHELL
```

## zshの場合
### 1. ルートディレクトリに移動
```
cd
```

### 2. .zshrcがあるか確認
```
ls -a
```

ある場合
```
open .zshrc
```

ない場合
```
touch .zshrc
open .zshrc
```

### 2. .bash_profileがあるか確認
```
ls -a
```

ある場合
```
open .bash_profile
```

ない場合
```
touch .bash_profile
open .bash_profile
```

### 3. .zshrcもしくは.bash_profileに追記
```
export PATH="$PATH:/Users/ユーザー名/.mint/bin"
```
保存してターミナルを再起動すればOKです。

**おわり**
Python Pandasのresample関数を使ったcsvデータの集計

***今回はPandasライブラリのresample関数を使って厚生労働省が提供している日次のPCR検査実施人数のオープンデータ(csvファイル)を月次集計してみます。***

:::note info 
**流れは、次の通りです。**
- **1. 厚生労働省からオープンデータPCR検査実施人数を取得**
- **2. 入手したデータファイルをUnixデータ形式に変換**
- **3. PythonでPandasのresample関数を使って月次集計。集計結果はcsv形式で出力する。**
- **4.実行する**
- **5.集計結果を確認する**
:::

では実際にやっていきます。

## 1. 厚生労働省からオープンデータPCR検査実施人数を取得
下記サイトからファイル名pcr_tested_daily.csvをダウンロードします。
https://www.mhlw.go.jp/content/pcr_tested_daily.csv

- pcr_tested_daily.csv
![スクリーンショット 2022-06-25 10.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2075298/a1cf7657-eb8b-3b6e-8669-f4ecc25eb7d9.png)

## 2. 入手したcsvファイルをUnixデータ形式に変換
```
$ unix2dos pcr_tested_daily.csv
```

## 3. PythonでPandasのresample関数を使って月次集計
下記用意したPythonコードです。

**■ファイル名: resample.py**
```Python:resample.py
import pandas as pd  # Pandasライブラリを読み込む

# ファイル名pcr_case_daily.csvをカンマ区切りで読み込む
df = pd.read_csv('./pcr_case_daily.csv',sep=',' ,index_col=0 ,parse_dates=True)

# resample関数で月次集計する。月初から月末までデータサンプリングして合計値を出す。
df_resample = df.resample('M').sum()  

# 結果をcsvファイル名output.csvに出力する
df_resample.to_csv('output.csv')
```


## 4. 実行する
```
python3 resample.py
```
実行後output.csvが出力された。
```
ls -lh output.csv
-rw-rw-r-- 1 ishimatsu ishimatsu 2.2K  6月 22 13:44 output.csv
```

## 5. 集計結果を確認
 結果ファイルを開き、月次集計されていることがわかりました。
 集計が月次になり、日付は毎月月末になります。
![スクリーンショット 2022-06-25 10.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2075298/7683e623-a412-d2ec-a815-fec549b63ffd.png)


以上になります。

Pandasのresample関数を使うことに容易に日次集計を月次集計できました。
resample関数は月次集計でなく多様な集計に対応しています。
下記参考にさせていただいたサイト(YutaKaのPython教室)には詳細な使用方法が書かれていますので、ご利用される場合にはぜひご参照ください。


##### ■ 参照させていただいたサイト
YutaKaのPython教室
https://www.yutaka-note.com/entry/pandas_resample
cscの作法 その211

# 概要
cscの作法、調べてみた。
BouncyCastle.Crypto.dll使ってみた。
練習問題やってみた。

# 練習問題
平文を暗号化せよ。

# 方針
平文は、「hogehoge2」。
rsaで作る。
秘密鍵、公開鍵の両方で、やる。


# サンプルコード

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;

namespace ConsoleExample
{
	class Program {
		static void Main(string[] args) {
			var originalText = "hogehoge2";
			var originalBytes = Encoding.UTF8.GetBytes(originalText);
			Console.WriteLine("original: " + Encoding.UTF8.GetString(originalBytes));

			var publicKeyPem = new StreamReader(@"mypublickey.pem", Encoding.ASCII);
			var publicKeyReader = new PemReader(publicKeyPem);
			var publicKeyParam = (AsymmetricKeyParameter) publicKeyReader.ReadObject();
			var rsa = new Pkcs1Encoding(new RsaEngine());
			rsa.Init(true, publicKeyParam);
			Console.WriteLine("ok");
			byte[] encrypted = rsa.ProcessBlock(originalBytes, 0, originalBytes.Length);
			Console.WriteLine("encrypted: " + Convert.ToBase64String(encrypted));
			File.WriteAllText("myenc.txt", Convert.ToBase64String(encrypted));

			var privateKeyPem = new StreamReader(@"myprivatekey.pem", Encoding.ASCII);
			var privateKeyReader = new PemReader(privateKeyPem);
			var keyPair = (AsymmetricCipherKeyPair) privateKeyReader.ReadObject();
			var rsa2 = new Pkcs1Encoding(new RsaEngine());
			rsa2.Init(true, keyPair.Private);
			Console.WriteLine("ok2");
			byte[] encrypted2 = rsa2.ProcessBlock(originalBytes, 0, originalBytes.Length);
			Console.WriteLine("encrypted: " + Convert.ToBase64String(encrypted2));
			File.WriteAllText("myenc2.txt", Convert.ToBase64String(encrypted2));

		}
	}
}


```

# 実行結果


```
>bc10
original: hogehoge2
ok
encrypted: L/okhFsA8Qku3tsYqiKWGqIHVx7TvVWOBDIXlBbZzRIVawk1zGEOHM/EmOh6Ymnrv9AxKdL/RmioCUTCer3QKLhF73jlW1ESUxOPLN8Bffnfm/IKfo/U9YWzHSV1aHevzdnWyPxJdXKasKqYRayFtHWANqFJEZqFwnN2mfl1Yg/VvrcmqNOszqVvNQC805Uwp5ENDnhCSD+2D5VgjPCh42x/IgQJrKAZMv31lRunuIeIEpUMMWcnWbUgRXX7rq368kup6RtQkcusFCwChzrlbgoSSJ57Pao+g/R5aCN8bFJvWZ00ddio0luR+bL6VR1QB8mFx4TRysgdGLtPWREf7A==
ok2
encrypted: lJ242QzTG4BAfR0vmpjYiQ5VtZxfBa0hPg0IGIr4CohTKo5TrAMYLhcorxMh4kSxEQHsMl1kFQX/uUZGeMONvnKkudrNYWS1CltgGSUscGdcRcgpz8ggmYElA5ZV08xj+a8KYRXMZHDVtg0tQ2EnGEGOuuNRW5UJP/lmi3cDWAwqu7TCAiGQ8rqcW0tRwOHJ+9Dx5jSZ44CuvBFqNK9pYRdEvU0OX7r9rj9xUSf/99CUCRUGYmpiJRJQPVPpdMdCmAOi2Zu2joMdm+KqtGAr+7mWTOgXWJeqcAmHGL1peBu3Nm3NYKN3lft5SwiG+rHcD9oqm9bJX4guTQFGHULoDA==

```

以上。
[Haskell+Windows] 起動しないHLSと戦った記録

[前回の記事](https://qiita.com/merliborn/items/63467fab96c44ed03443)

HLSがghc9系に対応するようになって、前回のような事態は一時期なりを潜めましたが、今度はVSCode起動時にHLSが起動してくれないという現象に見舞われました。勘弁してくんなまし

記憶で書いてる上にログも書き慣れてないクソ文書ですが生暖かく見てください

## 環境

* OS: Windows 10
* ghc, cabal, stack: Chocolatey 経由で導入 (下記参照)
* エディタ: [VSCode](https://code.visualstudio.com/)
* プラグイン: [Haskell for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=haskell.haskell)・[Haskell Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=justusadam.language-haskell)

[Chocolatey](https://chocolatey.org/)で導入したもの：
* cabal 3.6.2.0 (最新)
* ghc 9.2.3 (最新)
* ghc 9.0.2
* haskell-dev 0.0.1
* ~~haskell-language-server~~ ←おそらく今回の主犯
* haskell-stack 2.7.5 (最新)

## 現象
VSCodeでHakellプロジェクトを起動すると、起動時に各種セットアップが自動で行われるわけですが、謎の力によってうまくHLSが起動せず、エラーが出て終了する現象が発生しました。

この時コンソール経由で`stack init`などを試すと、それはそれで文字コードの違いに起因するエラーやらなんやかんやがでて沼ります。沼りました。沼ると数か月帰ってこれなくなるので先にほかの可能性を考えましょう(真顔)。

### 個人的な要件
<dl>
<dt>なるべくバージョン管理を考える場所を減らしたい</dt>
<dd>スタンドアロンかつ自動でアップデートチェックしてくれるものはともかく、既にChocolateyとMicrosoft StoreとTexLiveがある現状で、そう何個も何個もバージョン管理するソフトばっかり増やしたくありませんでした。</dd>
<dt>TUIモードが使えないならghcup使うメリット半分くらいなくない？</dt>
<dd>ghcupは現状、WindowsでTUIモードが使えません(真顔)。
なので先の条件と合わせると、自分の中でChocolateyからHaskell周りだけghcupにするメリットがかなりありません。Chocolateyでできるならその方がコスト少ないんじゃ。</dd>
</dl>

## 解決方法

1.野放図にインストールされたghcをいったん全てアンインストール (自動除去されずChocolateyToolsやAppDataに残ってしまったものもすべて探し、パスも除去する)

2.haskell-devおよびstackをchocolateyを使って再度導入
```console
> choco install haskell-dev
> choco install haskell-stack
```

3.別途ghc 9.0.2を導入
```console
> choco install ghc -m --version 9.0.2
```

4.HLSをChocolateyを**使わずに**、[ビルド済みのバイナリを直接入手](https://downloads.haskell.org/~hls/haskell-language-server-1.7.0.0/)して導入する。

5.展開したファイルに含まれている実行ファイルを適当なディレクトリ (`D:\HLS`など) に置いて、パスを通す。

## まとめ

今回の原因はおそらく、Chocolateyにある**haskell-language-serverパッケージの更新が最新版に追い付いていない**ことだと思われます。2022年6月現在でバージョンが1.5.1であり、対応しているghcのバージョンが9.0.1までしかないため、プロジェクト側で要求したghc v9.0.2に対応できずHLSが起動不可能になったものと考えられます。

本当は修正書いてプルリク送れたら最強なんだろうな…
NimでJSONプロパティアクセスする

JSONオブジェクトを作成し、普通に出力、整形して出力(`pretty()`)します。

```nim: nim
var js = %*{
  "name": "taro",
  "age": 33,
  "family": {
    "wife": {
      "name": "hanako",
      "age": 34
  },
  "boy": {
    "name": "ken",
    "age": 5
  },
  "girl": {
    "name": "moe",
    "age": 1
  },
}
}
echo "JSON object: ", js
# => JSON object: {"name":"taro","age":33,"family":{"wife":{"name":"hanako","age":34},"boy":{"name":"ken","age":5},"girl":{"name":"moe","age":1}}}
echo "Prettify: ", js.pretty()
#  |
#   v
#Prettify: {
#  "name": "taro",
#  "age": 33,
#  "family": {
#    "wife": {
#      "name": "hanako",
#      "age": 34
#    },
#    "boy": {
#      "name": "ken",
#      "age": 5
#    },
#    "girl": {
#      "name": "moe",
#      "age": 1
#    }
#  }
#}
```

ここで`girl`要素へアクセスするにはカッコでくくりまくらないといけないわけです。

```nim:nim
echo js["family"]["girl"]  # =>{"name":"moe","age":1}
```

Pythonなら[SimpleNamespace](https://docs.python.org/ja/3/library/types.html#types.SimpleNamespace) を使ってnamedtupleに変換できます。

```python: python
import json
from types import SimpleNamespace

jstr='''{
  "name": "taro",
  "age": 33,
  "family": {
    "wife": {
      "name": "hanako",
      "age": 34
  },
  "boy": {
    "name": "ken",
    "age": 5
  },
  "girl": {
    "name": "moe",
    "age": 1
  }
}
}'''

jobj=json.loads(jstr)
print(jobj["family"]["girl"])
# => {'name': 'moe', 'age': 1}

jprop=json.loads(jstr, object_hook=lambda x: SimpleNamespace(**x))
print(jprop.family.girl)
# => namespace(name='moe', age=1)

```

Nimで同じようにプロパティアクセスするには、型を指定して、[to](https://nim-lang.org/docs/json.html#to%2CJsonNode%2Ctypedesc%5BT%5D)メソッドを使ってnamedtupleの代わりにオブジェクトへ変換するようです。

最初のNimコードに追記します。

```nim: nim
(...snip...)
type Person=object
  name: string
  age: int

type Family=object
  wife: Person
  boy: Person
  girl: Person

type Household=object
  name: string
  age: int
  family: Family

let jprop=js.to(Household)
echo jprop.family.girl
# => (name: "moe", age: 1)
```

Goの`json.Marshal()`ぽいと思いました。
htmlのアクセシビリティについて -セマンティクス-

# htmlは見た目だけ整えれば良い訳では無いという話

htmlを学んでいる中でアクセシビリティとセマンティクスについて学んだのでメモ。
参考URLは下記。

https://developer.mozilla.org/ja/docs/Learn/Accessibility/HTML#good_semantics

*メモ：このようなドキュメントは往々にして冗長であり、読むのに少々時間がかかることが多い。*


## セマンティクス

セマンティクス (semantics)：「意味論」
すなわち、見た目だけ整った「ぐちゃぐちゃな」コード（スパゲティコード）では、下記点から不利である。

- 開発しにくい
`button`で囲むべきところを`div`で囲んでしまうと、本来htmlで得られる`button`の機能を失ってしまう。
javascript等で`div`に`button`の機能を強制的に付与することは可能だが、ページの読み込み・動作を遅延させるだけであり、スマートなコードとは言えない。

- モバイル機器へのアクセシビリティ
セマンティックに書かれたコードはファイルサイズの点でほぼ間違いなく軽量、レスポンシブにするのも簡単。

- SEO
検索エンジンのクローラーは、非意味的な`div`などに含まれるキーワードよりも、見出しやリンクなどの中のキーワードの方に重みを持たせてデータ収集している。
よって、セマンティックに書くことでドキュメントがより顧客に見つけてもらいやすくなる。

## セマンティックに書く（実例）

**セマンティックに書かない場合**

```html:index.html
<!-- セマンティックに書かない場合 -->
<div class="article">
    <h1 class = "section-title">セマンティックに書く事の優位性</h1>
    <p>～～本文～～</p>
    <h1 class = "section-title">セマンティックに書かないと…？</h1>
    <p>～～本文～～</p>
</div>
```
**セマンティックに書く場合(HTML5)**

```html:index.html
<!-- セマンティックに書く場合 -->
<article>
    <section>
    <h1 class = "title">セマンティックに書く事の優位性</h1>
    <p>～～本文～～</p>
    </section>

    <section>
    <h1 class = "title">セマンティックに書かないと…？</h1>
    <p>～～本文～～</p>
    </section>
</article>
```

ここで使用したarticleとsectionについては下記URLが詳しい。

- https://www.cyber-bridge.jp/cbmedia/webdesign/html-article-section/
- https://web-camp.io/magazine/archives/85309

下記ドキュメントもあるが、若干わかりづらい
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/article
React: JavaScript heap out of memory

次の環境でテストしました。

```text
$ node --version
v14.19.0
$ npm --version
6.14.16
```

起動時にエラーが出ました。

```bash
npm start
```

```text
<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memo
ry
 1: 0xa3aaf0 node::Abort() [node]
 2: 0x970199 node::FatalError(char const*, char const*) [node]
 3: 0xbba45e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bo
ol) [node]
```

##  解決策 ##

```bash
export NODE_OPTIONS="--max-old-space-size=2048"
npm start
```
python 正規表現(メモ)

# 正規表現のメモ
自分用のメモです。。。

・「.(ドット)」
なんでもいい1文字
例)
```
pattern = ".球"
# 野球
# 卓球
# 草野球 →×
```

・「+(プラス)」
直前のパターンの1回以上繰り返し
例)
```
pattern = ".+球"
# プロ野球
# 野球
# 球 →×
```

・「*」
直前のパターンの0回以上繰り返し
例)
```
pattern = ".*球"
# プロ野球
# 野球
# 球
```

・「?」
直前のパターンの0回か1回
例)
```
pattern = ".?球"
# 野球
# 球
# プロ野球 →×
```

・{min, max}
繰り返し回数を指定(min, maxそれぞれ省略可)
例)
```
pattern = ".{1,4}球"
# 野球
# プロ野球
# 少年軟式野球 →×
```

・()
対象パターンをグループ化
例)
```
pattern = "(えい)+"
# えい
# えいえいえい
```

・(|)
いずれか
例)
```
pattern = "(はい|おう)+!"
# はいはい！
# おうおう！
```

・[abc]
囲んだ文字にマッチ
文字クラスと呼ばれる
例)
```
# 半角数字
pattern = "[0123456789]"
# 文字コード上で連続する場合
# 半角数字
pattern = "[0-9]"
# アルファベット小文字大文字
pattern = "[a-zA-Z]"
```
・[^]
囲んだ文字の否定
例)
```
# 半角数字以外
pattern = "[^0123456789]"
# アルファベット小文字大文字以外
pattern = "[^a-zA-Z]"
```
・^
先頭文字
例)
```
pattern = "^今日"
# 今日は晴れ
```

・$
末尾
例)
```
pattern = "。$"
# 今日は晴れ。
```
FreeBSD/llvm13 コンパイルに失敗するときのTIPS(2022年限定）

この半年くらい、llvm13 では FLANGオプションのコンパイルが失敗します。
対処法はなさそうなので、FLANG対応 は当面（というかFORTRAN使わないなら）外すしかありません。
lang/f18 が入っていたら良い方向に変化があるかもしれませんが、FORTRANを使う予定が０なので試していません。llvm系は日進月歩なのですぐに治るだろうと思っていましたが3ヶ月状況が変わらない感じですので書いておきます。
pythonのアンダースコア

# pythonのアンダースコア(_)を使う
コードを見ていると所々に出てくるアンダースコア。
変数の頭に付いていたり、関数の頭に二つ付いていたり、どんな意味があるかまとめた。

### 必要のない値を一時的に格納するもの

例
・for文
```
    # 単純に文字列を5回出力したいだけ。range()から取り出した変数は使わない。
    for _ in range(5):
        print("test")
```
・return値を返さない
```
def main():
    a = "hoge"
    b = "fuga"
    return a, b

if __name__ == '__main__':
    # aしか出力しない
    # bは廃棄される。
    a, _ = main()
    print(a)

```

### 関数名や変数名の頭に1つ付いているもの
クラス内メソッドや変数
あくまでも慣例的なので、外部からアクセス可能
importのワイルドカードで読み込まれない

### 関数名や変数名の頭に2つ付いているもの
ネームマングリングを適用することができる


ネームマングリングとは
クラス内のアンダースコアが２つ付いたメソッドや変数の名前を「_クラス名」+「変数名(メソッド名)」に変換する。その結果外部から定義した変数名やメソッド名で呼び出すことができなくなる。

### 関数名や変数名の後ろに1つ付いているもの
pythonの予約語と同じ関数名や変数名の場合、衝突を防ぐことができる

### 関数名の前後に2つずつついているもの
pythonで特別な用途で使用する、マジックメソッドを意味する。
Storage Access API メモ


* 3rd Party Cookie を用いたトラッキングがブロックされることで、 Single Sign On を始めとしたユースケースに影響が出た。
* これに対して、明示的に3rd Party Cookie にアクセスする方法を提供する手段である Storage Access API について個人用にメモする。

## 背景

* ほとんどのブラウザーは、クロスオリジンリソースのクッキーやサイトデータへのアクセスを制限している。 
  * これらの制限は、サードパーティのコンテキストでリソースが読み込まれた場合にストレージアクセスの完全なブロックにまで及ぶ。
* これらのクッキーブロックポリシーは、ファーストパーティストレージへのアクセスを必要とする埋め込まれたクロスオリジンコンテンツの中断につながる。
  * 例：フェデレーションログイン
    * ファーストパーティストレージに保存されている認証クッキーへのアクセスが必要になることが多く、これらのクッキーが利用できない場合、ユーザーは各サイトに個別にサインインする（または完全に中断する）必要がある。
    * 中断した場合、サイト所有者は、ユーザーにサイトを例外として追加するか、ポリシーを完全に無効にすることを推奨することがある。 
    * 埋め込まれたコンテンツとのやり取りを継続することを希望するユーザーはリソースのブロックポリシーを大幅に緩和する必要がある。

## 対策：Storage Access API

* 上述の問題への対策として、ユーザーがサードパーティのCookieを操作するときに、サードパーティの埋め込みがファーストパーティのCookieへのアクセスを要求できるようにする**`StorageAccessAPI`**が提案された。
* Storage Access APIは、クロスオリジンiframeに2つの関数`Document.hasStorageAccess()`と`Document.requestStorageAccess()`を提供する。
  * `Document.requestStorageAccess()`
    * サイトごとにファーストパーティストレージへの無制限のアクセスを要求する。
    * ファーストパーティストレージへのアクセスが許可された場合に解決し、アクセスが拒否された場合に拒否する `Promise` を返却する。
  * `Document.hasStorageAccess()` 
    * 既にアクセス権があるかどうかを確認する。
    * ファーストパーティストレージにアクセスできるかどうかを示すブール値で解決される `Promise`を返却する。
* 埋め込みトップフレームに新しいiframeサンドボックストークン`allow-storage-access-by-user-activation`を提供する。

### ストレージアクセス権を確認する

* `Document.hasStorageAccess()`を呼び出すと、既にファーストパーティのCookieにアクセスできるかどうかを示すブール値で解決されるpromiseが返される。

* iframeがトップフレームと同一生成元である場合、promiseはtrueを返す。

  ```javascript
  var promise = document.hasStorageAccess();
  promise.then(
    function (hasAccess) {
      // Boolean hasAccess says whether the document has access or not.
    },
    function (reason) {
      // Promise was rejected for some reason.
    }
  );
  ```

### ストレージアクセスをリクエストする

* `Document.requestStorageAccess()`を呼び出すと、ストレージアクセスが許可された場合は解決され、アクセスが拒否された場合は拒否されるPromiseが返却される。

* ストレージアクセスが許可されている場合、`Document.hasStorageAccess()`を呼び出すとtrueが返却される。

* Cookieがいつ変更されるかを開発者が制御できるようにするために、iframeからこのAPIを明示的に呼び出す。

  ```javascript
  <script>
  function makeRequestWithUserGesture() {
    var promise = document.requestStorageAccess();
    promise.then(
      function () {
        // Storage access was granted.
      },
      function () {
        // Storage access was denied.
      }
    );
  }
  </script>
  <button onclick="makeRequestWithUserGesture()">Play video</button>
  ```

  

## iframeがストレージアクセスを許可するために準拠すべき基本ルール

- iframeのCookieは、現在ITPによってパーティション化されていること。
  - そうでない場合、iframeはすでにCookieにアクセスできるか、Cookieが削除されているためにアクセスを許可できない。
- iframeはトップフレームの直接の子であること。
- iframeは、API呼び出し時にユーザージェスチャ/アクションを処理していること。

## 参考情報

* [Storage Access API](https://developer.mozilla.org/ja/docs/Web/API/Storage_Access_API)
* [Introducing Storage Access API](https://webkit.org/blog/8124/introducing-storage-access-api/)
First-Party Sets メモ



## 概要

* 関連するドメインをまとめてひとつのファーストパーティであると宣言できる技術
  * パーティ
    * first-party：現在アクセスしているドメイン
    * third-party：現在アクセスしているドメインとは異なるドメイン
* 実際のWebサイト/アプリでは複数のドメインにまたがって運用されていることがある。
* First-Party Setsを利用することでログイン状態を維持しつつドメインを跨ぐことができる。
* 導入計画段階

## 仕組み

* 他ドメインとの関係を定義するマニフェスト ファイル (`.well-known/first-party-set` アドレスの JSON ファイル) を提供することで、一連の Web ドメインのメンバー (または所有者) であることを宣言する。

* 例

  * `a.example`、`b.example`、および `c.example` が `a.example` が所有する first-party set を形成する場合

  ```json
  // https://a.example/.well-known/first-party-set
  {
    "owner": "a.example",
    "members": ["b.example", "c.example"],
    ...
  }
  
  // https://b.example/.well-known/first-party-set
  {
      "owner": "a.example"
  }
  
  // https://c.example/.well-known/first-party-set
  {
      "owner": "a.example"
  }
  ```

* 流れ

  1. 所有者ドメインは、そのメンバードメインを一覧表示するマニフェストファイルをホストする。
     * `https://<domain>/.well-known/first-party-set`
     * [許可されるセットポリシー](https://github.com/WICG/first-party-sets#ua-policy)

  2. ブラウザは、メンバードメインの Web サイトに対して所有者を指定する。

  3. ブラウザは、所有者のマニフェストを確認して関係を検証するように要求する。

* 禁止事項

  * 関連のないサイト間でのユーザー情報の交換
  * 同じ組織が所有していないサイトのグループ化

* 対応

  * 提案されたドメインのグループと、ブラウザポリシーを満たすために必要な情報を、パブリックトラッカー (専用の GitHub リポジトリなど) に送信する。
  * メンバードメインに対する所有者の検証で、各ドメインの `.well-known` URL でサービスを提供するための検証を行う、など



## 参考情報

* [First-Party Sets](https://developer.chrome.com/ja/docs/privacy-sandbox/first-party-sets/)
* [First-Party Sets](https://github.com/WICG/first-party-sets)
OWASP A07:2021 – Identification and Authentication Failures メモ


OWASP A07:2021 – Identification and Authentication Failuresについて個人用にメモする。
※かなり以前にまとめたもの

## 概要

* これまではBrokenAuthenticationとして扱われていたカテゴリの脆弱性

* 該当するCWE（Common Weakness Enumeration、ソフトウェアにおけるセキュリティ上の脆弱性の種類を識別するための共通の基準)

  | CWE No. | 内容                                     |
  | ------- | ---------------------------------------- |
  | CWE-287 | 不適切な認証                             |
  | CWE-297 | ホストの不一致による証明書の不適切な検証 |
  | CWE-384 | セッション固定化                         |




## 説明

* 認証関連の攻撃から保護するには、ユーザーのID、認証、およびセッション管理の確認が重要。

* アプリケーションが次の状態の場合、認証処理に脆弱性を含んでいる可能性がある。
  * (攻撃者が、有効なユーザー名/パスワードのリストを持っている場合、)資格情報の連続入力など自動化された攻撃を許可している場合
  * ブルートフォースまたはその他の自動化された攻撃をブロックしていない場合

  * 「Password1」や「admin / admin」など、デフォルト、脆弱、または既知のパスワードを許可している場合
  * 「個人に関する質問」など、弱いもしくは効果のないリカバリ手段を利用している場合
  * プレーンテキスト、暗号化、もしくは弱くハッシュ化されたパスワードを使用している場合
  * 多要素認証を利用していない場合
  * URL上にセッションIDを公開している場合
  * ログイン成功後、セッションIDをローテーションしていない場合
  * ユーザーセッションや認証トークン（主にシングルサインオン（SSO）トークン）をログアウト中や非アクティブ期間中に無効化しない場合

## 対策

* 多要素認証を実装し、次の攻撃を防止する。
  * クレデンシャルスタッフィング(インターネット上に流出したIDとパスワードの組み合わせを使って、他のWebサイトへのログインを自動的に試みる攻撃)
  * ブルートフォース
  * 盗まれたクレデンシャル再利用攻撃

* 管理者ユーザーの資格情報をデフォルトのままデプロイしない。
* パスワードチェック処理の実装
  * 新規または変更されたパスワードを上位10,000の最悪のパスワードリストと照合してチェックする、など。

* パスワードの長さ、複雑さ、およびローテーションポリシーをNIST800-63bのガイドラインに合わせる。
* ログイン処理の結果に、同じメッセージを使用する(アカウント列挙攻撃対策)
* ログイン試行を制限もしくは再試行にウェイトを設ける。すべてのログイン試行失敗をログに記録し、管理者にアラートを通知する。
* ログイン後にエントロピーの高い新しいランダムセッションIDを生成する、サーバー側の安全な組み込みセッションマネージャーを使用する。
  * セッションIDは、URLに含めず、安全に保存し、ログアウト、タイムアウト後などに無効にする。

## 攻撃シナリオ

### シナリオ＃1

* クレデンシャルスタッフィング攻撃(既知のパスワードリストの使用)対策していない場合

  → アプリケーションをクレデンシャルリストの有効性確認に利用されてしまう。

### シナリオ＃2

* アプリケーションセッションのタイムアウトが正しく設定されていない場合。
  1. ユーザーは、公共のコンピューターを使用してアプリケーションにアクセスする
  2. 「ログアウト」を選択する代わりに、ユーザーはブラウザのタブを閉じて立ち去る
  3. 攻撃者は1時間後に同じブラウザを使用しますが、ユーザーは引き続き認証される



## 参考情報

* [Introduction to OWASP Top 10 2021/A07:2021 – Identification and Authentication Failures](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/)
OWASP A01:2021 – Broken Access Control メモ



* OWASP TOP10 （最も一般的な10のアプリケーションの脆弱性のリスト）のA01:2021 – Broken Access Control についてメモする。
※かなり以前にまとめたもの
## 概要

* アクセス制御の不備に関する脆弱性

* 該当するCWE

  | CWE No. | 内容                                       |
  | ------- | ------------------------------------------ |
  | CWE-200 | 不正なアクターへの機密情報の公開(情報漏洩) |
  | CWE-201 | 送信データによる機密情報の公開             |
  | CWE-352 | クロスサイトリクエストフォージェリ（CSRF） |

  ※CWE  :  Common Weakness Enumeration、ソフトウェアにおけるセキュリティ上の脆弱性の種類を識別するための共通の基準

* **アクセス制御の不備がもたらす影響**

  * データの不正な情報開示や変更、破壊、
  * 制限外のビジネス機能の利用

* **一般的なアクセス制御に関する脆弱性**

  * アクセス制御チェックのバイパス
    * URLやアプリの内部状態、HTMLページの変更など

  * 他ユーザーのアカウント情報の参照または編集
  * 権限昇格
    * 本来与えられないはずの権限がユーザーに与えられる

  * メタデータ操作
    * JSON Web Token（JWT）のリプレイ攻撃や改竄
    * Cookieまたは非表示フィールドの操作　など

  * 不正なAPIアクセス
    * CORS設定ミスによる

  * 権限外情報の強制参照
    * 未ログイン状態でログイン済みページへアクセス
    * 標準ユーザーのログインから特権/管理者ページへアクセス
    * アクセス制御が欠落しているAPIへのアクセス。




## 対策

* 攻撃者へのアクセス制御チェックもしくはメタデータを変更できないようサーバー側コードを記述
  * パブリックリソースを除き、デフォルトではアクセス拒否
  * アクセス制御機能を実装し、アプリケーション全体で利用
  * ユーザーが任意のレコードを作成、読み取り、更新、または削除できることを受容せず、レコードの所有権を強制させる
  * 固有のビジネス要件による制限は、ドメインモデルによって実施
  * ファイルメタデータやバックアップファイルをWebルート内に配置させない
  * ログイン操作の失敗回数などをログ記録し、必要に応じて管理者へアラートを通知
  * 自動化された攻撃ツールに対してアクセスレート制限を実施
  * JWTトークンをログアウト後にサーバーで無効化

* 開発担当とQA担当は、機能的なアクセス制御に関する統合テストを実施する。



## 攻撃シナリオ

### シナリオ例①

* 未検証パラメータを使用したユーザー情報アクセス

```java
pstmt.setString（1、request.getParameter（ "acct"））;
ResultSet results = pstmt.executeQuery（）;
```

1. 攻撃者は、ブラウザの「acct」パラメータを変更し、必要なアカウント番号を送信する
2. 正しく検証されていない場合、攻撃者は任意のユーザーのアカウントにアクセスできる

### シナリオ例②

* 管理権限が要求されるようなページへのアクセス

```
https://example.com/app/getappInfo
https://example.com/app/admin_getappInfo
```

* 以下の場合は脆弱性に該当する。
  * 未認証ユーザーがどちらかのページにもアクセスできる場合
  * 管理者以外の人が管理者ページにアクセスできる場合



## 参考情報

* [Introduction to OWASP Top 10 2021/A01:2021 – Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)
* [共通脆弱性タイプ一覧CWE概説](https://www.ipa.go.jp/security/vuln/CWE.html)
RFC 9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens メモ


* OAuth 2.0アクセストークンのJSON Webトークン（JWT）プロファイルについてメモする。



## JWT Access Token Header and Data Structure

### ヘッダ

* `alg`:必須。JWTトークンの署名アルゴリズムを指定。

### データ構造

* iss,exp,aud,sub,iat,jti(RFC7519参照のこと)などの他、認証情報、アイデンティティ、認可情報などのクレームで構成される。

## Requesting a JWT Access Token

* リクエスト

```http
GET /as/authorization.oauth2?response_type=code
           &client_id=s6BhdRkqt3
           &state=xyz
           &scope=openid%20profile%20reademail
           &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
           &resource=https%3A%2F%2Frs.example.com%2F HTTP/1.1
Host: authorization-server.example.com
```

* レスポンス

  * ヘッダー

    ```json
    {
        "typ":"at+JWT",
        "alg":"RS256",
        "kid":"RjEwOwOA"
    }
    ```

  * クレーム

    ```json
    {
            "iss": "https://authorization-server.example.com/",
            "sub": "5ba552d67",
            "aud": "https://rs.example.com/",
            "exp": 1639528912,
            "iat": 1618354090,
            "jti" : "dbe39bf3a3ba4238a513f51d6e1691c4",
            "client_id": "s6BhdRkqt3",
            "scope": "openid profile reademail"
    }
    ```

    

##  Validating JWT Access Tokens

* 次の流れで検証を行う。
  1. `alg`で指定されたアルゴリズムを使用して、署名を検証する。
     * `alg`が指定されていないトークンは拒否する。
  2. `Typ`ヘッダ値が`jwt`、`at+JWT`または`application/at+jwt`であることを確認する。
  3. (JWTアクセストークンが暗号化されている場合、)指定されたキーとアルゴリズムを使用して復号化する。
     * 認可サーバーと暗号化がネゴシエートされていながら、JWTアクセストークンが暗号化されていない場合、そのトークンを拒否する。
  4. 認可サーバーの発行者識別子が`iss`クレームの値と完全一致していることを確認する。
  5. `aud`クレームに有効なリソースインジケーターが含まれているかを確認する。
  6. 現在時刻が`exp`に指定された値よりも前であることを確認する。
  7. (認可クレーム`scope`などが含まれる場合、)リクエストの文脈情報と組み合わせて、リクエストの許可または拒否されるべきかどうかを確認する。

## セキュリティに関する考慮事項

* cross-JWT confusion
  * 傍受したトークンを、所定の⽬的以外の⽬的で使⽤する攻撃。
  * `aud`クレーム値としてユニークな識別子を使用し、個別のリソースに対して同じ発行者によって発行されたアクセストークンを一意に識別する。
* トークンリクエストに複数のリソースインジケータが含まれている場合、認可サーバーはJWTアクセストークンに含まれる各スコープが、`aud`クレームに関連付けられる特定のリソースと関連があることを確認する。



## 参考情報

* [RFC 9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens 日本語訳](https://tex2e.github.io/rfc-translater/html/rfc9068.html)
ARRAYFOMULA 関数で複数行のそれぞれの合計を計算する話

## はじめに

スプレッドシートにある ARRAYFOMULA 関数の備忘録まとめとなります。

> 公式ページ

[ARRAYFORMULA](https://support.google.com/docs/answer/3093275)

> サンプルソース

- スプレッドシート
[arrayformula](https://docs.google.com/spreadsheets/d/1VbyiFZ5z9NT_UmhChrGKRm3qPIBSW8bR4SKw02KZGMA/edit?usp=sharing)

## SUM 関数を使う方法

ARRAYFORMULA(SUMIF(IF(COLUMN(1行目の範囲),ROW(1列目の範囲)),ROW(1列目の範囲),全体の範囲))

```
=ARRAYFORMULA(SUMIF(IF(COLUMN(B2:D2),ROW(B2:B6)),ROW(B2:B6),B2:D6))
```
adbで「adb.exe: more than one device/emulator」が出るとき



複数のAndroidがPCに接続されてたりエミュレータが立ち上がってるとき

```powershell
PS C:\Users\frieren> adb devices
List of devices attached
192.168.1.8:39333       device
emulator-5554   device
```

そのまま`adb shell`するとエラーが出る

```powershell
PS C:\Users\frieren> adb shell
adb.exe: more than one device/emulator
```

こういうときは`adb -t 1 shell`みたいにデバイスを指定する。
 **デバイスを指定するためのオプションはshellの前に書かないと働かないので注意。**

# USB接続のデバイスを指定: `adb -d shell`
> use USB device (error if multiple devices connected)

複数台あるとエラー。


# TCP/IP接続のデバイスを指定: `adb -e shell`
> use TCP/IP device (error if multiple TCP/IP devices available)

複数台あるとエラー。
エミュレータも含まれるみたい。

# Transport IDで指定: `adb -t 1 shell`

> use device with given transport id

Transport IDは`adb devices -l`で確認できる。

```powershell
PS C:\Users\frieren> adb devices -l
List of devices attached
192.168.1.8:39333      device product:crosshatch model:Pixel_3_XL device:crosshatch transport_id:2
emulator-5554          device product:sdk_gphone64_x86_64 model:sdk_gphone64_x86_64 device:emu64xa transport_id:1
```

# シリアルで指定: `adb -s XXXXX shell`
> use device with given serial (overrides $ANDROID_SERIAL)

シリアルといってもデバイスのシリアル番号のことじゃない。紛らわしい。
`adb devices`の最初に出てるデバイス名みたいなもののこと。

シリアルだけじゃなくて上記だと`adb -s product:crosshatch shell`みたいにやっても接続できたり、ほかにも接続できる書き方はあるっぽい。

# オプションじゃなく環境変数で指定

ANDROID_SERIALに上記シリアルを書き込むとずっと使ってくれるらしい。

https://developer.android.com/studio/command-line/variables?hl=ja#:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,adb%20%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0,-ANDROID_SERIAL

```powershell:windows(powershell)で一時的に指定したいとき
$env:ANDROID_SERIAL = "emulator-5554"
```

```powershell:windows(powershell)でずっと指定したいとき
[Environment]::SetEnvironmentVariable("ANDROID_SERIAL", "emulator-5554", "User")
```

windows以外のやり方は誰でも分かるので書きません

# 参考URL
https://developer.android.com/studio/command-line/adb?hl=ja

https://stackoverflow.com/questions/14654718/how-to-use-adb-shell-when-multiple-devices-are-connected-fails-with-error-mor

---

ググったらエミュレータ終了しようとか出るけど選択できないわけないでしょって思って調べました。
昔はなかったのかも？
DNS名を付けるように構成する

# DNS名を付けるように構成する
AWSマネジメントコンソールでVPCダッシュボードを表示します。

左メニューの「お使いのVPC」をクリックしてください。

DNS名を設定するEC2インスタンスのあるVPCをチェックし、アクションの「DNSホスト名の編集›」をクリックしてください。

![スクリーンショット 2022-06-25 7.00.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/ae2c723a-ddb5-50ac-c0b7-72225c0b563e.png)

DNSホスト名の編集ページが表示されます。
「有効化」をチェックし、「変更を保存」をクリックしてください。
![スクリーンショット 2022-06-25 7.00.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/c4e0b299-631f-7d82-71c4-c4ad891ecc08.png)

# 割り当てられたDNS名を確認する
AWSマネジメントコンソールEC2ダッシュボードを表示します。
DNS名を付けたいEC2を表示します。
パブリックDNSとプライベートDNSの部分に割り当てられたDNS名が表示されます。

以上です。
「いちばんやさしい新しいサーバーの教本」を流し読みした要点と図説

[いちばんやさしい新しいサーバーの教本 人気講師が教える動かして理解する基礎からコンテナまで (いちばんやさしい教本シリーズ) | 水野 源, 宮原 徹 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4295013188)
[いちばんやさしい新しいサーバーの教本 人気講師が教える動かして理解する基礎からコンテナまで - インプレスブックス](https://book.impress.co.jp/books/1121101028)

説明用に、必要十分な本だったのでメモ。


## 要点

### サーバーとインターネット


```plantuml
客 -> ウォーターサーバー :水を飲みたい
ウォーターサーバー -> 客 :水
```
<br>

```plantuml
Webブラウザ -> Webサーバー: URLを入力 （リクエスト）
Webサーバー -> Webブラウザ: HTMLや画像 （レスポンス）
```
<br>

インターネットでこのやりとりをする「プロトコル」がTCP/IP
```plantuml
クライアント -> サーバー: 「接続します」
サーバー -> クライアント: 「どうぞOKです」
クライアント -> サーバー: 「こちらもOKです」
```

### 仮想マシンを動かそう

|仮想サーバー1|仮想サーバー2|仮想サーバー3|
|:-----:|:-----:|:-----:|
|アプリ   |アプリ  |アプリ  |
|ミドル   |ミドル  |ミドル  |
|OS      |OS   |OS   |
|VM      |VM   |VM   |
|└ |ハイパーバイザー  |┘|
|└ |実サーバーハードウェア    |┘| 

実サーバー1台 + 仮想サーバー3台


### ネットワークの動作を確認しよう

|OSI参照モデル |
|:--|
|アプリケーション層(L7)   |
|プレゼンテーション層(L6)    |
|セッション層(L5)    |
|トランスポート層(L4)   |
|ネットワーク層(L3)    |
|データリンク層(L2)   |
|物理層(L1)    |


| インターネットプロトコルスイート | |
|:-|:-|
| アプリケーション層  |HTTP, SMTP, FTP ... etc |
| トランスポート層  |TCP, UDP ... etc |
| インターネット層  |IPv4, IPv6 ... etc|
| ネットワーク・インターフェース層   | PPP, イーサネット ... etc|


```plantuml
クライアント -> サーバー: ping送信
サーバー -> クライアント: ping応答
```
<br>

DNSによる名前解決

```plantuml
クライアント -> DNSルートサーバー: 「www.example.comのIPアドレスは？」
DNSルートサーバー -> クライアント: 「.comのサーバーに聞いてください」
クライアント -> .comのDNSサーバー: 「www.example.comのIPアドレスは？」
.comのDNSサーバー -> クライアント: 「example.comのサーバーに聞いてください」
クライアント -> example.comのDNSサーバー: 「www.example.comのIPアドレスは？」
example.comのDNSサーバー -> クライアント: 「192.0.2.1です」
```

## 他

[Webページがブラウザに表示されるまでに何が起こるのか？](https://zenn.dev/ak/articles/61d25099295372)
[tetz-akaneya/what-happens-when-JA](https://github.com/tetz-akaneya/what-happens-when-JA)

以上です～
2022/6/25主にITとかセキュリティの記事

Google、「Chrome 103」をリリース - 重要度「「クリティカル」の脆弱性に対処
https://www.security-next.com/137564

ランサム被害の鳴門山上病院、通常診療を再開
https://www.security-next.com/137596

「OpenSSL」にスクリプトインジェクションの脆弱性 - アップデートが公開
https://www.security-next.com/137569

KnowBe4最新調査レポート： セキュリティ意識向上トレーニングの頻度を増やすことで、セキュリティ侵害の予防が改善される(6/23)
https://www.jiji.com/jc/article?k=000000098.000053624&g=prt

被害を最小限に抑えるために　フィッシング詐欺から身を守る4つのポイント(6/22)
https://news.goo.ne.jp/article/moneypost/life/moneypost-917328.html

サプライチェーン全体のサイバーセキュリティ強化に向けた取り組み
－サイバーセキュリティ委員会サイバーセキュリティ強化ワーキング・グループ(6/23)
https://www.keidanren.or.jp/journal/times/2022/0623_11.html

新種のランサムウェアとその亜種、2021年には大幅に減少 - ウィズセキュアがリサーチ(6/23)
https://www.jiji.com/jc/article?k=000000335.000001340&g=prt

PowerShellの無効化は現実的ではない、設定すれば問題なし - 米国当局(6/23)
https://news.mynavi.jp/techplus/article/20220623-2376139/

「東芝グループ サイバーセキュリティ報告書２０２２」の発行について(6/23)
https://www.global.toshiba/jp/news/corporate/2022/06/news-20220623-01.html

増加する北朝鮮のサイバー攻撃　“国家主導”の脅威アクターから自社をどう守る(6/23)
https://enterprisezine.jp/article/detail/16161

トヨタ紡織子会社、タイ販社に不正アクセス　データ漏洩(6/23)
https://www.nikkei.com/article/DGXZQOFD2328M0T20C22A6000000/

「Adobe Acrobat Reader」がセキュリティチェックをブロックか ~イスラエルの会社が指摘／セキュリティソフトのDLLインジェクションを無効化(6/23)
https://gunosy.com/articles/ei4xy

トヨタ紡織グループ会社にサイバー攻撃、生産・販売活動に影響なし(6/23)
https://e-nenpi.com/article/detail/358950

「Adobe Acrobat Reader」がセキュリティチェックをブロックか ~イスラエルの会社が指摘／セキュリティソフトのDLLインジェクションを無効化(6/23)
https://gunosy.com/articles/ei4xy

「サムライバックドア」と「忍者トロイ」用いる、未知の脅威が出現(6/23)
https://news.mynavi.jp/techplus/article/20220623-2375725/

第一生命、6月16日に発生したシステム障害について陳謝(6/23)
https://www.nikkei.com/article/DGXZRSP635098_T20C22A6000000/

犯罪手法としても使われるソーシャル・エンジニアリングの主な手口やその対策(6/23)
https://ascii.jp/elem/000/004/095/4095288/?rss

IE11サポート終了の本当の問題って何だろう(6/23)
https://www.itmedia.co.jp/pcuser/articles/2206/23/news115.html

「Slack」でメッセージの送信日時を設定するには(6/23)
https://japan.zdnet.com/article/35189288/

【 New-NetIPAddress 】コマンドレット――ネットワークアダプターに静的IPアドレスを設定する(6/23)
https://atmarkit.itmedia.co.jp/ait/articles/2206/23/news003.html

Windows 10 / 11、ロシアでダウンロードできなくなる(6/23)
https://www.zaikei.co.jp/article/20220623/677849.html

SNSを用いた詐欺事件に注意！(6/23)
https://www.saga-s.co.jp/articles/-/874524

「ウイルスバスター ビジネスセキュリティ」がWindows 7を繰り返し再起動させる不具合
パターンファイルのアップデートとエージェントの再インストールを推奨(6/23)
https://forest.watch.impress.co.jp/docs/news/1419580.html

EC支援のShopify副社長「NFTで商店に新体験」 テックの未来(6/23)
https://www.nikkei.com/article/DGXZQOUC213RF0R20C22A6000000/

宮城県警サーバーで不正中継　3万件の国外メール転送(6/23)
https://www.nikkei.com/article/DGXZQOUE22DIH0S2A620C2000000/

Google Chromeの拡張機能を利用していると追跡される恐れ(6/23)
https://news.mynavi.jp/techplus/article/20220623-2375439/

クラウドにバックアップを取るユーザーが最多に、ただし「使い方が不適切」(6/23)
https://atmarkit.itmedia.co.jp/ait/articles/2206/23/news174.html

ドージコインはテロや児童性的虐待資料との結びつきが強まる(6/23)
https://nextmoney.jp/?p=51234

テレワーク実施率の地域差がはらむ大問題、都市と地方の経済格差がさらに拡大へ(6/24)
https://xtech.nikkei.com/atcl/nxt/column/18/00989/052700086/

DNS(6/24)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031500132/061700004/

物流を救う技術、ドローンと自動運転よりグーグルが先に来た(6/24)
https://xtech.nikkei.com/atcl/nxt/column/18/01268/00058/

富士通クラウドに不正アクセス　利用者データや認証情報が流出(6/24)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031800050/061700040/
ローカルWebサーバーを立てる方法

## Node.js
Node.js がインストールされている場合には`npx serve`を実行してローカルのWebサーバを立てられます。

```:ターミナル
$ npx serve
   ┌────────────────────────────────────────────────┐
   │                                                │
   │   Serving!                                     │
   │                                                │
   │   - Local:            http://localhost:3000    │
   │   - On Your Network:  http://172.22.0.2:3000   │
   │                                                │
   └────────────────────────────────────────────────┘
```
http://localhost:3000 にアクセスします。
![スクリーンショット 2022-06-25 午前3.17.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6d00d29a-b007-4117-dbb1-5f5eb1069fef.png)



`serve`の後にフォルダ名を指定できます。
```:ターミナル
$ npx serve フォルダ名
```

また以下のオプションを使用できます。
```
      --help                                ヘルプメッセージを表示
      -v, --version                         バージョンを表示
      -l, --listen {underline listen_uri}   リッスンする URI エンドポイントを指定する（複数指定可）
      -p                                    ポートを指定(デフォルトは 3000)
      -d, --debug                           デバッグ情報を表示
      -s, --single                          見つからないリクエストをすべて\ `index.html\`に書き換え 
      -c, --config                          \`serve.json\`へのカスタムパスを指定
      -C, --cors                            CORSを有効にし、\`Access-Control-Allow-Origin\`を\`*\`に設定
      -n, --no-clipboard                    ローカルアドレスをクリップボードにコピーしない
      -u, --no-compression                  ファイルを圧縮しない
      --no-etag                             \ `ETag\`の代わりに\`Last-Modified\`ヘッダーを送信
      -S, --symlinks                        404エラーを表示する代わりにシンボリックリンクを解決
	  --ssl-cert                            HTTPS で提供するための SSL/TLS 証明書へのオプションのパス
	  --ssl-key                             SSL/TLS証明書の秘密鍵へのオプションのパス private key
	  --ssl-pass                            SSL/TLS証明書のパスフレーズへのオプションのパス
      --no-port-switching                   取得時に指定されたポート以外のポートを開かない
```

https://github.com/vercel/serve

## VSCode

`Live Server`を使用します。

https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&ssr=false#overview

`Live Server`をインストールします。

画面右下に表示されている`Go Live`をクリックします。
![スクリーンショット 2022-06-25 午前3.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/dd1d852e-b772-0cb9-315e-f5aa0e7329d0.png)

自動的にブラウザが表示されます。

![スクリーンショット 2022-06-25 午前3.14.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e397bffe-7abf-2648-c539-0a5fc8f6188b.png)


`Live Preview`を使用することもできます。

https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server&ssr=false#overview


`Live Preview`をインストールします。

`html`ファイルを開き、下画像の赤枠の箇所をクリックします。
![スクリーンショット 2022-06-25 午前3.20.02のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/aef54a7f-c63f-8504-a0b7-63b799d48adb.png)

すると以下のように表示されます。
![スクリーンショット 2022-06-25 午前3.24.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b0807d49-39f1-cd29-a6a2-37065773489e.png)
PL/pgSQLを使い、PostgreSQLのクエリ内で条件分岐して例外発生を起こす

## 動機

- 現在のスキーマの数が5以下なら、新しいスキーマ`new_schema`を作りたい。
- 複数のクライアントからDBが更新される可能性があるので、競合状態になるのを防ぎたい。

処理のイメージは以下。
🟥 を実現するために PL/pgSQLを使いたい。

```
START TRANSACTION
  - CREATE SCEMA new_schema;
  - (🟥) Raise error if num(schemas) > 5
COMMIT
```

## PL/pgSQL を使うとよい

(通常のpostgresのクエリではなく) PL/pgSQL を使用することで以下の構文を使用できる。
- ① if 文
- ② raise exception 文

👉 良さそう。


## PL/pgSQLを試してみる

[【PL/pgSQL入門】PL/pgSQLを勉強したのでまとめてみた](https://qiita.com/ebichan_88/items/1effb09fbc458276ea51) がわかりやすい。
function と procedure の二種類があるが、今回は procedure を使用する。

やってみる。

postgresqlの起動

```
$ brew services start postgresql

# defaultのDBに繋がる。
$ psql -d postgres
```

[スニペット](https://qiita.com/ebichan_88/items/1effb09fbc458276ea51#%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99%E3%83%86%E3%82%B9%E3%83%88%E3%83%87%E3%83%BC%E3%82%BF%E6%8A%95%E5%85%A5)を実行してテストデータを作成する。

作成後の確認。
```
$ \dn

      List of schemas
     Name     |   Owner    
--------------+------------
 public       | daiki-kudo
 test_plpgsql | daiki-kudo
(2 rows)
```


プロシージャーの作成、実行、削除のサンプルを実行してみた。

```sql

-- 定義
CREATE OR REPLACE PROCEDURE test_plpgsql.sample1_02() AS $$ 
DECLARE 
BEGIN   
    RAISE INFO 'HELLO WORLD！！';
END;    
$$ LANGUAGE plpgsql; 

-- 実行
CALL test_plpgsql.sample1_02();
INFO:  HELLO WORLD！！
CALL

-- 削除
DROP PROCEDURE p;
DROP PROCEDURE

```

## PL/pgSQL で本題の処理を作成する

`Raise error if num(schemas) > 5` を作る。


```sql
CREATE OR REPLACE PROCEDURE p() AS $$ 
DECLARE
  schema_cnt int;
BEGIN
  SELECT COUNT(nspname) INTO schema_cnt FROM pg_catalog.pg_namespace; -- schema_cnt に代入。
  IF schema_cnt > 5 THEN
    RAISE EXCEPTION 'Schema cannot be created any more!';
  END IF;
END;
$$ LANGUAGE plpgsql; 

CALL p();
```

完成。乙です。