OmniAICreator/Qiita-1.07M huggingface dataset:
Android OS 7 以上で Charles を使う

## はじめに
社内のAndroid端末で [Charles](https://www.charlesproxy.com/) を使ったときのメモ。
Android OS 7 以上では、 SSL通信(https)を割り込むのに、以下の設定が必要だった。

Charlesについては割愛。

## 環境
Android OS 8.0.0
macOS High Sierra 10.13.6

## 証明書の書き出し
Help -> SSL Proxying -> Save Charles Root Certificate...
<img width="700" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/112186/c16ca636-3210-45bf-848a-020e0844df9c.png">

適当に `certificate.pem` で保存。

## アプリの設定
1. 書き出したファイルを追加

    rawフォルダが無ければ作成する。

    ```
/app/src/main/res/raw/certificate.pem
```


2. 設定ファイルを作成。

    格納場所は `/app/src/main/res/xml` 配下。
    ファイル名は適当に `network_security_config.xml` とする。

    ```xml:/app/src/main/res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/certificate"/> ← さっき作成したファイル
        </trust-anchors>
    </debug-overrides>
</network-security-config>
```

3. AndroidManifest.xmlに１行追加

    ```xml:AndroidManifest.xml
    <application
        android:networkSecurityConfig="@xml/network_security_config"  ← 追加
```

以上。
Kubernetes 1.14: 変更点まとめ

# はじめに

このエントリは、Kubernetes 1.14 の CHANGELOG から Kubernetes 1.14 の各変更点についてまとめたページをまとめています。

*今回から SIG 単位でまとめる形式に変更しました。*

# 1.14 の主な変更点

ここでは [1.14 What’s New](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#114-what%E2%80%99s-new) から概要を抜粋してまとめます。詳細は各 SIG の変更ページを確認ください。

- Window Node のサポートが Stable になりました  ([#116](https://github.com/kubernetes/enhancements/issues/116))
- kubectl のプラグイン機構が Stable になりました ([#579](https://github.com/kubernetes/enhancements/issues/579))
    - :memo: プラグイン機構自体の詳細は https://qiita.com/superbrothers/items/b4a0aab0575ca6d65739
- 永続ボリュームのひとつである Local Volume が GA になりました ([#121](https://github.com/kubernetes/enhancements/issues/121#issuecomment-457396290))
- Pid Limiting がベータになりました ([#757](https://github.com/kubernetes/enhancements/issues/757))
    - :memo: Pod や Node が利用する PID の数を制限する機能のことです
- Pod Priority と Preemption が GA になりました ([#564](https://github.com/kubernetes/enhancements/issues/564))
    - :memo: Pod に優先度をつけて、優先度が高い Pod がスケジュールできないときに優先度の低い Pod を退去(evict)する機能のことです
- Pod Ready++ が GA になりました ([#580](https://github.com/kubernetes/enhancements/issues/580))
    - :memo: ReadinessGate とも呼ばれている Pod の Readiness を拡張する機能のことです
    - :memo: Pod Ready++ の詳細は https://qiita.com/shmurata/items/69ffaf9e201cba1498c1 に記載してあるのでよければ参照してください
- Kubeadm: HA セットアップでコントロールプレーン間での証明書の自動コピー機能が追加されました
- Kubeadm: `kubeadm join` のワークフローをフェーズとして公開するようになりました ([#1204](https://github.com/kubernetes/kubeadm/issues/1204), [kep](https://github.com/kubernetes/enhancements/blob/master/keps/sig-cluster-lifecycle/0029-20180918-kubeadm-phases-beta.md))

# 既知の問題点

- CoreDNS 1.3.1 に [coredns/coredns#2629](https://github.com/coredns/coredns/issues/2629) の既知の問題点があり、CoreDNS が接続中に apiserever がシャットダウンすると CoreDNS がクラッシュします。この問題は CoreDNS 1.4.0 で修正されています
- flexvolume でマウントされた PVC に多数のディレクトリが存在する場合やディスクが一杯の場合、Kubelet が Restart に失敗することがあります。[#75019](https://github.com/kubernetes/kubernetes/pull/75019)

# 重大なアップグレードに関する通達と廃止予定となった機能や削除された機能と廃止予定となったメトリクス

[Kubernetes 1\.14: Urgent Upgrade Notes, Deprecations, Removed and deprecated metrics, API Changes](https://qiita.com/tkusumi/items/a824e040475fc47d311a) を参照してください。

# SIG (Special Interest Group) 毎の変更点

- [SIG API Machinery](https://qiita.com/shmurata/items/e859288053ecd6d92ec5) @shmurata
- [SIG Apps](https://qiita.com/inajob/items/bb9ac4d6ee385026d42c) @inajob
- [SIG CLI](https://qiita.com/superbrothers/items/a4bc02932f1014d49106) @superbrothers
- [SIG Network](https://qiita.com/summerwind/items/7ca97a5d6e3e2537ebca) @summerwind
- [SIG Node](https://qiita.com/yuanying/items/bccec90e14c230b87d24) @yuanying
- [SIG Scheduling](https://qiita.com/kkohtaka/items/dce5d9875478d090df90) @kkohtaka
- [SIG Storage](https://qiita.com/ysakashita/items/3c27d25ad8b369aac9a6) @ysakashita
- [SIG Auth](https://qiita.com/hiyosi/items/f90803a1f3d0a4880b5f) @hiyosi 
- [SIG Windows](https://qiita.com/ainoya/items/e6441d6d3e69cc8c71d2) @ainoya 
- SIG ClusterLifeCycle *Comming Soon* @yuanying
ElastiCacheのノード名にまつわる落とし穴

ElastiCache for Redisのprimaryノードのメンテナンス対応で経験した問題について書いていきます。


# あらすじ
ElastiCache for Redis(クラスタ有効、primary * 1, replica *1)のノードメンテナンス時のお知らせ
↓
primaryが対象だったため手動対応しよう
↓
multi-az無効にする
↓
replicaをprimaryに昇格
↓
元のprimaryと同名のノードを追加...出来ない...

よくあるprimaryノードがメンテナンス対象の場合の対応だと思いますが、ElastiCache for Redisのクラスター名の制限により元のprimaryと同名のノードが追加出来ない事象に遭遇しました。

# 詳細
## そもそもElastiCache for Redisのクラスター名の制限とは？
AWSのドキュメントには以下のように書かれています。

>1～20 文字の英数字またはハイフンを使用する必要があります。
>先頭は文字にする必要があります。
>連続する 2 つのハイフンを含めることはできません。
>末尾をハイフンすることはできません。
>
>https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/GettingStarted.CreateCluster.html


これはあくまでクラスター名の制限です。
ドキュメントに**クラスターの命名上の制約**とあります。
つまり、**qiita-elasticache-00**(20文字)のクラスターの作成は可能です。

その**qiita-elasticache-00**のクラスター名でreplica * 1としてクラスターを作成します。
※クラスター有効/無効はどちらでも構いません

すると作成されたprimayとreplicaのノード名は以下のようになります。
・primaryノード：**qiita-elasticache-00-001**(24文字)
・replicaノード：**qiita-elasticache-00-002**(24文字)

```
$ aws elasticache describe-cache-clusters --query 'CacheClusters[].CacheClusterId'
[
    "qiita-elasticache-00-001",
    "qiita-elasticache-00-002"
]
```

では、一度multi-azを無効化しreplicaノード(qiita-elasticache-00-002)を消して、再度同名(qiita-elasticache-00-002)のノードを追加出来るかやってみます！

すると以下のようなエラーが発生し、replicaノードを追加することが出来ません。

<img width="495" alt="スクリーンショット 2019-04-04 13.57.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/137707/e456fc98-2a7a-c06a-1c0d-8f3c9b6708a7.png">

コンソールからクラスターを作成した場合は20文字より多い文字数のノードが作成出来たにも関わらず
このようなエラーが発生します

これが私がハマった罠でした...

このあとAWSへのサポートへ問い合わせしましたが、残念ながらそういう仕様だそうです

# 結論
クラスター名は20文字まで可能ですが**-00X**がノードに付与されることを考慮して、16文字以下にしましょう
AWS EC2にnkfをインストールする 2019-04-04版



yumでinstallできないのでrpmからインストールします。

# バイナリのダウンロード

[https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/](https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/)から`nkf`のパッケージを探してダウンロードしてください。

2019-04-04時点だと、`nkf-2.1.3-5.el7.x86_64.rpm`があります。

URL [https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/nkf-2.1.3-5.el7.x86_64.rpm](https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/nkf-2.1.3-5.el7.x86_64.rpm)

```
$ wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/n/nkf-2.1.3-5.el7.x86_64.rpm
```

# インストール

以下のコマンドでインストールします。

```
$ sudo rpm -ivh nkf-2.1.3-5.el7.x86_64.rpm
```

# 改行コードの変換方法

dos -> unix は -Lu(unix)
unix -> dos は -Lw(win)
です。

```
$ nkf -Lu dos.txt > dos2unix.txt
$ nkf -Lw unix.txt > unix2dos.txt
```


---
※参考URL
[AWS EC2にnkfをインストールする](https://qiita.com/hidechae/items/1164bca2871c0bfde418)
[色々な改行コード変換の方法](https://qiita.com/dharry/items/b4eead2868dddf1499f0)
ありがとうございました。
【elasticsearch】【python】bulk APIで使うjsonをcsvから動的に生成する


##環境
elasticsearch6.6.0
python3.5.1

##今回やりたいこと

今回やりたいことは、bulkAPIで使うjsonファイルの生成をpythonでやる。
※bulkAPIとは、elasticsearchへのたくさんのデータ登録をjsonを使ってコマンド一つでやってしまうものである。

以下のようなcsvを、、、

```csv:name.csv
三木夏海,
川原香菜,
大宮梨子,
・・・
・・・
・・・
```

以下のように整形する。

```json:sample_bulk.json
{"index" : {}}
{"name":"三木夏海"}
{"index" : {}}
{"name":"川原香菜"}
{"index" : {}}
{"name":"大宮梨子"}
・・・
・・・
・・・
```

indexの名前やtype名はcurlコマンド内に記述する。
idを指定して振りたい場合は、pythonプログラム内に一工夫が必要。


##準備

- elasticsearchのsettingとmappingを登録。フィールドはnameのみ。
- サンプルデータを用意

以下のサイトから名前のサンプルデータをcsvで取得した。
https://hogehoge.tk/personal/generator/


##pythonファイル
作成したコードは以下のようになった。

```python:bulk.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
import json

def func():
    # csvから名前をdataframe型で取得。ヘッダーがない場合は、dropメソッドは使わなくて良い。
	name = pd.read_csv("name.csv", header=None).drop(0, axis=0)[0].values.tolist()

    # dict型でnameを定義
	data = {'name' : name}
    # データフレームに変換
	df = pd.DataFrame(data)

    # JSON形式の文字列（str型）に変換。
    # 引数force_ascii=FalseとするとUnicodeエスケープされない。
    # 引数orient='records'で、引数lines=Trueとすると{name:名前}ごとに改行された文字列になる。
	df_str = df.to_json(force_ascii=False, orient='records', lines=True)

    # リスト型に変換
	df_list = df_str.split('\n')

    # 一行毎に、{"index" : {}}を追加
	even_list = ['{"index" : {}}\n' + df_list[i] for i in range(len(df_list))]
	if even_list[-1] == '{"index" : {}}':
        # 最後の行には{"index" : {}}を追加しない
	    even_list.pop(-1)
	else:
        # 最後は改行で終わらせる
	    even_list.append("\n")

    # 文字列に変換
	mojiretsu = '\n'.join(even_list)

    # jsonファイルとして出力
	with open("sample_bulk.json", mode='w') as f:
	    f.write(mojiretsu)

# 関数実行
func()
```

ターミナルで実行したらsample_bulk.jsonが生成される。

##データインサート
sample_bulk.jsonが出来上がったら、データを登録してみる。
以下のようにcurlコマンドを実行。indexやtypeはここで指定する。

```shell
curl -H "Content-Type: application/json" -X POST http://localhost:9200/index名/type名/_bulk?pretty --data-binary @sample_bulk.json
```

以下でデータを確認

```shell

curl -H "Content-Type: application/json" -XGET 'localhost:9200/index名/type名/_search?pretty'
```

##参考
[pandas.DataFrameをJSON文字列・ファイルに変換・保存（to_json）](https://note.nkmk.me/python-pandas-to-json/)
numpyで値の範囲を指定した乱数行列の生成

例えば「-10.0 から 10.0 までの範囲の一様乱数で構成された 2×3の行列を生成する」といった処理をしたかったら、

```python
>>> 20 * np.random.random((2,3)) -10
array([[ 0.05083841,  5.67039253,  4.40987912],
       [-7.21727498,  3.29485038,  9.83926988]])
```
とする。  
最初の20は値の範囲(-10~+10だから20)で、最後の-10は値の最小値。

---
参考: https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.random.html#numpy.random.random
[Zabbix 4.0][Ubuntu 18.04] Zabbix環境構築手順

# TL;DR
以下の記事を参考にZabbix環境を構築しようとしたところ、
バージョンの違いによりコピペできなかった部分があったため、読み替えポイントをメモ。
[[Zabbix 3.2][Ubuntu 16.04] Zabbix環境構築手順まとめ](https://qiita.com/koara-local/items/26475b321030140d2048)

- [公式ドキュメント](https://www.zabbix.com/documentation/4.0/manual/installation/install_from_packages/debian_ubuntu)を読むのが面倒な人向け

# 元記事との環境比較

|  | Reference_env | my_env |
|:-:|:-:|:-:|
| OS | Ubuntu 16.04 LTS / 64bit  | Ubuntu 18.04 LTS / 64bit  |
| Zabbix  | 3.2 | 4.0 |
| PostgreSQL | 9.5 | 10.6 |

- 元記事の公開後にリリースされたUbuntu 18.04 LTSを採用
- [zabbix3系が既にサポート切れ](https://www.zabbix.com/jp/life_cycle_and_release_policy)のためzabbix 4.0 LTSを採用
- パッケージの依存関係によりPostgreSQL 9.5 -> 10.6

# 元記事から具体的に読み替えた箇所

## Zabbixのリポジトリの設定
- パッケージをwgetするリポジトリ先を変更

```text
$ wget http://repo.zabbix.com/zabbix/4.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_4.0-2+bionic_all.deb
```
※ Ubuntu 18.04のコードネームがBionic Beaver（ cf.https://ja.wikipedia.org/wiki/Ubuntu ）なので対応するファイルをリストから選択する。
### 参考画像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/279234/90e18ef1-9f83-079c-5605-8cb1c1facbb2.png)

## 依存パッケージのインストール
- PHP7.0系がapt-getできなかった（[既にサポート切れ](https://www.php.net/supported-versions.php)のためだと思われる）
ので7.2系に変更

```text
$ apt-get install php7.2-bcmath php7.2-xml php7.2-mbstring php7.2-pgsql
```


### 失敗例

```text
$ sudo apt-get install php7.0-bcmath php7.0-xml php7.0-mbstring php7.0-pgsql
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package php7.0-bcmath
E: Couldn't find any package by glob 'php7.0-bcmath'
E: Couldn't find any package by regex 'php7.0-bcmath'
E: Unable to locate package php7.0-xml
E: Couldn't find any package by glob 'php7.0-xml'
E: Couldn't find any package by regex 'php7.0-xml'
E: Unable to locate package php7.0-mbstring
E: Couldn't find any package by glob 'php7.0-mbstring'
E: Couldn't find any package by regex 'php7.0-mbstring'
E: Unable to locate package php7.0-pgsql
E: Couldn't find any package by glob 'php7.0-pgsql'
E: Couldn't find any package by regex 'php7.0-pgsql'
```
## zabbix 用のDBの作成
- PostgreSQLのインストール時は特に意識する必要は無いが、10系になったことで**pg_hba.conf**のパスが変わっており、設定時に元記事の例をコピペできないので注意

```text
$ sudo sed -i -e '/^local.*all.*all.*/s/peer/trust/' /etc/postgresql/10/main/pg_hba.conf
```

# 結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/279234/6b72dc34-49a4-8c7f-5fa7-4bff2b3b64cd.png)
＜中略＞
![image.png](https://qiita-image-store.s3.amazonaws.com/0/279234/6cacacac-d5c8-f177-356a-c6812050a1a7.png)


---------------------------------------

# Appendix.
## 作成したDBの初期化
- 元記事のコマンドをそのまま実行するとパーミッションエラーとなるので直前の設定に倣って次のように実行

```text
$ zcat /usr/share/doc/zabbix-server-pgsql/create.sql.gz | sudo -u postgres psql -U postgres zabbix
```
Laravel　よく使うコマンド

・コントローラー作成
` $ php artisan make:controller HelloController `

・コントローラー作成（CRUDつき）
` $ php artisan make:controller PhotoController --resource `

・マイグレーションファイル作成
` $ php artisan make:migration create_users_table `

・シーダー作成
` $ php artisan make:seeder BooksTableSeeder `

・シーダー実行
` $ php artisan db:seed `

・シーダー実行（特定のclassのみ）
` $ php artisan db:seed --class=PhotoTableSeeder `

・メールクラス作成
` $ php artisan make:mail OrderShipped `

・モデル作成
` $ php artisan make:model User `

・バリデーション（フォームリクエスト）作成
` $ php artisan make:request ValidateStoreBlogPost `
Invalid Option: corejs is not a valid top-level option が出る


circle ciで動かしているwebpackのbuildが落ちる

babelrcの `corejs` はトップレベルでは使えないオプションだ、みたいなことを言われる

```console
ERROR in ./src/index.jsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: [BABEL] /home/circleci/project/src/index.jsx: Invalid Option: corejs is not a valid top-level option.
        Maybe you meant to use 'targets'? 
```

babelは7を入れており、babelrcの設定はこんな感じだが、ローカルの開発環境でbuildしてもエラーは出ない。

```js
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [
            "last 2 versions",
            "ie >= 11"
          ]
        },
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ],
```

circle ciで実行していた `npm install` を `npm ci` に変更し、現在の `package.lock.json` を `.gitignore` から削除して再度circle ciを回したらビルドが通るようになった。
JQueryを使わないプレビュー表示できるイメージアップローダー修正版【複数対応】

以前投稿したやつの改訂版
https://qiita.com/ketabawo/items/1f40283e2d64c283d13b
上記コードは同一ページ内に複数のアップローダーがあると動かないという欠陥があり、業務中にその欠陥に遭遇したので改良したものを投稿しておきます。

rails simple_formを使ってます。

```haml
.imageUploader{onclick: "buttonClick('HUGAHUGA')"}
  .imageUploader__preview
    - if f.object.HOGEHOGE.present?
      = image_tag "#{f.object.HOGEHOGE.retina}"
      %p.change 画像を変更する
    - else
      %p.upload 画像を選ぶ
= f.input :HOGEHOGE, label: false, input_html: {onchange: 'imageUploader(event)'}

```

```javascript
function buttonClick(targetNode){
  document.getElementById(targetNode).click();
};
function imageUploader(e){
  var imageFile = e.target.files[0];
  var reader = new FileReader();
  var imageScreen = e.target.parentNode.previousElementSibling.querySelector('.imageUploader__preview');
  var imageTag = e.target.parentNode.previousElementSibling.querySelector('.imageUploader__preview img');
  if(imageTag != null){
    imageScreen.removeChild(imageTag);
  }
  reader.onload = function(){
    var img = document.createElement('img');
    img.setAttribute('src', reader.result);
    imageScreen.appendChild(img);
  };
  reader.readAsDataURL(imageFile);
};
```
画像タグをどこに出力させるかのアクセス先がおかしかったので、それぞれのinput type='file'の位置から辿って正しい場所を指定。
ご利用の際はHTML構成が異なるはずなので適宜変更してください。

```javascript
var imageScreen = e.target.parentNode.previousElementSibling.querySelector('.imageUploader__preview');
var imageTag = e.target.parentNode.previousElementSibling.querySelector('.imageUploader__preview img');
```

これでテストした限りだと正常に動作しているのでOKかとは思いますが、なにせ僕が書いたコードなのでアテになりませんｗｗｗ
concrete5インストール時のデータベースエラー

## エラー内容

concrete5を`./vendor/bin/concrete5 c5:install -i`でインストールする際の最後の確認ステップで、以下のような警告が表示されました。
データベースをアップグレードせよと言われているが、どうしたらいいんだ的な状況になり、解決に手間取りました。

```console
- Database should support the configured character set and collation...
The database does have a complete support for all the Unicode characters.
This implies, for example, that you may not be able to save emoticons
(it's the same behavior as concrete5 versions older than 8.5.0).
You should upgrade your database to fix this issue.
```

## 環境

* Amazon Lightsail
* Ubuntu 18.04.2 LTS
* concrete5 8.5.1
    * `composer create-project concrete5/composer` でインストール
* mariadb-server-10.1

## 発生条件

`create database`するときに、character setに`utf8mb4`を指定すると発生するようです。

```console
create database c5 character set utf8mb4 collate utf8mb4_unicode_ci;
```

## 対応

mysqldの設定で、長いカラム長のフィールドにインデックスを張れるようにします。
（設定を反映するにはmysqldの再起動が必要です）

```config:/etc/mysql/conf.d/mysqld.cnf
[mysqld]
innodb_default_row_format=dynamic
innodb_file_format=Barracuda
innodb_large_prefix=ON
```

## 参考

* https://github.com/concrete5/concrete5/issues/7360
* https://stackoverflow.com/questions/42043205/how-to-fix-mysql-index-column-size-too-large-laravel-migrate
* https://blog.kamipo.net/entry/2012/11/13/102024
セキュリティ② 応用情報技術者試験 対策日記@16

#情報セキュリティマネジメントシステム(ISMS)
ISMSの構築方法や要求事項などは**ISO27001**、ISMSの実践規範は**ISO27002**に示されている。
また、セキュリティ技術を評価する規格に**ISO15408**がある。CC(コモンクライテリア)とも呼ばれる。

ユーザ認証の方法には、**知識**(パスワードなど)、**所持**(ICカードや電話番号など)、**生体**(指紋など)の三種類があり、二種類以上を組み合わせることを多要素認証という。

脆弱性の深刻度を評価するための評価手法の一つに**CVSS(Common Vulnerability Scoring System)**がある。基本評価基準、現状評価基準、環境評価基準の三つの視点がある。

#典型的なサイバー攻撃
###バッファオーバーフロー攻撃
バッファの長さを超えるデータを送り込むことによって動作不能にし、プログラムを上書きする攻撃。対策としては入力文字列長をチェックする。

###SQLインジェクション
フォームなどにSQL文を入力することによって、データベースを不正に操作する攻撃。制御文字のエスケープ処理やプレースホルダを利用する**バインド機構**が有効。

###XSS(クロスサイトスクリプティング)
脆弱性のあるWebサイトを標的として、閲覧者に攻撃者が作成したマルウェアなどの実行ファイルをブラウザ上で実行させる攻撃のこと。例えば、標的サイトのアンケートフォームなどに、なんらかの方法によってJavaScriptなどのブラウザ上で動作するスクリプトを挿入しておく(これをスクリプトインジェクションという)。これを閲覧者が実行することによって、攻撃が成功する。インジェクションの方法としては、URLパラメータにあらかじめスクリプトを仕込んでおいて、そのURLを通して閲覧者を標的サイトに誘導するなどの方法がある。Hiddenタグを用いる手法もある。
対策方法としては組み込まれたJSを<script></script>の形でHTML内に表示させない様に、<>などの文字をエスケープする、属性に””を必ずつける様にするなど。

###CSRF(クロスサイトリクエストフォージェリ)
Webサイトにログイン中のユーザのスクリプトを操ることで、サーバ上に被害を起こす攻撃。

###DNSキャッシュポイズニング攻撃
DNSのキャッシュに不正な情報を注入することで、不正なサイトへのアクセスを誘導する攻撃。

###パスワードクラック
パスワードクラックの方法には、辞書に出てくる用語を使用する**辞書攻撃**、適当な文字列を組み合わせて力任せに攻撃を繰り返す**ブルートフォース攻撃**、他のサイトで取得したパスワードリストを利用する**パスワードリスト攻撃**などがある。

###ランサムウェア
コンピュータの機能を制限し、その制限を解除するための身代金を要求するマルウェア。

#セキュリティ実装技術
###セキュアOS
セキュリティを強化したオペレーティングシステムのことである。 厳密な定義は存在していないが、強制アクセス制御(MAC)機能及び、最小特権を実現する機能を備えたものをそう呼ぶことが一般的である。通常のOSは任意アクセス制御(DAC)である。

###ファイアーウォール
あらかじめ設定されたACL(アクセス可能リスト)に応じてパケットを中継したり破棄したりする。
IPアドレスとポート番号を基に制御する**パケットフィルタ型**と、アプリケーションプログラムごとに細かく設定できる**アプリケーションゲートウェイ型**がある。インターネットと内部ネットワークの間に**DMZ(非武装地帯)**を設けることがある。

###IDS/IPS
**IDS(Intrusion Detection System)**はネットワークやホストをリアルタイムで監視し、侵入や攻撃を検知するシステム。検知するだけでなく防御するシステムとして、**IPS(Intrusion Prevention System)**もある。

###認証プロトコル
**SPF(Sender Policy Framework)** 電子メールの認証技術の一つで、差出人のIPアドレスなどを基にメールのドメインの正当性を検証する。
**DKIM(Domain Keys Identified Mail)** 電子メールの認証技術の一つで、ディジタル署名を用いて送信者の正当性を立証する。

###その他用語
**テンペスト** 機器が発する微弱な電磁波を受信することで通信を傍受すること。
**ステガノグラフィ** 音声や画像などのデータに秘匿のメッセージを埋め込む技術。
**SMTP-AUTH** 送信メールサーバで、ユーザ名とパスワードなどを用いてユーザを認証する方法。

------
[ホームへ](https://qiita.com/k-y/items/dc2c9a3a8425712253e8)
herokuでApplication Errorになってしまった時の対処法

herokuにアプリをダウンロードしたものの、以下のように、Application Errorが出てしまうことがあると思います。
![Screenshot 2019-04-02 at 17.17.57.png](https://qiita-image-store.s3.amazonaws.com/0/305466/19532ee4-4d90-70b4-0abe-09fc80963d92.png)

こんな時、どうすればいいのか？
対処法を色々試してみたので、ここにまとめておきます。

# エラーコードを見てみる

まずは

```
heroku logs
```
でエラーコード見てみました。

```
2019-04-02T08:06:29.780173+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=arcane-plains-99735.herokuapp.com request_id=1e0af85d-7844-4e8b-8928-b928e60771ac fwd="126.234.120.249" dyno= connect= service= status=503 bytes= protocol=https
```

んーよくわからん。
どうすればいいの？って感じでした。

# herokuを再起動する

次に、https://qiita.com/Oakbow/items/1565922ddcdea0ce9ab5　
の記事で紹介されていたherokuの再起動コマンド

```
heroku restart --app application_name
```
や

```
heroku restart web.1 --app application_name
```
を試してみました。

でも、エラーが解消されません...。

# コンソールを開いてみる

最後に、

```
heroku run rails c
```
でコンソールを見てみると、

```
Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? sqlite3 is not part of the bundle. Add it to your Gemfile. (LoadError)
```
の文字が。
sqlite3周りのエラーですね、sqlite3はマジでやっかい。

# まとめ

```
heroku run rails c
```
が優秀！
Windowsスポットライトの画像を保存する

# 説明
- Windowsスポットライトの画像を保存するスクリプトです。
- スポットライトのディレクトリ内の100KB以上、横長の画像をPictureフォルダにコピーします。
- スポットライトのディレクトリ内は定期的に削除されているようなので、スタートアップ時の実行ディレクトリに入れておくと定期的にクロールして保存してくれると思います。
- また整理します。

# スクリプト

```bash:savephoto.bat
<# : Batch portion (PowerShell multi-line comment)
@echo off & setlocal

for %%F in ( %homedrive%%homepath%\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\* ) do (
    if %%~zF GEQ 100000 (
        call :isLandscape %%F && (
            echo copy_%%F_to_%homedrive%%homepath%\Pictures\%%~nF.jpg
            copy %%F %homedrive%%homepath%\Pictures\%%~nF.jpg
        )
    )
)

goto :EOF

:isLandscape <imgfile>
rem # function sets errorlevel 0 if landscape, 1 if portrait or square
setlocal disabledelayedexpansion
set "img=%~1"
powershell -noprofile -noninteractive "iex (${%~f0} | out-string)"
endlocal & exit /b %errorlevel%

: end batch / begin PowerShell hybrid code #>

add-type -Assembly System.Windows.Forms
$size = [Drawing.Image]::FromFile((gi $env:img)).Size
exit ($size.Width -le $size.Height) # 0 = false, 1 = true
```
ざっくりGraphQLをまとめてみた

# GraphQL とは

GraphQLとはAPI用のクエリ言語である。
フレームワークや特定の技術を指すのではなく、データに対するクエリ言語の仕様

Web版SQL = GraphQL

# RESTと何が違う？

## REST
RESTfulなAPIはURLとmethodでリソースを表現する

## GraphQL
単一エンドポイント。欲しいリソースをHTTP POSTのbodyに明示的に記載してリクエスト

![picture_pc_0c546509acf3af01052977d2d0ba7f83.jpg](https://qiita-image-store.s3.amazonaws.com/0/211318/8f3422b9-75be-475e-03ab-63de39b3cb04.jpeg)



# メリット

## 1. リソースをまとめることができる
RESTではURLがひとつのリソースを表すため、複数のリソースが必要な複雑な画面では複数回のAPIリクエストが必要になる。

結果的に、綺麗に設計されたRESTful APIほど複数回のリクエストが必要になり、パフォーマンスが落ちたりコードの複雑さが増す欠点があった。

GraphQLでは必要なリソースだけを明示的に記載してリクエストし、必要なリソースを無駄なく1発で取得可能。

## 2. 中間層としても活躍する
マイクロサービスのGateway（中間層）としても良筋と思われる。

スキーマを定義することでGraphQLに対応しているデータソースを取得することができる。
DBを直接取得することもできるし、既存のREST APIを内部的に叩いて取得させることもできる。

![picture_pc_d897f516730d1b98b75429336b88546f.jpg](https://qiita-image-store.s3.amazonaws.com/0/211318/8988b516-95b6-22f6-be6e-813d20a32e86.jpeg)


# REST APIと勝手が違うところ

## リソース制限の視点

APIに利用制限を設ける場合、RESTでは1時間にx回マデなどの回数ベースの制限を設ける例がよくあるが、

GraphQLは引っ張るリソース数(=負荷)はクライアントが任意に決められるため、負荷の計算方法を考える必要がある。

githubのGraphQL API v4は、なめるオブジェクトの数をscoreにし、それを1時間に超えない範囲でリクエスト可能にしている。

## キャッシュ効率

GraphQLは単一エンドポイントなので、HTTPのCache-ControllのようなURLベースのキャッシュ機構やCDNでのキャッシュはそのままでは使えない。

キャッシュが使えないわけではなくサーバー、CDN、クライアントの各層でキャッシングの現実的な実装は用意されているので
別途必要なものを実装しなければならない。

## エラーハンドリング

RESTではエラーはHTTPのステータスコードで表現される

GraphQLではリクエストが通れば200で返し、何かエラーが発生した時はエラーオブジェクトに表現される。


# まとめ

- 様々なデータソースを扱えるのでGood
- Web版SQLが発行できてイイネ！
- REST API開発でAPIが多すぎてメンテナンスがしんどいということはGraphQLではなくなりそう。
- リソース制限やキャッシュ効率、エラーハンドリングの仕方などREST APIとはまた異なるノウハウが必要

これからの主流になっていく(らしい)ので、頑張って習得したい。

# 参照URL
https://note.mu/konpyu/n/nc4fd122644a1
#GCP ( Google Cloud Platform ) を Centos に build する #docker image ( Dockerfile ) の例 

# ./Dockerfile

```
# https://cloud.google.com/sdk/docs/quickstart-redhat-centos

FROM centos

COPY . ./

# vim is just for only your interactive mode operation 
RUN yum install -y vim sudo && \
  cp ./google-cloud-sdk.repo /etc/yum.repos.d/ && \
  sudo yum install -y google-cloud-sdk

ENTRYPOINT /bin/bash
```

# ./google-cloud-sdk.repo

```
[google-cloud-sdk]
name=Google Cloud SDK
baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
```

# exe

```
docker build . -t your-gcp
```

```
docker run -it your-gcp
```

その後 gcloud init するなりして利用

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1064








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Dockerで<none>のイメージを削除する

## 不要なnoneのイメージを削除する

dockerで同じ名前のイメージを作り直した際に古いほうのイメージがnoneになってしまったので、そのnoneを削除する方法について

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
docker-whale        latest              03e697003e07        About a minute ago   278MB
<none>              <none>              021059f3393e        4 minutes ago        278MB
```

とりあえずIDがnoneのリポジトリを抽出

```
$ docker images -f dangling=true
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              021059f3393e        About an hour ago   278MB
```

以下のコマンドで<none>を削除しようとしてみたところ、

```
$ docker rmi $(docker images -f dangling=true -q)
Error response from daemon: conflict: unable to delete 021059f3393e (must be forced) - image is being used by stopped container 1ef4720be2f0
```

このようなメッセージが。
これを解決するためにfオプションをつけることによって強制削除！

```
$ docker rmi 021059f3393e -f
```

## 補足

```
$ docker rmi `docker images -aq`
```

こちらのコマンドで使用していないイメージの一括削除が可能
WindowsでBashコンテナを動かすためのバッチファイル

Bashを動かす環境をDockerコンテナで作って、Windows（Docker CE on Ubuntu on WSL2 or Docker Desktop）から簡単に利用できるようにするためのバッチファイル。

#### Dockerイメージのビルド（build_bash.bat）

```cmd
@echo off

cd /d %~dp0

# Docker Desktop環境ではwslは不要
wsl docker build ^
  -t bash ^
  .

echo Press any key to finish.
pause > NUL
```

#### Dockerコンテナ起動（run_bash.bat）

```cmd
@echo off

cd /d %~dp0

wsl docker stop bash > NUL 2>&1

wsl docker run ^
  -it ^
  --rm ^
  --name bash ^
  -v /c:/c ^
  bash

if %errorlevel% neq 0 pause
```

#### Dockerfile

```dockerfile
FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
    && apt-get install -y \
      locales \
      gettext-base \
      vim \
      python3 \
      python3-pip \
      curl \
    && locale-gen ja_JP.UTF-8 \
    && echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc

CMD ["bash"]
```
Azure Pipelines上でJestを非対話モードで実行する

# はじめに
Azure Pipelines上でJestを使ったCI環境を構築するときに `yarn test` でテストを実行してしまうと対話モードで起動してしまい、CIが止まってしまいます。

本稿では、非対話モードでJestを使ってCIを実行する方法を紹介します。

# 環境
- Azure Pipelines 
- `create-react-app`で作成したReactプロジェクト
- パッケージマネージャ
  - yarn

# `azure-pipelines.yml`の設定
- 非対話モードでJestを実行するためには環境変数 `CI=true` を設定する必要があります。

- 以下のファイルを作成して、Build Pipelineに設定します。

``` azure-pipelines.yml
variables:
  CI: true
jobs:
- job: Ubuntu
  pool:
    vmImage: 'ubuntu-16.04'
  strategy:
    matrix:
      node_10_x:
        node_version: 10.x
  steps:
  - script: |
      yarn
    displayName: 'node moduleをインストール'
  - script: |
      yarn test
    displayName: 'テスト'
  - script: |
      yarn build
    displayName: 'ビルド'
```
サブネットの自動割り当て IP 設定 - EC2 VPC

VPC の[サブネット]から[自動割り当てIP設定の変更]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/336c67d4-7855-260b-177f-f51a5148ff03.png)

[IPv4 の自動割り当て パブリック IPv4 アドレスの自動割り当てを有効にする]にチェックする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b05fc624-c212-ec73-5f23-f10450da5a86.png)

---

ここにチェックを入れないと、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b98e1564-38f8-0e34-32fb-e4cb6e6f023a.png)
にしても、IPv4 パブリック IPが以下のとおり割り当てられない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/6b844118-f749-3c9f-32ec-d720bb8bd8da.png)


---
チェックを入れ、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b98e1564-38f8-0e34-32fb-e4cb6e6f023a.png)
にすると、IPv4 パブリックが割り当てられる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/30e65d13-2a46-4e6c-e670-009a962b8790.png)
Javaでかな大文字⇔小文字変換、濁点・半濁点削除

```java
import java.util.HashMap;
import java.util.Map;

public class KanaUtil {
    private static final Map<Character, Character> lower2upperMap = new HashMap<>();
    private static final Map<Character, Character> upper2lowerMap = new HashMap<>();

    private static final String LOWER_CHARS = "ぁぃぅぇぉゃゅょっァィゥェォャュョッｧｨｩｪｫｬｭｮｯ";
    private static final String UPPER_CHARS = "あいうえおやゆよつアイウエオヤユヨツｱｲｳｴｵﾔﾕﾖﾂ";
    static {
        char[] lowerChars = LOWER_CHARS.toCharArray();
        char[] upperChars = UPPER_CHARS.toCharArray();
        if (lowerChars.length != upperChars.length) {
            throw new RuntimeException("char count not match. lower=" + lowerChars.length + ", upper=" + upperChars.length);
        }
        for (int i = 0; i < lowerChars.length; i++) {
            lower2upperMap.put(lowerChars[i], upperChars[i]);
            upper2lowerMap.put(upperChars[i], lowerChars[i]);
        }
    }

    public static String toUpperCase(String s) {
        return conv(s, lower2upperMap);
    }

    public static String toLowerCase(String s) {
        return conv(s, upper2lowerMap);
    }

    private static String conv(String s, Map<Character, Character> convMap) {
        StringBuilder sb = new StringBuilder();
        s.chars().mapToObj(c -> (char) c).forEach(c -> {
            Character conv = convMap.get(c);
            if (conv == null) {
                sb.append(c);
            } else {
                sb.append(conv);
            }
        });
        return sb.toString();
    }

    private static final Map<Character, Character> zenDaku2ZenNotDakuMap = new HashMap<>();

    private static final String ZEN_DAKU_CHARS = "ゔがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ";
    private static final String ZEN_NOT_DAKU_CHARS = "うかきくけこさしすせそたちつてとはひふへほはひふへほウカキクケコサシスセソタチツテトハヒフヘホハヒフヘホ";
    static {
        char[] zenDakuChars = ZEN_DAKU_CHARS.toCharArray();
        char[] zenNotDakuChars = ZEN_NOT_DAKU_CHARS.toCharArray();
        if (zenDakuChars.length != zenNotDakuChars.length) {
            throw new RuntimeException("char count not match. zenDaku=" + zenDakuChars.length + ", zenNotDaku=" + zenNotDakuChars.length);
        }
        for (int i = 0; i < zenDakuChars.length; i++) {
            zenDaku2ZenNotDakuMap.put(zenDakuChars[i], zenNotDakuChars[i]);
        }
    }

    public static String removeDakuten(String s) {
        StringBuilder sb = new StringBuilder();
        s.chars().mapToObj(c -> (char) c).forEach(c -> {
            if (c == '゛' || c == '゜' || c == 'ﾞ' || c == 'ﾟ') {
                // スキップ(削除)
            } else {
                Character conv = zenDaku2ZenNotDakuMap.get(c);
                if (conv == null) {
                    sb.append(c);
                } else {
                    sb.append(conv);
                }
            }
        });
        return sb.toString();
    }
}
```
Ruby の配列を+-|&演算子で遊ぶ

Ruby を使ったことない人(C が主)が、配列操作に | 演算子を用いている Ruby のコードを見て「……なにしてんの？？？」と疑問にもち遊んでみたことのまとめです。

# 準備

```rb
array1 = [1, 2, 3]
array2 = ["a", "b", "c"]
num = 255
```

# +演算子で配列の連結

単純に配列同士を連結するには + 演算子が使える

```rb
array3 = [111, 111, 111] + array1 + [11, 22, 33] + array2
p array3
```

```:出力結果
[111, 111, 111, 1, 2, 3, 11, 22, 33, "a", "b", "c"]
```

# | 演算子で配列の連結？

 | (or)演算子でも配列が連結できる…？

```rb
array1 |= array2 
p array1
```
```:出力結果
[1, 2, 3, "a", "b", "c"]
```

# | 演算子で要素の追加？

 | 演算子で要素が追加できる…？

```rb
array1 |= [num]
p array1
```
```:出力結果
[1, 2, 3, "a", "b", "c", 255]
```

# | 演算子で要素の追加！

そんでもってさらに | 演算子で要素が…… 追加できてないね！？

```rb
array1 |= [num]
p array1
```
```:出力結果
[1, 2, 3, "a", "b", "c", 255]
```

# +演算子で要素の追加

+演算子だと追加できる……ということは、 | 演算子はあくまで |(or) なのか。

```rb
array1 += [num]
p array1
```
```:出力結果
[1, 2, 3, "a", "b", "c", 255, 255]
```

# 重複する要素がある配列同士と | 演算子

| 演算子だと array3 の要素の中で、array1 に含まれるものが前方にきて、array1 にないものが後ろに追加される。
そして重複する要素 [111, 111, 111] や [255, 255] はユニークになるのか。
要素の重複をなくしたいときに便利そうだな。

```rb
array1 |= array3
p array1
```
```:出力結果
[1, 2, 3, "a", "b", "c", 255, 111, 11, 22, 33]
```

というか要素の追加時に

```rb
array |= [elem]
```

としていけば、そもそも要素の重複がなくなっていって一石二鳥だね♪というコードだったのか、あれは！
(ここがまとめでもいいくらいの気づき……)

# お試し(1): 要素の移動？

ということは……？

```rb
array1 = [num] | array1
p array1
```
```:出力結果
[255, 1, 2, 3, "a", "b", "c", 111, 11, 22, 33]
```

……やっぱり先頭にきた！(予想が当たって嬉しい)

# | 演算子による配列操作のまとめ

- 新しく追加しようとした要素に対し配列の中に重複する要素がなければ追加する
- 新しく追加しようとした要素に対し配列の中に重複する要素があれば追加しない
- すでに配列の中に重複する要素がある場合重複が解消される

# お試し(2): じゃあ & 演算子は？

↑の結果を踏まえるとそりゃそうか、という感じ。
配列同士で重複する値を取り出したいときとかにいいな。

```rb
array1 = [1, 2, 3]
array2 = ["a", "b", "c"]
num = 255
array3 = [111, 111, 111] + array1 + [11, 22, 33] + array2
```

```rb
p array1 & array2
p array3 & array1
p array3 & array2
```

```:出力結果
[]
[1, 2, 3]
["a", "b", "c"]
```

```rb
p array1 & [num] 
array1 += [num] 
p array1
p array1 & [num] 
```

```:出力結果
[]
[1, 2, 3, 255]
[255]
```

# お試し(3): じゃあじゃあ -演算子は？？

```rb
array1 = [1, 2, 3, 2, 1]
array2 = ["a", "b", "c"]
array2_1 = ["a", "b", "c", 1]
array3 = [111, 111, 111] + array1 + [11, 22, 33] + array2
```

```rb
p array3 - array1
p array3 - array2
p array1 - array2
p array1 - array2_1
```

```:出力結果
[111, 111, 111, 11, 22, 33, "a", "b", "c"]  # array3 から array1 が引かれる。
[111, 111, 111, 1, 2, 3, 2, 1, 11, 22, 33]  # array3 から array2 が引かれる。
[1, 2, 3, 2, 1]                             # array1 と array2 には重複する要素がないので
                                            # 何も引かれない。
[2, 3, 2]                                   # array1 と array2_1 の重複する要素[1]だけが
                                            # array1 から引かれる。
```

1行目、便利！直感的に分かる。便利！
2行目、同上
3行目、array1 だけ残るんだー
4行目、3行目を受けて分からんでもないが「気のまわりすぎる子なのでは？」と思う

気のまわりすぎる子の再確認。

```rb
array4 = ["うまい！", "ラーメンショップ", "うまい！"]
p array4
p array4 - ["うまい！"]
p array4 - ["ラーメンショップ"]
```

```:出力結果
["うまい！", "ラーメンショップ", "うまい！"]
["ラーメンショップ"]
["うまい！", "うまい！"]
```

まあこれは一つ前の 1, 2行目同様、直感的にわかりやすいか。
でもこんな便利な世界に住んでないからびっくりして二度見しちゃった、みたいな感じ。
Python3 エンジニア認定基礎試験 受験記2019/03

Python3 エンジニア認定基礎試験を受験してきたので受験を検討している方のために私の受験記を残しておきます。

# 結論
合格。
試験の難易度は低なので、会社から受験料や報奨金、および、評価に繋がるのであれば簡単なのでオススメ。
また、プログラミング初学者、および、Python3初学者の方の最初の一歩としては良い選択だと思います。

上記にあてはまらない方は、正直無駄です。
違う勉強をしましょう！！！


# 筆者の経歴
SE歴：10年以上のオッサン！
Python経験：無
他言語経験：C、C++、Java、Ruby・・・etc

# 試験について
試験時間：1時間
問題数：40問（1000点満点）
合格ライン：70%以上（28問以上）
⇒12問も間違えられる！やったね！
受験料：10,800円

しかし、この難易度で10,800円って。。。ボッタクリだろ！
ほんとに資格ビジネスというのは甘い汁が吸えますね！！！

# 申し込み方法
https://cbt.odyssey-com.co.jp/pythonic-exam.html
⇒受験の流れをみてね！

# 学習方法
・試験範囲となる以下のチュートリアルを実際に手を動かしつつ1周。
https://docs.python.org/ja/3/tutorial/
⇒ただし、プログラミング初学者がこれを読むのは心が折れると思う。わかりづらい。


・Udemyで以下の講座を購入し、入門編まで実施。
<https://www.udemy.com/python-beginner/>
⇒大変わかりやすく、動画で学べるのでオススメ。
定価は高いのでSALE中に買うべし。（しょっちゅうSALEしてます。）
チュートリアルで心が折れた方はこれで勉強すると良い。

・模擬試験を10周。
https://diver.diveintocode.jp/exam
⇒ここで模擬試験を受験できるので10周ぐらいしました。
1000点満点採れるようになり、理解できるようになれば、合格確率99%でしょう！
※保証は致しません。

# 試験難易度
難易度：低
⇒模擬試験を多少難しくした感じ。(2019/3月時点)
それでも模擬試験で1000点満点採れるようになり、理解できていれば無問題。


# 試験当日
・身分証明書は持ったか？
・OdysseyのIDとパスワードはメモったか？（CBT方式でログイン時に必要。）
・受験票は持ったか？（私が受験したテストセンターでは不要でした）

問題なければ、テストセンターへレッツゴー！

試験自体は見直し含めても30分もあれば終わります。
落ち着いて受験すれば問題ないです。頑張ってください。


以上です。
DirectX11のテクスチャをコンピュートシェーダーで書くときの覚え書き

メモ書きです。清書してなくてすみません。
>テクスチャを作成するとき、 DXGI_FORMAT_R32G32B32A32_FLOAT で作成すれば、コンピュートシェーダー、シェーダーリソースビュー、 アンオーダードアクセスビューへのアクセスは全て上手く行くが、 テクスチャの容量が大きくなりすぎる。
>
>一般的には、DXGI_FORMAT_R8G8B8A8_UNORM で作成するのが 望ましいと思われる。コンピュートシェーダーには、 RGBAで32bitで渡せるのが望ましい。
>
>そのためには、下記のフォーマットで組み合わせて作成する必要があった。
>
>テクスチャ：DXGI_FORMAT_R8G8B8A8_UNKNOWN シェーダーリーソースビュー：DXGI_FORMAT_R8G8B8A8_UNORM アンオーダードアクセスビュー：DXGI_FORMAT_R32_UINT
AWS Certificate ManagerにGlobalSignクイック認証SSLの証明書をインポートする

# はじめに

CloudFrontで外部証明書を使う要件があり、
GlobalSignのクイック認証SSLで証明書を発行し、
AWS Certificate Manager（以下ACM）にインポートしました。

クイック認証SSL
<https://jp.globalsign.com/service/ssl/quickssl.html>

GlobalSignの証明書はCloudFrontに対応
<https://jp.globalsign.com/info/news_press/2013/07/463.html>

CSR作成から証明書インポートするまでのメモを公開します。
2019年1月時点の情報となります。

# 証明書の発行依頼

CSR と秘密鍵のペアを作成し、証明書の発行を依頼します。

```sh
% openssl genrsa -des3 -out private.key 2048
% openssl req -new -key private.key -out cloudfront.csr
Enter pass phrase for private.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter /your/path/cloudfront.csr is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:JP
State or Province Name (full name) []:xxxxx
Locality Name (eg, city) []:xxxxx
Organization Name (eg, company) []:xxxxx
Organizational Unit Name (eg, section) []:xxxxx
Common Name (eg, fully qualified host name) []:*.example.com
Email Address []:postmaster@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
```

# 証明書発行

クリック認証SSLに申し込みを行います。
申込時に作成したCSRが必要になります。
審査などクリアすると、発行された証明書がメールで届きます。

# インポートの準備

証明書チェーンを作成し、さらにAWSにインポート可能な形式へ証明書を変換します。

1. メール本文中の証明書本体を`domain.crt`として保存します。

1. メール本文中の中間証明書を`intermediate.cer`として保存します。

1. <https://jp.globalsign.com/repository/>からルート証明書（`rootcacert_r1.cer`）をダウンロードします。

1. 中間証明書とルート証明書を結合し`chain.cer`を作成します。

    ```sh
    cat intermediate.cer rootcacert_r1.cer > chain.cer
    ```

1. `domain.crt`と`chain.cer`を pem 形式に変換します。

    ```sh
    openssl x509 -in ./domain.crt -outform pem -out ./domain.pem
    openssl x509 -in ./chain.cer -outform pem -out ./chain.pem
    ```

1. 秘密鍵のパスフレーズを外し、pem 形式にします。

    ```sh
    openssl rsa -in ./private.key -outform PEM -out private.key.pem
    # パスフレーズの入力が必要
    ```

# 証明書のインポート

1. AWS Console で`us-east-1`リージョンを選択し、「AWS Certificate Manager」から「証明書のインポート」をクリックします。

1. PEM 形式の証明書（`domain.pem`）、秘密鍵（`private.key.pem`）、証明書チェーン（`chain.pem`）を入力します。

1. インポートします。

# 補足

この手順で発行する証明書はSNI対応しているものになります。
<https://aws.amazon.com/jp/cloudfront/custom-ssl-domains/>

CSRの作成方法は以下にまとめられていますが、２０１９年4月時点でAWS向けの手順はまとめられていません。
<https://jp.globalsign.com/support/ssl/?cat=csr>
DirectX11バッドノウハウ 頂点バッファとインデックスバッファ

DirectX11で地雷を踏みまくったので、自ら踏んだ地雷をここに貼っていきます。

```C++
	ID3D11Buffer*           m_pVertexBuffer;
	ID3D11Buffer*           m_pIndexBuffer;

    //
    D3D11_MAPPED_SUBRESOURCE msr = {};
	HRESULT hr;

	// vertices upload
	hr = m_context->Map(m_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr);

	if (FAILED(hr))
		return;

	memcpy_s(msr.pData, sizeof(vtx_buf), vtx_buf, msr.RowPitch); // 頂点コピー msr.RowPitchで全体を書き換えないとまれに落ちる
	m_context->Unmap(m_pVertexBuffer, 0);

	// indices upload
	D3D11_MAPPED_SUBRESOURCE ires = {};
	hr = m_context->Map(m_pIndexBuffer 0, D3D11_MAP_WRITE_DISCARD, 0, &ires);
	if (FAILED(hr))
		return;

	void* idxbuf = ires.pData;
	if (idxbuf) {
//		memcpy(idxbuf, idc_buf, sizeof(uint32_t) * m_idc_cnt);			// 書き換えたインデックス数のコピーだとまれに落ちる
		memcpy_s(idxbuf, sizeof(idc_buf), idc_buf, ires.RowPitch);      // msr.RowPitchで全体を書き換えないと落ちる
		m_context->Unmap(m_pIndexBuffer, 0);
	}
```
VertexBufferとかIndexBufferをメインメモリからGPUメモリに転送するとき、何故かmemcpy関数の中で落ちるという、不可解な現象が起きました。 最初は書き換えたサイズだけ転送していたのですが、どうやらそれが原因だったみたい。

```C++
// indices upload
    D3D11_MAPPED_SUBRESOURCE ires = {};
    hr = m_context->Map(m_pIndexBuffer 0, D3D11_MAP_WRITE_DISCARD, 0, &ires);
    if (FAILED(hr))
        return;

    void* idxbuf = ires.pData;
    if (idxbuf) {
//      memcpy(idxbuf, idc_buf, sizeof(uint32_t) * m_idc_cnt);          // 書き換えたインデックス数のコピーだとまれに落ちる
        memcpy_s(idxbuf, sizeof(idc_buf), idc_buf, ires.RowPitch);      // msr.RowPitchで全体を書き換えないと落ちる
        m_context->Unmap(m_pIndexBuffer, 0);
    }
```
MapしたときのRowPitchのサイズでmemcpyしないと、何故かたまに落ちます。 理由はわかりませんが、これで動いているのでまぁよしとしましょう。
【JS初心者向け】スムーススクロールJSを分解して説明

今回JQuery初心者の社員のためのJQuery講座ということで社内共有したものです。
いまだにJQueryかよと思う方いらっしゃるかと思いますが、運用している案件ほぼほぼJQueryのためお許しください（；＿；）


```.js

$('a[href^="#"]').on('click', function () {
var speed = 500;
var href = $(this).attr('href');
var target = $(href == '#' || href == "" ? 'html' : href);
var position = target.offset().top;

$('body,html').animate({
scrollTop: position
}, speed, 'swing');
return false;
});
```


よくあるコードです。

普段頻繁に使っているが、コードの意味を理解している人は少ないと思うので分解して説明します。



##$('a[href^="#"]')
「^=」はビット排他的論理和演算子。

JQueryの構文の１つ　$('[ 属性 ^= "値" ]')

指定した"値"が属性の値と前方一致する要素を選択する

つまり上記のコードの場合

aタグのhref属性の内容の前方に#が付いている要素を取得する。





##var speed = 500;
speedに500を代入。

変数に入れた方がのちのち管理しやすいので推薦されている。



##var href = $(this).attr('href');
$('a[href^="#"]')　で取得した内容の属性の中身を取得
```<a href="#section1">なら「#section1」）してhrefに代入```



##var target = $(href == '#' || href == "" ? 'html' : href);
まず**「||」は論理演算子**。
意味はor。左辺及び右辺のどちらか1つでもtrueだった場合に全体の式がtrueになる。

**「?」は三項演算子**。
if文のショートカットとしてよく用いられる。

(例)

```.js
var number = 10
console.log((number > 11) ? 'big' : 'small' );
```

結果：falseがかえるのでsmallが出力

つまり、var target = $(href == '#' || href == "" ? 'html' : href);は下記と同じ意味を持つ

```.js
if(href == "#" || href == ""){
var target = $('html');
}else{
var target = $(href);
}
```
そのことからhrefが#の時と空の時は$('html')が、それ以外は$(href)がtargetに代入される。



##var position = target.offset().top;
offset().top;はドキュメントの左上の起点から、要素の左上までの距離（数値）を取得し、positionに代入。

あくまでpositionにはいるのは数値。



$('body,html').animate({scrollTop: position}, speed, 'swing');
先に変数に代入してきた値をここで使う。

animate関数は下記の意味

.animate({変化させるCSSのキーと値のマップ値} ,[ スピード] ,[ イージングの種類] ),[アニメーションが完了した時に実行したい処理] )

参考:http://js.studio-kingdom.com/jquery/effects/animate



##return false;
処理を中断。

この関数の場合は大丈夫だが、リンク先に飛ばされる可能性を防ぐために書いている。



##まとめ
aタグのhref属性の内容の前方に#が付いている要素を取得し、それをクリックした時、
ドキュメントの上から、position分、speedの速さで、イージングの'swing'を使用してスクロールさせるクリックイベント。
コピペでもしっかり意味を理解して使いましょう。
Win32用見えないウィンドウ＆メッセージループ

###Win32でマルチスレッドにする時にメッセージループが挟まってると管理が便利かなと思って作ってみました。
[[GitHub] Invisible Window for Windows 10](https://github.com/marukun700/invisiblewinow)

```C++
#include	<windows.h>

const char *strClassName = "UnvisibleWindowClass";
const char *strTitle= " UnvisibleWindow";

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}

//
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// ウィンドウクラスの登録
	WNDCLASSEX wcex = { };
	wcex.cbSize			= sizeof(WNDCLASSEX);
	wcex.style			= WS_EX_NOACTIVATE;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon = nullptr;
	wcex.hCursor = nullptr;
	wcex.hbrBackground = nullptr;
	wcex.lpszMenuName	= nullptr;
	wcex.lpszClassName	= strClassName;
	wcex.hIconSm		= nullptr;

	if(!RegisterClassEx(&wcex)) return 0;

	// ウィンドウ作成
	HWND hwnd;
	hwnd = CreateWindowEx(WS_EX_NOACTIVATE, strClassName , strTitle, WS_DISABLED /*WS_OVERLAPPEDWINDOW*/,
			0, 0, 1, 1,
			nullptr, nullptr, hInstance, nullptr);
	if (!hwnd) return 0;

	ShowWindow(hwnd, SW_HIDE); // Window非表示

	// メッセージループ
	MSG msg = { };

	while (WM_QUIT != msg.message)
	{
		if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			// ここにメインタスクの処理を書く
			// 更新時間を計ったりする
			Sleep(1);		// dummy
		}
	}

	return msg.wParam;
}
```
docker-composeで使用するyamlファイルを指定する

# 環境ごとの差異を吸収したい
`docker-compose` コマンドはデフォルトでは`docker-compose.yaml`ファイルが使用されるようになっているが、ローカル環境とCI環境でコンテナを分けたいときなどは、使用したいyamlファイルも異なってくる。
そういったケースのために、使用するyamlファイルを指定するオプションもきちんと用意されている。

## コマンドの使用方法
### コンテナ起動
```
$ docker-compose -f [指定したいファイル名] up
```
#### ex
```
$ docker-compose -f docker-compose-ci.yaml up
```

### コンテナビルド
```
$ docker-compose -f [指定したいファイル名] build
```
### ex
```
$ docker-compose -f docker-compose-ci.yaml build
```
Googleの検索結果にサムネイル画像を表示する方法

##前提条件
 - スマートフォンでの検索結果です
 - 2019/4/3時点の内容です

##サムネイル画像で頭に叩き込んでおくこと
 - **Yahoo!検索にも反映される（時間差あり）**
 - **カスタム検索の[サムネイル画像](https://support.google.com/customsearch/answer/1626955?hl=ja)ではない**
 - **リッチリザルトの[カルーセル](https://developers.google.com/search/docs/guides/mark-up-listings?hl=ja)ではない**
 - **検索キーワードによって表示/非表示が変わる**
 - サムネイル画像に使われる画像は指定できない（誘導程度なら可能）
 - サイトに共通のロゴやバナーは表示されない

##検索キーワードと表示/非表示の傾向
 - 例として「賃貸」は出ないが、「マンション」は出る
 - また、「賃貸 マンション」だと出ないが、「高級 マンション」は出る
 - 物理的な存在と形容詞の組み合わせなら出やすい
 - 動詞や動名詞的な使われ方をするキーワードがあると出にくい

##サムネイル対策と結果

|施策|内容|結果|
|---|---|---|---|
|画像サイズ|画像サイズを大きくする|効果なし（他ではあるかもしれない）|
|Pagemap|構造化データを追加する|効果なし|
|OGPタグ|og:imageに画像ファイルのURLを指定する|効果なし|
|画像サイトマップ|サイトマップに画像情報を追加する|効果なし|
|altタグ|画像にaltタグを追加する|**効果あり**|
|titleタグ|画像からのリンクにtitleタグを追加する|非実施|
|ファイル名|画像URLにキーワードを追加する|非実施|
|meta thumnail|metaタグを追加する|非実施|
|周辺テキスト|画像周辺にテキストを追加する|非実施|
|メイン画像|H1タグの近くにキーワードに最適なメイン画像を追加する|非実施|

※ページ内の画像のサイズが200pxでも出るときは出る
※altタグがなくても出るときは出る
※メイン画像は「画像検索」をした場合に上位に表示されるようなもの（テキストと画像の中身がマッチするもの）を使う
※サムネイル画像は正方形にトリミングされるため、元画像の比率には注意が必要
※PCとモバイルでHTMLが異なる場合、お互いに影響を与える可能性がある（リスクを避けるために同じにしておいた方がよい）

##まとめ
自分の場合は画像にaltタグを追加した段階で表示させることができたが、サムネイル画像を制御したい場合はaltタグを設定したユニークなメイン画像をページ内に設定する方が確実性が高いと思われる。
（逆にその他の重要度が低い画像に関してはaltタグを外すなど）

##仮説
Googleは画像検索において「画像がページの中心であり、ページの上に画像があるサイトに優先順位を付ける」という考えを持っていることから推察すると、画像をコンテンツの中心に持つページと認識されておかないとサムネイル画像が表示されないのではないか。

https://www.blog.google/products/search/making-visual-content-more-useful-search/

>We now prioritize sites where the image is central to the page, and higher up on the page.

##その他
カスタム検索のサムネイル画像と検索結果のサムネイル画像を混同している会社やサイトが数多く見受けられる。カスタム検索を知らない人々が悪意なくGoogleのヘルプだけを見て記事を書いているのかもしれない。
SimpleSAMLphpのデータソースにMySQLを指定する

# 概要
開発環境にSAML2.0方式によるシングルサインオンを構築するにあたり（IDプロバイダー用途で）[SimpleSAMLphp](https://simplesamlphp.org/) を使う場合のユーザー認証データソースとして、MySQLなどのRDBMSを指定する方法を調べてみました。

※ちなみにデフォルトのデータソースは、config/authsources.php の'example-userpass'の部分で、PHP連想配列で「ユーザ名:パスワード」を定義するぽいです。

##### SimpleSAMLphpのバージョン
```
$ grep 'function getVersion' -i -A3 lib/SimpleSAML/Configuration.php
    public function getVersion()
    {
        return '1.17.1';
    }
```


# 対応手順

### 1. sqlauthモジュールを有効化する。

```config/config.php
'module.enable' => [
    'sqlauth' => true,
],
```

### 2. データベース接続情報を設定する。

※自分の環境に合わせて、'dsn' や 'query' なども変更する。

```config/authsources.php
    'example-sql' => [
        'sqlauth:SQL',
        'dsn' => 'mysql:host=sql.example.org;port=3306;charset=utf8;dbname=simplesaml',
        'username' => 'simplesaml',
        'password' => 'secretpassword',
        'query' => 'SELECT uid, givenName, email, eduPersonPrincipalName FROM users WHERE uid = :username AND password = SHA2(CONCAT((SELECT salt FROM users WHERE uid = :username), :password), 256);',
    ],
```

### 3. IdPが参照する認証データソースを変更する

```metadata/saml20-idp-hosted.php
//    'auth' => 'example-userpass',
    'auth' => 'example-sql',
```

### そのた

※ちなみに最初の手順1で 'sqlauth' => true を設定し忘れると、下記エラーが発生するぽい。

```
SimpleSAML\Error\Error: UNHANDLEDEXCEPTION

Backtrace:
1 www/_include.php:17 (SimpleSAML_exception_handler)
0 [builtin] (N/A)
Caused by: Exception: Could not resolve 'sqlauth:SQL': no class named 'SimpleSAML\Module\sqlauth\Auth\Source\SQL' or 'sspmod_sqlauth_Auth_Source_SQL'.
Backtrace:
6 lib/SimpleSAML/Module.php:404 (SimpleSAML\Module::resolveClass)
5 lib/SimpleSAML/Auth/Source.php:318 (SimpleSAML\Auth\Source::parseAuthSource)
4 lib/SimpleSAML/Auth/Source.php:363 (SimpleSAML\Auth\Source::getById)
3 lib/SimpleSAML/Auth/Simple.php:216 (SimpleSAML\Auth\Simple::logout)
2 modules/core/www/authenticate.php:17 (require)
1 lib/SimpleSAML/Module.php:236 (SimpleSAML\Module::process)
0 www/module.php:9 (N/A)
```

# 参考
SimpleSAMLphpのインストール自体は下記ページを参考にしました。

- [SimpleSAMLphp で開発用の SAML ID Provider を立てる](https://suer.hatenablog.com/entry/2015/11/20/141941)
ChainerとOptunaで画像のよいAugmentationを探索してみた

# 要約
- random {vertical, holizontal} flip を使うべきかをOptunaで探索してみた
- 3層MLP+MNISTの場合、共に不要という直感にあう結果になった
- サンプルコードは[github](https://github.com/adusa1019/optuna_autoaugment/blob/master/minimum_autoaugment.py)にて公開した

# モチベーション
[Optuna](https://github.com/pfnet/optuna)を使って**何か作ってみたかった**。


大体以上ですべてなのですが少しだけ補足します。
Optunaの[MLPの層数を探索するサンプル](https://github.com/pfnet/optuna/blob/master/examples/chainer_simple.py)を眺めていた時に、[AutoAugment](https://arxiv.org/abs/1805.09501)のことを思い出しました。(AutoAugmentの解説は[こちら](https://www.slideshare.net/harmonylab/autoaugmentlearning-augmentation-policies-from-data)が簡潔でわかりやすかったです。)
Optuna公開からしばらくたちましたが画像認識の前処理探索に使った話をきかない(Qiitaにはなさそう)ので自分で作ってみました。

# 実行と結果
サンプルを実行すると最終的に以下のような結果がでてきます。

```
$ python minimum_autoaugment.py
(途中の出力を省略)
$ python FrozenTrial(trial_id=4, state=<TrialState.COMPLETE: 1>, 
value=0.02066851265822789, datetime_start=datetime.datetime(2019, 3, 20, 9, 
54, 27, 523348), datetime_complete=datetime.datetime(2019, 3, 20, 9, 56, 6, 
612511), params={'vertical flip': False, 'horizontal flip': False}, 
user_attrs={'main/loss': 0.03885125317600872, 'main/accuracy': 
0.9896055437100213, 'validation/main/loss': 0.06722574303799038, 
'validation/main/accuracy': 0.9793314873417721, 'epoch': 10, 'iteration': 
4688, 'elapsed_time': 98.81312308297493}, system_attrs={}, 
intermediate_values={}, params_in_internal_repr={'vertical flip': 1, 
'horizontal flip': 1})
```
`params` は一番良かったときのパラメータ、`user_attrs`は一番良かった時のログレポートです。

# 作成したもの
[github](https://github.com/adusa1019/optuna_autoaugment/blob/master/minimum_autoaugment.py)にて公開しています。
~~私が実装をさぼった~~コンセプト確認のためのプロトタイプですので、以下の点は要改善かなと思っています。~~この記事がうけたらやります。~~

- GPUを使っていない
- MNISTを使うようハードコードしてある
- MLPを使うようにハードコートしてある
- 探索できるaugmentationが少ない

# まとめ
画像認識における前処理方法をOptunaで探索するサンプルアプリを作成しました。
random flipの要否を3層MLP+MNISTの場合で検証し、不要という直感にあう結果が得られました。
サンプルコードは[github](https://github.com/adusa1019/optuna_autoaugment/blob/master/minimum_autoaugment.py)にて公開しています。