それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

phpで改行が反映されない件(終了タグと改行コードの関係)

php で改行コードが反映されないことがあります。

LFでもCRLFでも関係なく、文字コードも関係ありません。php では終了タグで「改行」すると、出力には改行が反映されません。

<?php 

$title = 'コーチングのプロが教える 「ほめる」技術';
$author = '鈴木 義幸';
?>

著者:<?= $title?>
書題:<?= $author?>

実行結果

$ php sample.php

著者:コーチングのプロが教える 「ほめる」技術書題:鈴木 義幸

不思議ですね。

次のように、単位が入るとさらに表示が想像がつかなくなります。

<?php 

$title = 'コーチングのプロが教える 「ほめる」技術';
$author = '鈴木 義幸';
$price = 1047;
?>
著者:<?= $title?>
価格:<?= $price;?>円
書題:<?= $author?>

これを実行すると次のようになります。

$ php sample.php
著者:コーチングのプロが教える 「ほめる」技術価格:1047円
書題:鈴木 義幸

”円”にだけ改行が反映されています。何故なんでしょうか。改行は無視されるときとされない時があるんです。

改行は反映されません。

php では、<?php ?> で囲まれたエリアはそのまま、コードとして解釈されます。と一般的に習うんでしょうけど、例外があります。

終了タグは、「改行」を含んで終了と解釈されます。?> ⏎?> と同じなのです。

改行コードは2つ続いても、一つになる。

一つだけだと

abc<?php
?>

実行後は

abc

になります。

なので、改行を反映したいときは、空行を入れるか、空白を入れます。

abc<?php
?> ⏎
⏎

これが実行されると

abc⏎

になります。

対策

こうします。空白を入れます。

<?php echo $name; ?>␣⏎

便利なときもある。

php のファイルから php をrequire したときに、改行コードをいい感じにしてくれるので便利なこともある。

テンプレートのフォーマットでは空白か空行を多めにいれる。

そういう仕様なのです。如何ともし難い。仕方ないのです。php で改行がでなくてもHTMLは改行を無視するのであまり気になっていないという現実があります。

これが、phpCSVバッチ処理やメール送信など、プレーンテキストを扱うと途端に問題になります。とくにCSVとメールでしょうか。

php の仕様

仕様なのです。phpは4→5, 5→6とかなり後方互換を切り捨ててきたので、そろそろこの辺もバッサリ切ってほしいと思ったりするのですが。

テンプレートとしてphpを実行したときに改行コードを意識する必要があるのは若干不便ではないでしょうか。

実験に使用したphp

今回は、このphp でサンプルコードを書いて実行しています。

PHP 7.3.11 (cli) (built: Oct 24 2019 11:29:42) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans

参考資料

mac で sendmail コマンドを動かす。

sendmailgmailSMTPを使う。

mac には 最初から postfix が入っているので、 postfix を使うのが手っ取り早い

postfix を使ってSMTPリレーをし、GmailSMTPサーバーに接続する。

sasl password ファイルを用意する

takuya@mail$ sudo -e  /etc/postfix/sasl_passwd

/etc/postfix/sasl_passwd

smtp.gmail.com:587 youname@gmail.com:your_password

main.cf の作成

私の環境では、なぜか、main.cf が空っぽのファイルになっていたので、デフォルトを取り出します。

sudo cp  /etc/postfix/main.cf~orig /etc/postfix/main.cf

postmap の実行

postmap をつかって、パスワードをdb に登録します。

sudo postmap /etc/postfix/sasl_passwd

main.cf でリレーを設定します。

main.cf を開いて、末尾に追記します。

# Apple Defaults
#
message_size_limit = 10485760
mailbox_size_limit = 0
biff = no
mynetworks = 127.0.0.0/8, [::1]/128
smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated permit
recipient_delimiter = +
tls_random_source = dev:/dev/urandom
smtpd_tls_ciphers = medium
#### ここから追記
## gmail へのリレー設定

relayhost=smtp.gmail.com:587
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_use_tls=yes
smtp_tls_security_level=encrypt
tls_random_source=dev:/dev/urandom
smtp_sasl_security_options = noanonymous
smtp_always_send_ehlo = yes
smtp_sasl_mechanism_filter = plain

postfix の実行

設定ができたので、postfixを起動します。

sudo postfix start

起動を確認しておきます。

takuya@mail$ ps aux | grep postfix
321:_postfix          9807   0.0  0.0  4305160   4004   ??  S     4:32AM   0:00.03 tlsmgr -l -t unix -u
325:_postfix          9461   0.0  0.0  4324644   4092   ??  S     4:28AM   0:00.04 qmgr -l -t fifo -u
326:_postfix          9460   0.0  0.0  4332788   4036   ??  S     4:28AM   0:00.03 pickup -l -t fifo -u -o content_filter=
327:root              9459   0.0  0.0  4297908    560   ??  Ss    4:28AM   0:00.03 /usr/libexec/postfix/master -w

終了するときは、 

sudo postfix stop

sendmail コマンドでテストメールを送信します。

サンプル用のメールを作成します。 sample-mail.txt

To:takuya@example.com
Subject: HELLO , from test



Hi, can you see my mail?

sendmail コマンドで送信します。

cat sample-mail.txt | sendmail -i -t

メールの受信を確認します。

無事に届けばOKです。

注意点

幾つか、気にしておく点をメモしておきます。

ポート開けっ放し?

postfix を常時動かすのはセキュリティ的に怖いのですが。使うときだけ起動できるので、それで妥協する。

sendmail コマンドとを互換性を持った別のコマンドを作ってもいいんですけど。作るのはめんどくさすぎるので

使うときのみ postfix を起動し使い終わったら終了するようにしておく。

また、smtp のリレーを localhost ( ::1 / 127.0.0.1 ) に限定するのも一つの手段です。

GmailSMTPを使うために

GmailSMTPは「安全性の低いアプリ」などと呼称されている 。安全性の低いアプリ( less secure apps ) をオンにしないとSMTP経由でメールが送れないかもしれない。

最近は、SMTPだけは開放されているようです。以前はこれをONにしないとSMTPが使えなかった。

指定するGoogleSMTP(s)のポートによっては使えない可能性が高い。

lscpu コマンドが便利。 cat /proc/cpuinfo がメニーコアだと使いにくい

CPU マルチコア・マルチスレッド化 して情報を見にくい。

cat /proc/cpuinfo の出力が多すぎて見にくい。

表示は4コア2スレッドの合計8スレッドのCPUなんだけど、この数がどんどん増えていくんですよね。Ryzenとか買った日には、最大64個とかになるんでしょ?

proc/cpuinfo はもう限界。 lscpu を使う。

代替手段として lscpu コマンドを使うと便利。

takuya@:~$ LANG=C lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 94
Model name:            Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Stepping:              3
CPU MHz:               799.987
CPU max MHz:           4000.0000
CPU min MHz:           800.0000
BogoMIPS:              6816.00
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch invpcid_single ibrs ibpb stibp kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp

日本語表記もできる

takuya@:~$ lscpu
アーキテクチャ: x86_64
CPU 操作モード:   32-bit, 64-bit
バイト順序:       Little Endian
CPU:                   8
オンラインになっている CPU のリスト:0-7
コアあたりのスレッド数:2
ソケットあたりのコア数:4
ソケット数:       1
NUMA ノード数:     1
ベンダー ID:       GenuineIntel
CPU ファミリー:   6
モデル:             94
モデル名:          Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
ステッピング:    3
CPU MHz:               799.987
CPU 最大 MHz:        4000.0000
CPU 最小 MHz:        800.0000
BogoMIPS:              6816.00
仮想化:             VT-x
L1d キャッシュ:   32K
L1i キャッシュ:   32K
L2 キャッシュ:    256K
L3 キャッシュ:    8192K
NUMA ノード 0 CPU:  0-7
フラグ:             fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch invpcid_single ibrs ibpb stibp kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp

Intel のAESサポートが有効になっているか調べる

intel のAES処理が有効になっているか調べる

カーネルの暗号化モジュールから、一覧を拾ってきて aesni が入ってれば大丈夫っぽい

takuya@:~$ sort -u /proc/crypto | grep module
66:module       : aes_x86_64
67:module       : aesni_intel
68:module       : crc32_pclmul
69:module       : crc32c_generic
70:module       : crc32c_intel
71:module       : crct10dif_pclmul
72:module       : cryptd
73:module       : ghash_clmulni_intel
74:module       : kernel

対応CPUについて

詳しくは wikipedia:en を見ると書いてある。 wikipedia:ja は情報が更新されてない。

この辺が対応CPU

  • Westmere based processors, specifically:
  • Westmere-EP (Xeon 56xx) (a.k.a. Gulftown Xeon 5600-series DP server model) processors.
  • Clarkdale processors (except Core i3, Pentium and Celeron).
  • Arrandale processors (except Celeron, Pentium, Core i3, Core i5-4XXM).
  • Sandy Bridge processors:
  • Desktop: all except Pentium, Celeron, Core i3.[5][6]
  • Mobile: all Core i7 and Core i5. Several vendors have shipped BIOS configurations with the extension disabled;[7] a BIOS update is required to enable them.[8]
  • Ivy Bridge processors.
  • All i5, i7, Xeon and i3-2115C[9] only.
  • Haswell processors (all except i3-4000m,[10] Pentium and Celeron).
  • Broadwell processors (all except Pentium and Celeron).
  • Silvermont/Airmont processors (all except Bay Trail-D and Bay Trail-M).
  • Goldmont processors.
  • Skylake processors.
  • Kaby Lake processors.
  • Coffee Lake processors.

自分の買おうとしているCPUが対応しているかどうかは、Google検索で検索すればいい。

Skylake以降のデスクトップ用のCPUならほぼ確実に。それ以前はi7/i5以上。廉価CPUならGoldmont 以降CPUについてる。やすいの攻めたらついてないこともあるみたいね。

Celeron J1900 / 非対応 - よく売られている廉価ボードに搭載されている celeron j1900 aes - Google 検索

Pentium N4200 - Liva2 などに搭載されている。 pentium n4200 aes-ni - Google 検索

Livaいいじゃん

Amazonで中華製のLANポートがいっぱいついたマシンを買おうと思ってたけどJ1900ばっかりなんですよね。

HTTPSOpenVPNとか考えるとAESがいいかもしれない。

関連記事

AESの速度議論のためには種類のCPUで、AESの速度を測定する。- intel arm mips - それマグで!

CPUのAES暗号化速度をCPU組込のaesサポートのありなしで測定する。 - それマグで!

参考資料

How to find out AES-NI (Advanced Encryption) Enabled on Linux System - nixCraft

CPUのAES暗号化速度をCPU組込のaesサポートのありなしで測定する。

Intel CPU に搭載されたAESサポートがどれくらい強烈か比較してみたかった。

x86intel CPU にはAESのサポート ( AES-NI )が組み込まれていて 処理速度が速いということは、知られた事実だと思う。

暗号化アクセラレータとして動作しているのですが、どれくらいの速度の恩恵が出ているのか。知りたくなった。

HTTPSSSD/HDDの暗号化で処理速度が気になると言われたので、じゃぁ調べてみようじゃないかと。

AESのありなしで速度を測定するコマンド

CPU(AES-NI) の機能を「オフ」/disable にした場合の測定。

OPENSSL_ia32cap="~0x200000200000000" openssl speed -elapsed -evp aes-128-cbc

CPUの機能をオン / enable にした場合

openssl speed -elapsed -evp aes-128-cbc

実際に測定してみた結果

takuya@:~$ OPENSSL_ia32cap="~0x200000200000000" openssl speed -elapsed -evp aes-128-cbc
You have chosen to measure elapsed time instead of user CPU time.
Doing aes-128-cbc for 3s on 16 size blocks:

62451619 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 64 size blocks: 18216095 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 256 size blocks: 4615725 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 1024 size blocks: 1176014 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 8192 size blocks: 147045 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 16384 size blocks: 73621 aes-128-cbc's in 3.00s
OpenSSL 1.1.1d  10 Sep 2019
built on: Wed Oct  9 01:04:37 2019 UTC
options:bn(64,64) rc4(16x,int) des(int) aes(partial) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-1.1.1d=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128-cbc     333075.30k   388610.03k   393875.20k   401412.78k   401530.88k   402068.82k

takuya@:~$ openssl speed -elapsed -evp aes-128-cbc
You have chosen to measure elapsed time instead of user CPU time.
Doing aes-128-cbc for 3s on 16 size blocks: 153491212 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 64 size blocks: 66078098 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 256 size blocks: 16915245 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 1024 size blocks: 4232165 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 8192 size blocks: 533750 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 16384 size blocks: 266600 aes-128-cbc's in 3.00s
OpenSSL 1.1.1d  10 Sep 2019
built on: Wed Oct  9 01:04:37 2019 UTC
options:bn(64,64) rc4(16x,int) des(int) aes(partial) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-1.1.1d=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128-cbc     818619.80k  1409666.09k  1443434.24k  1444578.99k  1457493.33k  1455991.47k
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
なし aes-128-cbc 333075.30k 388610.03k 393875.20k 401412.78k 401530.88k 402068.82k
あり aes-128-cbc 818619.80k 1409666.09k 1443434.24k 1444578.99k 1457493.33k 1455991.47k

AES-NIはえ

関連記事

AESの速度議論のためには種類のCPUで、AESの速度を測定する。- intel arm mips - それマグで!

参考資料

https://github.com/mdaxini/howto-openssl/wiki/OpenSSL-Cipher-Speed

https://ja.wikipedia.org/wiki/AES-NI

AES instruction set - Wikipedia

Google Chrome に保存されたパスワードを全消去しパソコンから削除する方法

Google Chrome に保存されたパスワードの削除方法

Google Chromeに保存されたパスワードを削除し、パスワードが自動入力されるのを防止したり、パソコンに保存されたパスワードが読み取られないようにする。

履歴から消すと早いです。

一つずつ削除してもいいのですが、履歴からすべての保存済みパスワードを削除するのが楽です。

f:id:takuya_1st:20191209170557p:plain

履歴から削除する手順

Chromeを開いて「閲覧履歴データ」を表示します。

閲覧履歴データの削除を選びます。

f:id:takuya_1st:20191209170535p:plain

詳細設定で、削除したいパスワードの「期間」を選びます。すべて削除するなら「全期間」です。

f:id:takuya_1st:20191209170538p:plain

自動入力フォームの記録や、パスワードをスクロールして選びます。

あとは、「削除」ボタンを押すだけです。

f:id:takuya_1st:20191209170557p:plain

パスワード管理ソフトに頼る

パスワードは、記憶より機械に頼るほうが安全です。

Chrome パスワードはパスワードで保護されている- 最初に知っておく

最初に知っておくべきことですが、保存されたChromeのパスワードは暗号化されパスワードで保護されています。

Chromeのパスワードはパソコンにログインするパスワードで保護されています。macOSであればキーチェインで保護されています。

ときどき、「パスワードをパソコンに保存しないことがセキュリティ」という誤った説明を見かけますが、パスワードを保存すること自体が悪事ではなく、パソコンのユーザーにパスワードを掛けないことが危険なのです。

パソコンのログインにロックを掛けていない。その場合でも、Google ChromeGoogle アカウントでログインしていればパスワードは安全に保存されています。データを復元されたとしても盗まれたとしてもパスワードの中身まで取り出せる可能性は極稀です。

危険なのは、基本的な安全対策を怠っている場合です。パソコンにユーザーロックを掛けてない。Chromeにログインせずにパスワードを保存した。パスワードをExcelファイルに保存している*1。パスワードを保存することそれ自体を悪魔のように呼称するのは間違いでしょう。

自動保存のほうが安全。

パスワードは「自動的に保存」され「自動的に入力」されます。

自動的に入力されるときに、サイトが「正規のドメイン」であるか一致検証してから入力されます。

フィッシング詐欺の偽装サイトには自動入力が行われません。

逆に言えば

自動入力がされない場合はフィッシング詐欺の可能性がある。ということです。

なので、できる限り自動入力を使いましょう。

自動入力ができないサービスの利用を控えるのもいいでしょう。

Google を信用できないとき

Googlechrome は大勢に支持され使われていますが、その分狙われることも多いいです。 またGoogleに頼るのも心配なことでしょう。

その場合は、次のような無料サービスや

次のような有料サービス

などを利用するのも一つの手段です。

復元ソフト?大丈夫です。

復元ソフトで復元されたとしても、パスワード保存ファイルにパスワードが掛かっているので、そうかんたんには見られることはありません。WindowsMacのログインパスワードを掛けておくことが重要です。またHDD・SSDは暗号化しておくとそれらを安全に扱えるのです。

もしロックもパスワードもかけてないのであれば、「物理的」に安全にパソコンを管理しましょう。他人にパソコンを触らせない。外出時に部屋にカギをかける。他人を部屋に入れないなど物理的なセキュリティを確保することが大事です。

パスワードの定期的な変更よりずっと大事です。

まとめ

パスワードやセキュリティについてよく聞かれるので、そのときに答えていることを簡単にまとめました。

保存したパスワードを削除する方法は簡単です。履歴から削除すればいいのです。

ただし、パスワードは自動保存と自動入力したほうがむしろ安全な場面も多いと覚えておいてください。

万が一、Google を信用できないときは、パスワードを削除しましょう

*1: Excel ファイルをパスワードロックかけておくと安全です

mac で ⌘コマンドやオプション⌥を入力する方法。

Macのキーボードに印字された記号を入力する

コマンド⌘やオプション⌥など、Macのキーボードにはには記号がいっぱいある。

これを入力する方法を紹介します。

方法1:変換する

変換するのが手っ取り早い

入力したいときは、変換するのが手っ取り早いです。

オプション

f:id:takuya_1st:20191216162146p:plain

コマンド

f:id:takuya_1st:20191216162208p:plain

変換にない場合は、登録しましょう(後述

方法2文字ビューワーから

文字ビューワーを使って入力すると速いです。

f:id:takuya_1st:20191216162338p:plain

文字ビューワーの呼び出し方。

右上の日本語の「あ」と出てくるところをクリックして、絵文字ビューワーを表示します。 f:id:takuya_1st:20191216162537p:plain

そのままでは、キーボードの記号が出て来ません。

なので、リストをカスタマイズして一覧に表示します。

f:id:takuya_1st:20191216161729p:plain

f:id:takuya_1st:20191216162513p:plain

技術的記号を選択して、一覧に追加すると、⌘やオプションなどの記号が使えるようになります。 f:id:takuya_1st:20191216161700p:plain

日本語入力に辞書で登録する。

Google IME など日本語入力ソフトに、変換候補の文字列として辞書登録しておくと良いと思います。 f:id:takuya_1st:20191216163826p:plain

辞書登録の例。

f:id:takuya_1st:20191216164854p:plain

JSでHTTP GET クエリ文字列を JS オブジェクトから作成する-

js で http query をオブジェクトからビルドする

JavascriptのオブジェクトをURLのGET引数に変換したいときには、npm 探しますか? ライブラリ探しますか?

URLSearchParams ができています。

GETパラメタを扱うときは、これがあれば、だいたい解決する

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

URLSearchParams は 古くは querystring と呼ばれた関数です。パワーアップして帰ってきました。

https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/High-Level_APIs/querystring

Object( hash ) → queryString の変換

手軽で便利な使い方です。

new URLSearchParams( {a:1 , b:3} ).toString();
'a=1&b=3'

便利ですね。

ネストには注意

そのままでは、ネストできません。ネストできません。

オブジェクトのネスト:

Object文字列になります。

> new URLSearchParams( {a:{x:10,y:11}, b:3} ).toString();
'a=%5Bobject+Object%5D&b=3'

残念。toString されているだけです。

配列でネスト

配列も同じです。

> a = new URLSearchParams( {a:[10,11], b:3} ).toString();
'a=10%2C11&b=3'
> decodeURIComponent(a)
'a=10,11&b=3'
>

残念ですね。toStringされているだけです。

URLのGETパラメタを正しく扱うので、同名のパラメタが2個あっても良い。

これもオブジェクトを扱うときの注意点なのですが、キー名はダブることがあります。

オブジェクトではダブリを扱えないのですが、URLSearchParamsは扱えてしまいます。

> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺")
URLSearchParams { 'start' => '大阪', 'via' => '心斎橋', 'via' => '難波', 'dest' => '天王寺' }

Objectをパラメタ変換しようとしたり逆にObjectで取り出そうとしたとき、ネストをどう扱うか、ダブるキー名をパラメタに含めるなど、キーを扱うときは注意を払う必要があります。

Object {} と URLSearchParams は等価交換できないのです。配列になってくれたりしないのです。

iteratorで使うURLSearchParams

> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺").entries()
URLSearchParams Iterator {
  [ 'start', '大阪' ],
  [ 'via', '心斎橋' ],
  [ 'via', '難波' ],
  [ 'dest', '天王寺' ] }

こちらは、全パラメータをきれいにiterator で回るのです。

Iterator からさらオブジェクトへ(2021-11-19追記)

Iterator のママでは少々使いにくいので Object.fromEntries を使って便利に使う。

var cond = Object.fromEntries(new URLSearchParams(window.location.search))
cond['start']

Object.fromEntries はバージョンを選ぶので、polyfill したほうが無難。

node の組込querystringなら、配列になってくれる

https://nodejs.org/api/querystring.html
querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺")
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}

node 組み込みの querystring ならば、配列になってくれていたので、このほうが便利だったと思うんですね。

きれいなオブジェクトになる querystring

URLSearchParams と違って node の querystring ならオブジェクトになってきれいだと思う。

> a = querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺")
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}
> a
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}
> querystring.stringify(a)
'start=%E5%A4%A7%E9%98%AA&via=%E5%BF%83%E6%96%8E%E6%A9%8B&via=%E9%9B%A3%E6%B3%A2&dest=%E5%A4%A9%E7%8E%8B%E5%AF%BA'
> decodeURI(querystring.stringify(a))
'start=大阪&via=心斎橋&via=難波&dest=天王寺'

結論

URLSearchParamsが使えますが、ネストなど複雑なパラメタは扱いづらい。

node 環境下では querystring を使える。

ならば、ブラウザにnpmで互換パッケージをポーティングしたほうが便利なのかもしれません。

参考資料

Hello Worldを 2進数の0/1 にバイナリに変換してランダムパッド(使い捨て暗号

バイナリ変換してXORして遊びたい

暗号技術入門を呼んでいると、XORがバンバン出てくるので、ちょっとやってみようと思い立った

暗号技術入門 第3版

暗号技術入門 第3版

ruby で計算するのが早い

>> "Hello".each_byte.map{|e| e }.join(" | " )
=> "72 | 101 | 108 | 108 | 111"
>> "Hello".each_byte.map{|e|  sprintf("%b", e)  }.join(" | " )
=> "1001000 | 1100101 | 1101100 | 1101100 | 1101111"

これをXORと併せて計算しましょう

本当は、C言語のプログラミングの授業でやりたいんだけどねぇ。

Ruby で ランダムパッドをして遊ぶ。

>> "Hello".each_char.zip( "World".each_char )
=> [["H", "W"], ["e", "o"], ["l", "r"], ["l", "l"], ["o", "d"]]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("World".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "Hello"
>>

Hello を World で XORで符号化する

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.map{|e|  sprintf("%08b", e)  }.join(" | " )
=> "00011111 | 00001010 | 00011110 | 00000000 | 00001011"

この結果を、World以外の文字列でXORするともとに戻らない。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("abcdef".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "~h}dn"

ただし、ただし、一部が一致すると。。。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("world".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "hello"
>>

このように、一部が一致するとXORのランダムパッドでは暗号とは言えなくなる。

出てきた文字が正しいかわからない

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("XYZaa".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "GSDaj"

ここでは、暗号化に使う鍵に、「World」という文字列を採用しましたが、ランダムの使い捨てパッドである必要があります。

こうやって扱ってみると、ランダムパッドによる使い捨て暗号は、色々と問題があることがわかる。

安いLG Ultra HD モニタ(4k対応) はMacのRetinaモードに非対応(部分対応)だった件

4k ディスプレイのすべてがRetinaモードに対応してるわけではない。

4kディスプレイを幾つか試していて気づいたんですが、LGのディスプレイの一部モデルは、Retina解像度で縦横の長さを任意に変更できない模様。

LG Ultra HD のもの

Macのディスプレイ設定で見ると次のように見える。Full HDではRetinaモードになるのですが、フルHD以外の拡大率150% などは一切考慮されてないようで。。。

何故だろうか。とても不思議だった。

f:id:takuya_1st:20191129152032p:plain

Acer のモニタの場合

Acerのモニタで試したら、Retinaの任意の倍率に変更できる。28インチと32インチで試したら次のように表示される。

f:id:takuya_1st:20191129152046p:plain

IO-DATA のモニタの場合

IO−DATAのモニタの場合でも、Retinaの倍率選択が出てきて、好きな倍率の設定できて嬉しい。

f:id:takuya_1st:20191129152125p:plain

LGはガチャ

LGでも任意に設定できるものがあるのですが、安いものは駄目みたい。買ってみて接続しないとわからないので、実質的にガチャ回す感じ。

Amazonプライムで購入したら返品ができるのですが、それでも返品ガチャを回すひと手間はめんどくさい。やっぱりK国製より、台湾メーカーですね。

LGでも問題はないんだろうけど、今後ちょっと追調査が必要だと思われる。

おすすめの4kモニタ

この辺がMacで接続するにはおすすめだと思う。価格的にも3万円くらいで済むし、Amazonブラックフライデーサイバーマンデーセールで8%オフとか

 

Acerno27インチはスピーカーの性能と、HDMI検出がエラーになることが多いなど問題点は多いが、価格と性能は問題ないし、妥協しないと駄目だった。

USB-C電源と一体化したケーブルが便利

USB-Cと一体化したモニタが魅力だけど、USB-Cで一体化したモニタは高いので、こういうのを使うと使い勝手を享受しながら、価格を妥協できる

macOSでwinRAR の rar ファイルを「作成」する

macOS でも winRAR のファイルアーカイブを作成したい。

zip / tar.gz でいいだろと思われるんだろうけど、リカバリレコードを付与できるアーカイブ形式ってやっぱりrar しかないよね。

brew の formula 作った

winrar からコマンドバイナリを取得してインストールして管理するのは面倒なので、 brew 用のformula を作っておいた

https://github.com/takuya/homebrew-winrar-osx

brew tap takuya/homebrew-winrar-osx

インストール

brew install takuya/homebrew-winrar-osx

基本的な使い方はLinux版などと同じ。

rar コマンドでのファイルの作り方。

rar a 作りたいアーカイブ名 ファイル1 ファイル2 ...

リカバリレコードを付与したファイルの作成

リカバリレコードを5%付与した場合。

rar a -rr5p  out.rar dir/files*

ファイルをまるっと付与してRARファイルを作成することができる

rar ファイル

rar は加齢臭がするんだろうけど、他に手軽なツールってあまりないですよねぇ。zip ファイルはあれこれ制限があるし tar.gz こそ加齢臭がする。

展開(解凍)するなら

rar よりも lsar / unar のコマンドが便利。

https://takuya-1st.hatenablog.jp/entry/2016/08/03/145534

関連記事

Linux でwinrar のrarファイルを圧縮展開・rr3% つける。rarで文字コードも嬉しい? - それマグで!

tcpdump でパケットのサイズが指定以上より大きいものを取り出す。

tcpdumpで パケット長でフィルタを掛けたい

小さいパケットは無視したり、一定以上のサイズのものだけを取り出したい。

tcpdump -i eth0 greater 500

greater の条件を使うことで、パケットの長さを元にフィルタをかけることができる。逆は less

組み合わせる

tcpdump は組み合わせで使うことが多いので、条件をいれフィルタを掛けてあげる。

tcpdump -i eth0 dst 102.168.2.206 and udp and geater 1000

and で繋げばパケットをフィルタできる。 -i デバイス はそれとは別に tcpdump で取得するネットワーク・デバイス(インタフェース)を指定している。

tcpdump で UDP のパケットを表示する

tcpdump を使って UDP を指定する

tcp は syn ack があってパケットがたくさん出てきますが、 UDP はそうでもない。

tcpdump -i eth0 udp

UDPIPアドレスを指定する

tcpdump のコマンドは、フィルタ単体というより、いくつかのフィルタを組み合わせて使うのが便利。

tcpdump -i eth0  dst 192.168.2.206 and udp

and をつかって dst /src のIPなどと組み合わせてやれば、リアルタイムにパケットをきれいに見ることができる。

Number と parseInt()の挙動の違い / 数字に変換するとひと言でいうが奥深い

parseInt と Number の挙動の違い。

parseInt と Number という2つがある。文字列 → 数値の型変換の関数を使おうとしてみんな一度くらいこの違いが気になるんじゃない?

違いをパパッと確認しよう

parseInt と Number の差異が如実に顕出するのは、次の例ではないでしょうか。

// 文字列が含まれる
parseInt("64GB")   //  64
Number("64GB")  // NaN
// 少数
parseInt("0.1")  //  0
Number("0.1")   // 0.1

IntがほしいならparseInt が便利。

parseInt の結果を見てほしい

parseInt("1")      //  1
parseInt("10")     //  10
parseInt("0.1")    //  0
parseInt("010101") //  10101
parseInt("64GB")   //  64
parseInt("¥64")   // NaN
parseInt("64円")   // 64
parseInt("第64回") // NaN
parseInt("2e1")    // 2
parseInt("0xFF") // 255
parseInt("0xFF times")// 255

少数が処理できないという、parseInt の名前の通りの仕様を除けば、概ね楽ちんに変換できる。

事前に文字列を処理して、必要なフォーマットに変換する手間がない。

parseInt は関数の名前( parseInt =Int に解釈する )の通りの動作だったり。

Number は本当の意味で型変換

Number は JS の Number 型であり、Number型の変数を返すので、本当の意味で型変換だと思うの

Number("1")    // 1
Number("10")   // 10
Number("0.1")   // 0.1
Number("010101") // 10101
Number("64GB")  // NaN
Number("¥64")  // NaN
Number("64円")  // NaN
Number("第64回") // NaN
Number("2e1")  // 20
Number("0xFF") // 255
Number("0xFF times") // NaN

個人的な結論

parseIntは、単位が含まれたりする入力値してぱぱっと数字へ変換したいとき → 10px とか 100円とか、CSSの値を数値にしたいときに便利

Numberは厳密に文字列事前処理し、その結果を数字に正確に変換するときに使う。

基本はNumberを使う、事前処理などを無精するときはparseIntもまだまだ許容されると思う。

少数にならないCSSの文字列 element.style.width とか処理をするなら重宝する。

tcpdump コマンドで ping の応答 ( icmp echo reply ) だけに絞り込む

tcpdumpping の 応答パケットだけを取り出す。

tcpdumpLinuxルーターのなかで実行しているときに、デバッグしてるときにパケットを見ます。

ネットワーク間の forward が正しく動いているか、iptables の設定が正しいかどうか、NATできてるかどうか。など。

ちょっとした調査でping を打ち込んで調べることが多いと思います。そういうときに、icmp だけ取り出しても表示が多すぎて面倒くさい。

reply だけを表示する

tcpdump  icmp[icmptype] = icmp-echoreply'

指定のホストから reply が戻ってきたか調べる

IP を指定と組み合わせて使うと便利

tcpdump  src 192.168.1.1 and icmp[icmptype] = icmp-echoreply'

指定のホストに echo リクエストが転送されか調べる

逆も同じ

tcpdump  'dst 192.168.100.1 and icmp[icmptype] = icmp-echo'

組み合わせで便利。

バイスを指定したり、IPを指定で便利になる。単純に icmp を見るよりいいと思う。echo / echo-reply を表示するターミナルを開けておいて、設定を反映させる。

設定を変えたあと、画面にログが表示され始めたら、ネットワーク設定が正しく行えたことがわかる。

ログが流れないなら、設定ミスってるってわかるので視覚的にわかりやすくていい。中身見なくていいのが強い。

設定ミスしがちな「戻りパケット」の経路設定の切り分けをするときに、明確に分かれるから面白い

参考資料

https://hackertarget.com/tcpdump-examples/