text.Baldanders.info
tag:text.Baldanders.info,2024-03-28:/
2024-03-28T23:06:03+00:00
帰ってきた「しっぽのさきっちょ」
https://text.baldanders.info/images/avatar.jpg
https://text.baldanders.info/images/avatar.jpg
Chromebook を導入する
tag:text.Baldanders.info,2024-03-28:/remark/2024/03/chromebook-1/
2024-03-28T13:59:51+00:00
2024-03-28T23:06:03+00:00
「頑張ったご褒美」第2弾
Spiegel
https://baldanders.info/profile/
<p>給与明細を見たら残業代が凄いことになってたのですよ。
ちうわけで「頑張ったご褒美」第2弾。
ついに Chromebook を導入することにした。</p>
<h2>「頑張ったご褒美」にノートPCを物色中</h2>
<p>私は(当時の)東芝の Dynabook が登場したばかりの頃にそれを持たされて,現地調整と称して客先に缶詰になったことが何度かあってノート PC にいいイメージがない。
(今で言うところの)ブラックの象徴だったり。
まぁ,でも,仕事以外のサイクリング等で出掛けた先で軽く調べ物とかできたらいいなぁ,とちょっと思い直した。
そんでノートPCの物色を始めたんだけど…</p>
<p>私がプライベートで使ってる<a href="https://text.baldanders.info/remark/2022/10/messenger-bag/" title="遅走り,早歩き">メッセンジャーバッグ</a>はサイズ小さめで13インチ以下のノートPCしか入らないのね。
なのでその線で探してみたんだけど,
15インチノートPCのほうが断然安いってどういうことやねん! 進学・就職・異動の季節で各メーカーが安売りしてるみたいだけど,13インチノートPCは恩恵を受けられないようだ。
中古PCは前に酷い目にあったので買いたくないし。</p>
<p>…などとしばらく悩んで「そうだ! Chromebook なら要件を満たすんじゃね?」と気がついた。
しかも想定よりだいぶ安上がりになるし(笑)</p>
<h2>Chromebook / ChromeOS とは</h2>
<p>今更だけど,念のために記しておく。</p>
<p>Chromebook は ChromeOS を搭載したパソコンである。
日本円で数万円程度の廉価 PC として提供されていることが多い。</p>
<p>ChromeOS は,もの凄く簡単に言うと, Chrome ブラウザを GUI とした OS である。
したがって,基本的に ChromeOS のアプリケーションは Chrome ブラウザの拡張機能として実装されている(<a href="https://chromewebstore.google.com/">Chrome ウェブストア</a>から導入可能)。
ただし,近年の ChromeOS は Android と Linux のサブシステムを標準で装備している。</p>
<p>つまり Chromebook では Chrome ベースのアプリと Andorid アプリと Linux のアプリケーションが動くわけだ。
これならネットワーク端末としては申し分ないだろう。</p>
<h2>Chromebook を購入した</h2>
<p>前述したように,今回は13インチ以下のノートPCという縛りがある。
あちこち探し回って疲れたので Amazon にあるものから選択することにした。
日和ったとも言う(笑)</p>
<p>要件を満たす候補として <a href="https://www.amazon.co.jp/gp/product/B0BKKF7JHV?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">ASUS 製</a>と <a href="https://www.amazon.co.jp/dp/B0CNSWLJFM?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Lenovo 製</a>の2つまで絞り込んだ。
<a href="https://www.amazon.co.jp/dp/B0CNSWLJFM?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Lenovo 製</a>のほうが安くて軽くてストレージ容量が大きいのだが,私が ASUS のほうが好みなのとメモリ容量が大きいということで <a href="https://www.amazon.co.jp/gp/product/B0BKKF7JHV?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">ASUS 製</a>に決めた。
ストレージは後から調達できるからね。</p>
<p>というわけで到着。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53614190956/"><img src="./53614190956_f3a103a7a4_e.jpg" srcset="./53614190956_f3a103a7a4_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="先月の汗と涙とストレスと(削られた)睡眠時間の対価 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53614190956/">先月の汗と涙とストレスと(削られた)睡眠時間の対価 | Flickr</a></div></figcaption>
</figure>
<p>早速開梱してセットアップを始める。
以降は作業中の覚え書である。</p>
<h2>ChromeVox ?</h2>
<p>セットアップが始まって最初に ChromeVox を有効にするか訊かれる。
ChromeVox って何?</p>
<ul>
<li><a href="https://support.google.com/chromebook/answer/7031755?hl=ja">組み込みのスクリーン リーダーを使用する - Chromebook ヘルプ</a></li>
</ul>
<p>んー。
どうやら視覚障害者のためのスクリーンリーダーらしい。
いや,それならそうとちゃんと説明してくれ。
分かんないからググったやんけ。</p>
<p>ありがたいことに私は<a href="https://text.baldanders.info/remark/2021/08/age-of-reading-glasses/" title="老眼鏡の季節">眼鏡があれば普通に見える</a>ので,今回はスルーした。</p>
<h2>PIN コードを設定する</h2>
<p>そんなこんなでセットアップも無事完了して,色々と弄り始めたのだが,スクリーンロックからの復帰とか,ことあるごとに Google アカウントのパスワードを入れさせようとするのね。
いや,パスワードは覚えない主義なので,それじゃ困るわけさ。
せめて PIN コードの設定とかできないの? と探してみたらあった。</p>
<p>設定から「セキュリティとプライバシー」を選択し,さらに「ロック画面とログイン」を開く。</p>
<figure style='margin:0 auto;text-align:center;'><a href="./setting-pin-code.png"><img src="./setting-pin-code.png" srcset="./setting-pin-code.png 1100w" sizes="(min-width:600px) 500px, 80vw" alt="ロック画面とログイン" loading="lazy"></a><figcaption><div><a href="./setting-pin-code.png">ロック画面とログイン</a></div></figcaption>
</figure>
<p>設定後の状態ですまん。</p>
<p>あとで調べたら,最初のセットアップのときに PIN コードも設定させるみたいなのだが,そんな画面あったかな? まぁ,いいや。
無事に PIN コードが設定できたのでよしとする。</p>
<h2>Dropbox を Files アプリにマウントする</h2>
<p>Chromebook に標準で入ってる「ファイル(Files)」アプリはかなり出来がよくて,最初から Google Drive がマウントされた状態になっている。
ただ,私の場合はクラウドストレージは Dropbox を常用してるのね。
調べてみたら Dropbox も Google Drive のように Files にマウントできるようだ<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。</p>
<ul>
<li><a href="https://help.dropbox.com/ja-jp/integrations/google-files-app">Chromebook の Files アプリに Dropbox を追加する - Dropbox ヘルプ</a></li>
</ul>
<p>といっても全然難しくなく Android アプリの Dropbox アプリを導入してサインインすればいいらしい。</p>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.dropbox.android&hl=en_US">Dropbox: Secure Cloud Storage - Apps on Google Play</a></li>
</ul>
<p>これで自動的に Files に Dropbox が表示される。</p>
<figure style='margin:0 auto;text-align:center;'><a href="./dropbox-in-files.png"><img src="./dropbox-in-files.png" srcset="./dropbox-in-files.png 1100w" sizes="(min-width:600px) 500px, 80vw" alt="Dropbox をマウントする" loading="lazy"></a><figcaption><div><a href="./dropbox-in-files.png">Dropbox をマウントする</a></div></figcaption>
</figure>
<p>もし,いつまで待っても Dropbox が表示されないなら,一度再起動すると上手く行くことがある。</p>
<h2>NAS 共有ディレクトリを Files アプリにマウントする</h2>
<p>更に Files では SMB プロトコルで NAS の共有ディレクトリもマウントできるようだ。
設定から 詳細設定 → ファイル → ネットワークファイル共有 → ファイル共有を追加 と辿ると設定画面が表示される。</p>
<figure style='margin:0 auto;text-align:center;'><a href="./shared-directory.png"><img src="./shared-directory.png" srcset="./shared-directory.png 1100w" sizes="(min-width:600px) 500px, 80vw" alt="ファイル共有を追加" loading="lazy"></a><figcaption><div><a href="./shared-directory.png">ファイル共有を追加</a></div></figcaption>
</figure>
<p>「ファイル共有 URL」に共有ディレクトリを <code>\\server\shared_directory</code> または <code>smb://server/shared_directory</code> 形式で指定し,ユーザ名とパスワードをセットする。</p>
<p>ちなみに今回買った ASUS の Chromebook ではキーボード右上の <span class="box"> ¥ </span> キーと右下の <span class="box"> <code>\</code> </span> キーに割り当てられている文字コードが正しく ¥ (<code>U+00A5</code>) と <code>\</code> (<code>U+005C</code>) になっていた。
ちょっとしたことなんだけど時代を感じるねぇ。</p>
<h2>Tailscale も設定できた</h2>
<p>Andorid アプリの Tailscale アプリを導入することで tailscale にも対応できる。</p>
<ul>
<li><a href="https://tailscale.com/kb/1267/install-chromebook">Setting up Tailscale on a Chromebook · Tailscale Docs</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.tailscale.ipn&hl=en_US">Tailscale - Apps on Google Play</a></li>
</ul>
<p>当然ながらセットアップは <a href="https://text.baldanders.info/remark/2021/10/tailscale-with-synology-nas/#android" title="Android 端末に Tailscale をインストールする">Android 版</a>と同じ。
これで外から自宅 NAS に繋がるようになった。</p>
<p>よーし,うむうむ,よーし。</p>
<h2>その他のインストール</h2>
<p>随時更新予定。</p>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=keepass2android.keepass2android&hl=en_US">Keepass2Android Password Safe - Apps on Google Play</a></li>
<li><a href="https://play.google.com/store/apps/details?id=org.mozilla.firefox&hl=en_US">Firefox Fast & Private Browser - Apps on Google Play</a></li>
</ul>
<p>これで,最低限の環境は揃ったかな。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53613544342/"><img src="./53613544342_db09981a76_e.jpg" srcset="./53613544342_db09981a76_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="とりあえず最低限のセットアップ完了 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53613544342/">とりあえず最低限のセットアップ完了 | Flickr</a></div></figcaption>
</figure>
<p>自宅 Linux/Ubuntu 機と壁紙を合わせてみた。</p>
<p>次回からいよいよ Linux サブシステムのセットアップを行う。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="https://support.google.com/chromebook/answer/10474268?hl=ja">画面のスクリーンショットを撮影または録画する - Chromebook ヘルプ</a></li>
<li><a href="https://note.com/minakonono/n/n30b173adc169">Chromebookを購入しました|Mina</a></li>
<li><a href="https://did2memo.net/2020/10/19/chromebook-dropbox-app-setup/">【Chromebook】Dropboxを利用する方法(ファイルアプリからDropboxフォルダを利用できるようにする/Dropboxフォルダが表示されない場合の対処)</a></li>
</ul>
<h2>参考</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0BKKF7JHV?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41OOqwWbGBL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0BKKF7JHV?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">【Amazon.co.jp限定】 ASUS Chromebook クロームブック Flip CX1 11.6インチ 2-in-1 タッチスクリーン 日本語キーボード 重量1.32kg トランスペアレントシルバー CX1102FKA-MK0037</a></dt>
<dd>ASUS (Release 2022-11-04)</dd>
<dd>Personal Computers</dd>
<dd>B0BKKF7JHV (ASIN), 0195553939942 (EAN), 195553939942 (UPC)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">ASUS 製 Chromebook。11.6インチディスプレイ,8GBメモリ,32GBストレージ。正直,ストレージはもう少し欲しかったがメモリ容量優先で選んだ。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-27">2024-03-27</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- ASUS Chromebook -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B00G9NIL7G?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41uU9SMEAyL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B00G9NIL7G?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">エレコム マウス Bluetooth (iOS対応) Sサイズ 小型 3ボタン IRセンサー 省電力 シルバー M-BT12BRSV</a></dt>
<dd>エレコム (Release 2013-11-09)</dd>
<dd>Personal Computers</dd>
<dd>B00G9NIL7G (ASIN), 4953103501997 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">まぁ,マウスは消耗品だから(笑)</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2019-12-01">2019-12-01</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- エレコム マウス Bluetooth -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B09BMPZ3BZ?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51Q5HoOI9xL._SL160_.jpg" width="112" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B09BMPZ3BZ?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Chromebook仕事術 最速で業務に生かす基本+活用ワザ できるビジネスシリーズ</a></dt>
<dd>株式会社インサイトイメージ (著)</dd>
<dd>インプレス 2021-08-04 (Release 2021-08-04)</dd>
<dd>Kindle版</dd>
<dd>B09BMPZ3BZ (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">Chromebook の操作・設定の基本部分について一通り網羅している感じ。参考になった。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-28">2024-03-28</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Chromebook仕事術 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B08P54PQDB?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/31yRFa0S-+L._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B08P54PQDB?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">[クローム] メッセンジャーバッグ SIMPLE MESSENGER/シンプル メッセンジャー BLACK (現行モデル) 12L 防水 メンズ</a></dt>
<dd>CHROME(クローム)</dd>
<dd>ウェア&シューズ</dd>
<dd>B08P54PQDB (ASIN), 0841916163973 (EAN), 841916163973 (UPC)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">プライベートお出かけ用。たまたま安売りの時に購入できた。チャリンコ乗ってても背中がゆさゆさしない。大きすぎず丁度いいサイズ。鞄の蓋がマジックテープでちょっと煩いのが玉に瑕だが,概ね満足。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2022-10-08">2022-10-08</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- メッセンジャーバッグ -->
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>あとで調べたら Box や OnDrive も Android アプリを使って Files にマウントできるらしい。今回は試さないが。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
OpenPGP 公開鍵の期限を延長した
tag:text.Baldanders.info,2024-03-24:/remark/2024/03/update-expiration-2024/
2024-03-24T03:04:44+00:00
2024-03-24T03:35:08+00:00
2024年末で GnuPG 2.2 系はサポートから外れるんだけどねぇ
Spiegel
https://baldanders.info/profile/
<p>3年前に「<a href="https://text.baldanders.info/remark/2021/03/changing-publickey-management/" title="Baldanders.info サイトにおける OpenPGP 鍵管理の変更">来年からまた短期の運用に戻す</a>」と言ったのに未だに有言不実行。
今年も現行鍵の有効期限を 2025-04-01 まで延長するに留めた。</p>
<p>更新した公開鍵は以下の URI からインポートできる(既にインポート済みの場合は上書き更新される)。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ gpg --fetch-keys https://baldanders.info/pubkeys/spiegel.asc
</span></span></code></pre></div><p>または</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ gpg --fetch-keys https://github.com/spiegel-im-spiegel.gpg
</span></span></code></pre></div><p>拙作の <a href="https://github.com/goark/gpgpdump" title="goark/gpgpdump: OpenPGP packet visualizer">gpgpdump</a> を使えばインポートする前に公開鍵の内容をチェックできる。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ gpgpdump fetch https://baldanders.info/pubkeys/spiegel.asc
</span></span></code></pre></div><p>または</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ gpgpdump fetch https://github.com/spiegel-im-spiegel.gpg
</span></span></code></pre></div><p>いや Ubuntu が <a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 2.4 系にアップデートしてくれないので待ち状態なのよ。
いきなり自前で最新版をインストールするのは怖いので,仮想環境か何かで動作確認をしないといけないのだが,これも遅々として進まず。
2024年末で 2.2 系はサポートから外れるんだけどねぇ。</p>
<p>最近は OpenPGP 鍵の短期運用は,期限切れの鍵が増えるだけで,あまり意味がない気がしてきた。
サーバを運用しているならともかく, OpenPGP 鍵を Yubikey とかのデバイスに入れるのもあまり意味がない気がするんだよな。
私は基本的にノート PC を忌避してるし。</p>
<p>まぁ,どのみち OpenPGP 鍵は <a href="https://text.baldanders.info/openpgp/using-ecc-with-gnupg/" title="そろそろ GnuPG でも ECC を標準で使うのがいいんじゃないかな">ECC にしたい</a>ので,いつかは入れ替えなきゃいけないけどね。
それもこれも <a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 2.4 系の環境が整ってからだ!</p>
<p>…というわけで,もうしばらくはグズってます。</p>
<h2>ブックマーク</h2>
<ul>
<li>
<p><a href="https://www.procustodibus.com/blog/2023/02/gpg-2-4-on-ubuntu-22-04/">Installing GnuPG 2.4 on Ubuntu 22.04 | Pro Custodibus</a></p>
</li>
<li>
<p><a href="https://baldanders.info/pubkeys/">OpenPGP 公開鍵リスト | Baldanders.info</a></p>
</li>
<li>
<p><a href="https://text.baldanders.info/openpgp/gnupg-cheat-sheet/">GnuPG チートシート(鍵作成から失効まで)</a></p>
</li>
<li>
<p><a href="https://text.baldanders.info/openpgp/web-of-trust/">OpenPGP の電子署名は「ユーザーの身元を保証し」ない</a></p>
</li>
</ul>
<h2>参考図書</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4314009071?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51ZRZ62WKCL._SL160_.jpg" width="108" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4314009071?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号化 プライバシーを救った反乱者たち</a></dt>
<dd>スティーブン・レビー (著), 斉藤 隆央 (翻訳)</dd>
<dd>紀伊國屋書店 2002-02-16</dd>
<dd>単行本</dd>
<dd>4314009071 (ASIN), 9784314009072 (EAN), 4314009071 (ISBN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">20世紀末,暗号技術の世界で何があったのか。知りたかったらこちらを読むべし!</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-03-09">2015-03-09</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号化 プライバシーを救った反乱者たち -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51t6yHHVwEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門 第3版 秘密の国のアリス</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2015-08-25 (Release 2015-09-17)</dd>
<dd>Kindle版</dd>
<dd>B015643CPE (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-09-20">2015-09-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号技術入門 第3版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CW1DZS1W?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41pm5BJKQwL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CW1DZS1W?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">科学2024年3月号[雑誌]</a></dt>
<dd>岩波書店『科学』編集部 (編集)</dd>
<dd>岩波書店 2024-02-22 (Release 2024-03-01)</dd>
<dd>Kindle版</dd>
<dd>B0CW1DZS1W (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">この号の特集は「現代暗号の展開と応用」。耐量子計算機暗号や格子暗号といった今どきなキーワードも出てくる。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-01">2024-03-01</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 岩波「科学」2024年3月号 現代暗号の展開と応用 -->
Spiegelさん@がんばらない
tag:text.Baldanders.info,2024-03-23:/remark/2024/03/tekipaki-working/
2024-03-23T00:44:18+00:00
2024-03-23T00:45:54+00:00
たぶん「生産性の高い仕事」ってのは「がむしゃら」にがんばることではなく「てきぱき」さばくことだと思うのよ。
Spiegel
https://baldanders.info/profile/
<p>今回のネタ元はこちら。</p>
<ul>
<li><a href="https://note.com/tsukamoto/n/n8a03a4175572">「がむしゃらに働く」って週60時間ぐらいまで|塚本 牧生</a></li>
</ul>
<p>念のために引用しておくと</p>
<figure>
<blockquote>ただし、ここでいうがむしゃらとは「週60〜65時間労働」です。 これは超えてはいけない過労死ラインで、また超えても成果がむしろ出なくなるラインなので、がむしゃらも度が過ぎないようにしてください。</blockquote>
<figcaption><div><q><a href="https://note.com/tsukamoto/n/n8a03a4175572">「がむしゃらに働く」って週60時間ぐらいまで|塚本 牧生</a></q>より</div></figcaption>
</figure>
<p>ということだそうなので。
つか,まっとうな企業なら三六協定などでその辺は守られてると思うけど。</p>
<p>個人的な感覚として「もう週50Hも無理」になってきた。
我ながら衰えたなぁと思う。
いや頑張ればできるのよ。
でもそこから回復に時間がかかるようになった。
週末休んでも追いつかないくらい。</p>
<ruby><rb>閑話休題</rb><rp> (</rp><rt>それはさておき</rt><rp>) </rp></ruby>
<p>ぺーぺーの新人の頃に言われたのが「仕事には必ず終わりがある」である。
私はこれを曲解して「終わりのない(見えない)仕事は仕事じゃない」と思っている。
精神的に削られるのは「終わりのない仕事」である。
終わりがあるからこそ最終直線のひと仕事を「がむしゃら」に駆け抜けることができる。</p>
<p>たぶん「生産性の高い仕事」ってのは「がむしゃら」にがんばることではなく「てきぱき」さばくことだと思うのよ。
まぁ,それが難しいから「がむしゃら」に頑張ることでカバーしようとするんだけどね。
「てきぱき」さばくのって技能(スキル)だし。
だからといって,そこで「がむしゃら」を導入するのは根本からやり方を間違えてる。
「がむしゃら」は最後のひと鞭で発揮するからこそ効果が出るのである。</p>
<p>…というようなことをつらつらと考えたりした。
なので,やっぱり今年も「がんばらない」方向でよろしくお願いします。</p>
<h2>参考</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B00HY73M16?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51yk+9cbozL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B00HY73M16?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">SAVED. / Be mine!</a></dt>
<dd>坂本 真綾 (メインアーティスト)</dd>
<dd>FlyingDog 2014-02-05 (Release 2014-02-05)</dd>
<dd>MP3 ダウンロード</dd>
<dd>B00HY73M16 (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">「世界征服〜謀略のズヴィズダー〜」OP曲。万能感溢れるノリのいい曲である(笑)</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2020-12-26">2020-12-26</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Be mine! -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4757700423?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/518JGPT6DEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4757700423?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">てきぱきワーキン〓ラブ (5) (ビームコミックス)</a></dt>
<dd>竹本 泉 (著)</dd>
<dd>エンターブレイン 2000-05-01</dd>
<dd>コミック</dd>
<dd>4757700423 (ASIN), 9784757700420 (EAN), 4757700423 (ISBN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">ついに(「さよパラ」にも出てきた)アレックスの謎が解ける?</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2017-10-13">2017-10-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- てきぱきワーキン♡ラブ -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B00FYKN2C4?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51EE+Hx-J8L._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B00FYKN2C4?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">ささみさん@がんばらない【TBSオンデマンド】</a></dt>
<dd>高山カツヒコ (Writer), 新房昭之 (監督), ――― (プロデュース)</dd>
<dd> (Release 2013-05-15)</dd>
<dd>Prime Video</dd>
<dd>B00FYKN2C4 (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">2013年の作品なんだねぇ。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-02-08">2023-02-08</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- ささみさん@がんばらない -->
GnuPG 2.4.4 / 2.4.5 のリリース【セキュリティ・アップデートを含む】
tag:text.Baldanders.info,2024-03-20:/release/2024/03/gnupg-2_4_5-is-released/
2024-03-20T02:03:46+00:00
2024-03-24T03:11:40+00:00
2.4.4 では脆弱性の修正がある
Spiegel
https://baldanders.info/profile/
<p>仕事の忙しさにかまけて色々と放っぽり出してたので,少しずつ回復中。</p>
<p>遅まきながらであるが, 2024-01-25 に <a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 2.4.4 がリリースされた。
さらに先日 2024-03-12 に 2.4.5 がリリースされている。</p>
<ul>
<li><a href="https://lists.gnupg.org/pipermail/gnupg-announce/2024q1/000481.html">[Announce] GnuPG 2.4.4 released</a></li>
<li><a href="https://lists.gnupg.org/pipermail/gnupg-announce/2024q1/000482.html">[Announce] GnuPG 2.4.5 released</a></li>
</ul>
<p>詳細については割愛する。
<a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 2.4.4 については次節で紹介する脆弱性の修正がある。</p>
<h2>【脆弱性】スマートカード生成時に保護されていないバックアップ鍵が PC 上に残る</h2>
<p><a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 2.4.4 より前の一部のバージョンでスマートカード生成時に保護されていないバックアップ鍵が PC 上に残る脆弱性があるらしい。</p>
<figure lang="en">
<blockquote><p>The standard way to generate keys on a smartcard with GnuPG is to create the encryption subkey with gpg and to move this key to the smartcard. A password protected backup file named <code>sk_<keyid>.gpg</code> is also created so that in the case of a lost or broken smartcard, the key can be restored to a new smartcard to allow decryption of existing data. Unfortunately with some versions of GnuPG an additional unprotected copy of the encryption subkey is also kept on disk.</p>
<p>All possibly affected users should check whether such an unintended copy of a smartcard key exists and delete it.</p>
</blockquote>
<figcaption><div>via <q><a href="https://gnupg.org/blog/20240125-smartcard-backup-key.html">Smartcard key generation keeps an unprotected backup key on disk</a></q></div></figcaption>
</figure>
<p>該当するバージョンは以下の通り。</p>
<figure lang="en">
<blockquote><ul>
<li>Gpg4win version 4.2.0</li>
<li>GnuPG versions 2.4.2 and 2.4.3 iff the card generation was done with the command <code>gpg --card-edit</code>.</li>
<li>GnuPG version 2.2.42 iff the card generation was done with the command <code>gpg --card-edit</code>.</li>
<li>GnuPG VS-Desktop version 3.2.0 and 3.2.1 iff the card generation was done with the non-approved command <code>gpg --card-edit</code>. The documented way to create keys on OpenPGP cards and Yubikeys is not affected.</li>
</ul>
</blockquote>
<figcaption><div>via <q><a href="https://gnupg.org/blog/20240125-smartcard-backup-key.html">Smartcard key generation keeps an unprotected backup key on disk</a></q></div></figcaption>
</figure>
<p>確認方法等については以下を参照のこと。</p>
<ul>
<li><a href="https://gnupg.org/blog/20240125-smartcard-backup-key.html">Smartcard key generation keeps an unprotected backup key on disk</a></li>
</ul>
<h2><a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 関連パッケージ</h2>
<p><a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> 関連の各パッケージのバージョンは以下の通り(数字は大体の<a href="https://text.baldanders.info/openpgp/build-gnupg-in-ubuntu/" title="Ubuntu で最新版 GnuPG をビルドする">ビルド</a>順)。</p>
<table>
<thead>
<tr>
<th style="text-align:right">#</th>
<th>パッケージ名</th>
<th>バージョン</th>
<th>公開日</th>
<th style="text-align:center">更新</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:right">1</td>
<td><a href="https://gnupg.org/software/libgpg-error/">Libgpg-error</a></td>
<td>1.48</td>
<td>2024-02-23</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">2</td>
<td><a href="https://gnupg.org/software/libgcrypt/">Libgcrypt</a></td>
<td>1.8.11 (LTS)</td>
<td>2023-11-16</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right"></td>
<td><a href="https://gnupg.org/software/libgcrypt/">Libgcrypt</a></td>
<td>1.10.3</td>
<td>2023-11-14</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">3</td>
<td><a href="https://gnupg.org/software/libassuan/">Libassuan</a></td>
<td>2.5.7</td>
<td>2024-03-06</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">4</td>
<td><a href="https://gnupg.org/software/libksba/">Libksba</a></td>
<td>1.6.6</td>
<td>2024-02-23</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">5</td>
<td><a href="https://gnupg.org/software/npth/">nPth</a></td>
<td>1.7</td>
<td>2024-02-23</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">6</td>
<td><a href="https://gnupg.org/software/ntbtls/">ntbTLS</a></td>
<td>0.3.2</td>
<td>2024-01-12</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
<tr>
<td style="text-align:right">7</td>
<td><a href="https://gnupg.org/software/">GnuPG</a></td>
<td>2.4.5</td>
<td>2024-03-07</td>
<td style="text-align:center"><span><i class="fa-solid fa-check"></i></span></td>
</tr>
</tbody>
</table>
<p>ありゃ。
2.2 系のコードが一覧から消えてるな。</p>
<p>現在 <a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> には 2.2 系と 2.4 系があり<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, 2.4 系では AEAD (Authenticated Encryption with Associated Data) 等 <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-rfc4880bis/" title="draft-ietf-openpgp-rfc4880bis - OpenPGP Message Format">RFC 4880bis</a> で検討されている機能が実装されている。
2.2 系は 2.4 系のサブセットという位置づけで,少なくとも2024年末まではサポートが続けられる予定である。</p>
<p>別記事でも書いたが,どうも <a href="https://www.ubuntu.com/" title="The leading operating system for PCs, IoT devices, servers and the cloud | Ubuntu">Ubuntu</a> は真面目に <a href="https://gnupg.org/" title="The GNU Privacy Guard">GnuPG</a> のメンテナンスをやる気がないようである。
なので,自前でビルドを行おうかと考えているが,遅々として進まず…</p>
<ul>
<li><a href="https://www.procustodibus.com/blog/2023/02/gpg-2-4-on-ubuntu-22-04/">Installing GnuPG 2.4 on Ubuntu 22.04 | Pro Custodibus</a></li>
</ul>
<h2>ブックマーク</h2>
<ul>
<li>
<p><a href="https://github.com/iquiw/pinentry-w32-ncg-binary">iquiw/pinentry-w32-ncg-binary: pinentry-w32, no characters garbled</a></p>
</li>
<li>
<p><a href="https://gnupg.org/blog/20230321-adsk.html">ADSK: The Additional Decryption Subkey</a></p>
</li>
<li>
<p><a href="https://text.baldanders.info/openpgp/">OpenPGP の実装</a></p>
</li>
</ul>
<h2>参考図書</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4314009071?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51ZRZ62WKCL._SL160_.jpg" width="108" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4314009071?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号化 プライバシーを救った反乱者たち</a></dt>
<dd>スティーブン・レビー (著), 斉藤 隆央 (翻訳)</dd>
<dd>紀伊國屋書店 2002-02-16</dd>
<dd>単行本</dd>
<dd>4314009071 (ASIN), 9784314009072 (EAN), 4314009071 (ISBN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">20世紀末,暗号技術の世界で何があったのか。知りたかったらこちらを読むべし!</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-03-09">2015-03-09</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号化 プライバシーを救った反乱者たち -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51t6yHHVwEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門 第3版 秘密の国のアリス</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2015-08-25 (Release 2015-09-17)</dd>
<dd>Kindle版</dd>
<dd>B015643CPE (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-09-20">2015-09-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号技術入門 第3版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CW1DZS1W?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41pm5BJKQwL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CW1DZS1W?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">科学2024年3月号[雑誌]</a></dt>
<dd>岩波書店『科学』編集部 (編集)</dd>
<dd>岩波書店 2024-02-22 (Release 2024-03-01)</dd>
<dd>Kindle版</dd>
<dd>B0CW1DZS1W (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">この号の特集は「現代暗号の展開と応用」。耐量子計算機暗号や格子暗号といった今どきなキーワードも出てくる。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-01">2024-03-01</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 岩波「科学」2024年3月号 現代暗号の展開と応用 -->
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>厳密には1.4系もあるが,これは legacy 版と位置付けられており,よほどのバグか脆弱性がない限りは更新されない。もし今だに1.4系(あるいは既にサポートされていない2.0/2.1系)を使っているのなら2.4系以降にアップグレードすることを強くお勧めする。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
Java 22 がリリースされた(21 LTS 版についても遅まきながら)
tag:text.Baldanders.info,2024-03-20:/release/2024/03/java-21-22-are-released/
2024-03-20T01:00:51+00:00
2024-03-21T10:25:28+00:00
Java 22 は 2024-09 までの短期サポート版。 Java 21 は 2028-09 までの LTS 版
Spiegel
https://baldanders.info/profile/
<p>仕事の忙しさにかまけて色々と放っぽり出してたので,少しずつ回復中。</p>
<p>かーなり遅まきながらであるが,昨年(2023年)9月に Java 21 がリリースされている。
また今月(2024-03)に予定通り Java 22 もリリースされた。</p>
<ul>
<li><a href="https://jdk.java.net/21/">OpenJDK JDK 21.0.2 GA Release</a></li>
<li><a href="https://jdk.java.net/21/release-notes">JDK 21.0.2 Release Notes</a>
<ul>
<li><a href="https://openjdk.org/groups/vulnerability/advisories/2023-10-17">OpenJDK Vulnerability Advisory: 2023/10/17</a></li>
<li><a href="https://openjdk.org/groups/vulnerability/advisories/2024-01-16">OpenJDK Vulnerability Advisory: 2024/01/16</a></li>
</ul>
</li>
<li><a href="https://jdk.java.net/22/">OpenJDK JDK 22 GA Release</a></li>
<li><a href="https://jdk.java.net/22/release-notes">JDK 22 Release Notes</a></li>
</ul>
<p>Java 21 は LTS 版で 2028-09 までのサポートとなる。
既に2回のセキュリティ・アップデートが行われているけど,内容については割愛する。</p>
<p><a href="http://openjdk.java.net/">OpenJDK</a> を APT で管理するメリットはないので,実行バイナリを<a href="https://jdk.java.net/20/">リリースページ</a>から直接ダウンロードして配置する。
以下は完全手動でインストールした場合(笑)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ cd /usr/local/src
</span></span><span class="line"><span class="cl">$ sudo curl -L "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz" -O
</span></span><span class="line"><span class="cl">$ cd ..
</span></span><span class="line"><span class="cl">$ sudo unlink java # 以前のバージョンの Java 環境がある場合
</span></span><span class="line"><span class="cl">$ sudo tar xvf src/openjdk-21.0.2_linux-x64_bin.tar.gz
</span></span><span class="line"><span class="cl">$ sudo ln -s jdk-21.0.2 java
</span></span><span class="line"><span class="cl">$ java -version # すでに PATH が通っている場合
</span></span><span class="line"><span class="cl">openjdk version "21.0.2" 2024-01-16
</span></span><span class="line"><span class="cl">OpenJDK Runtime Environment (build 21.0.2+13-58)
</span></span><span class="line"><span class="cl">OpenJDK 64-Bit Server VM (build 21.0.2+13-58, mixed mode, sharing)
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ cd /usr/local/src
</span></span><span class="line"><span class="cl">$ sudo curl -L "https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_linux-x64_bin.tar.gz" -O
</span></span><span class="line"><span class="cl">$ cd ..
</span></span><span class="line"><span class="cl">$ sudo unlink java # 以前のバージョンの Java 環境がある場合
</span></span><span class="line"><span class="cl">$ sudo tar xvf src/openjdk-22_linux-x64_bin.tar.gz
</span></span><span class="line"><span class="cl">$ sudo ln -s jdk-22 java
</span></span><span class="line"><span class="cl">$ java -version # すでに PATH が通っている場合
</span></span><span class="line"><span class="cl">openjdk version "22" 2024-03-19
</span></span><span class="line"><span class="cl">OpenJDK Runtime Environment (build 22+36-2370)
</span></span><span class="line"><span class="cl">OpenJDK 64-Bit Server VM (build 22+36-2370, mixed mode, sharing)
</span></span></code></pre></div><p>私としては <a href="http://plantuml.com/" title="Open-source tool that uses simple textual descriptions to draw UML diagrams.">PlantUML</a> が動けばいいので,試しておく<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。</p>
<figure style='margin:0 auto;text-align:center;'><a href="./factory-method-pattern.puml"><img src="./factory-method-pattern.png" srcset="./factory-method-pattern.png 1160w" sizes="(min-width:600px) 500px, 80vw" alt="Factory Method Pattern" loading="lazy"></a><figcaption><div><a href="./factory-method-pattern.puml">Factory Method Pattern</a></div></figcaption>
</figure>
<p>よーし,うむうむ,よーし。</p>
<h2>Oracle Java のサポート期間</h2>
<p>“<a href="https://www.oracle.com/java/technologies/java-se-support-roadmap.html">Oracle Java SE Support Roadmap</a>” より。</p>
<table>
<thead>
<tr>
<th>Release</th>
<th>GA Date</th>
<th>Premier Support</th>
<th>Extended Support</th>
</tr>
</thead>
<tbody>
<tr>
<td>17 (LTS)</td>
<td>2021-09</td>
<td>2026-09</td>
<td>2029-09</td>
</tr>
<tr>
<td>21 (LTS)</td>
<td>2023-09</td>
<td>2028-09</td>
<td>2031-09</td>
</tr>
<tr>
<td>22</td>
<td>2024-03</td>
<td>2024-09</td>
<td></td>
</tr>
<tr>
<td>23</td>
<td>2024-09</td>
<td>2025-03</td>
<td></td>
</tr>
<tr>
<td>24</td>
<td>2025-03</td>
<td>2025-09</td>
<td></td>
</tr>
<tr>
<td>25 (LTS)</td>
<td>2025-09</td>
<td>2030-09</td>
<td>2033-09</td>
</tr>
</tbody>
</table>
<p>2024-03 時点で Premier Support が終了しているものは除いている。
いまだ需要のある Java 8 については <a href="https://adoptium.net/">Adoptium</a> などで最新バイナリを取得可能。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="https://gihyo.jp/article/2024/03/java22">Java 22リリース――Project AmberやProject PanamaのスタンダードJEPを含め12のJEPsがアップデート。そして、2025年のJavaOneがベイエリアで開催 | gihyo.jp</a></li>
</ul>
<h2>参考図書</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B07CKHR8C1?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/4143qCJap5L._SL160_.jpg" width="123" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B07CKHR8C1?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Spring Data JPAプログラミング入門</a></dt>
<dd>溝口賢司 (著)</dd>
<dd>秀和システム 2017-08-03 (Release 2018-04-23)</dd>
<dd>Kindle版</dd>
<dd>B07CKHR8C1 (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">JPA のお勉強用に購入。紙のほうはプレミアが付いてるっぽいが Kindle で買えるよ。固定レイアウトだからブラウザの Kindle Cloud Reader で読めるし。真面目に基本を押さえて書いていて分かりやすい。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2021-08-26">2021-08-26</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Spring Data JPAプログラミング入門 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4621303252?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41WZElZb9eL._SL160_.jpg" width="128" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4621303252?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Effective Java 第3版</a></dt>
<dd>Joshua Bloch (著), 柴田 芳樹 (翻訳)</dd>
<dd>丸善出版 2018-10-30</dd>
<dd>単行本(ソフトカバー)</dd>
<dd>4621303252 (ASIN), 9784621303252 (EAN), 4621303252 (ISBN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">再勉強中。 Kindle 版のほうがちょっと安いが,勤務先でも使いたかったので紙の本にした。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2021-03-17">2021-03-17</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Effective Java 第3版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0893LQ5KY?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51VWsWP87dL._SL160_.jpg" width="100" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0893LQ5KY?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Spring Boot 2 入門: 基礎から実演まで</a></dt>
<dd>原田 けいと (著), 竹田 甘地 (著), Robert Segawa (著)</dd>
<dd> 2020-05-22 (Release 2020-05-22)</dd>
<dd>Kindle版</dd>
<dd>B0893LQ5KY (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">Spring Boot を勉強することになって急遽買った本。めっさ分かりやすかった。 PDF 版が欲しいくらい(笑) Spring Boot 3.2 対応にアップデートされていた。素敵!</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-20">2024-03-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Spring Boot 2 入門 -->
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>2024-02-16 に <a href="http://plantuml.com/" title="Open-source tool that uses simple textual descriptions to draw UML diagrams.">PlantUML</a> <a href="https://github.com/plantuml/plantuml/releases/tag/v1.2024.3">1.2024.3</a> が<a href="http://plantuml.com/changes">リリース</a>されている。 <a href="http://plantuml.com/" title="Open-source tool that uses simple textual descriptions to draw UML diagrams.">PlantUML</a> の使い方等については拙文「<a href="https://text.baldanders.info/remark/2018/12/plantuml-1/">真面目に PlantUML</a>」シリーズを参考にどうぞ。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
不自由な ICOCA
tag:text.Baldanders.info,2024-03-17:/remark/2024/03/icoca-for-persons-with-disabilities/
2024-03-17T10:18:49+00:00
2024-03-17T10:19:01+00:00
本当にバスカードの代替でしかないんだな。
Spiegel
https://baldanders.info/profile/
<p>松江市内の路線バス料金は(現金以外は)長いことペラペラのバスカードでの決済だったのだが,2021年から ICOCA が導入され始め,昨年(2023年)には高齢者割引も ICOCA 決済が既定になった。
ただ身障者については対応が遅れていて,今月に入ってようやく身障者用 ICOCA が配布された。
バスカード全面廃止期限(2024年3月末)に間に合わないかと思ったよ。</p>
<figure style='margin:0 auto;text-align:center;'><a href="./ICOCA.jpg"><img src="./ICOCA.jpg" srcset="./ICOCA.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="身障者用 ICOCA 来た!" loading="lazy"></a><figcaption><div><a href="./ICOCA.jpg">身障者用 ICOCA 来た!</a></div></figcaption>
</figure>
<p>見た目は普通の ICOCA カードなのだが,どうも市内路線バスにしか使えないっぽい。
モバイル ICOCA にもできないし,チャージもするなと同封の説明書に書いてあった。
本当にバスカードの代替でしかないんだな。
まぁええけど。
どう考えても身障者用 ICOCA はイレギュラー運用だろうし,この辺が精一杯なんだろう。</p>
<p>なんで今頃こんな話をしているかというと,今日は自転車じゃなくてバス移動だったのよ。
天気予報が「午後からにわか雨が降るかも」などと脅してくるもんで(笑) 結局,にわか雨どころか,午後から晴れてきたけどね。
身障者用 ICOCA がちゃんと機能するか試してみるまでドキドキだったよ。</p>
<p>用事の合間に城山公園に登ってみる。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53592850205/"><img src="./53592850205_d948458ef6_e.jpg" srcset="./53592850205_d948458ef6_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="今日の松江城 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53592850205/">今日の松江城 | Flickr</a></div></figcaption>
</figure>
<p>そういや,月末に花見をするとか言ってたな。
今はどんな感じかな。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53592849435/"><img src="./53592849435_ae92e77bda_e.jpg" srcset="./53592849435_ae92e77bda_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="もうすぐ開花(松江城) | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53592849435/">もうすぐ開花(松江城) | Flickr</a></div></figcaption>
</figure>
<p>おー。
かなり蕾が膨らんでる木があるな。
今年の予想通り,来週末に開花宣言で,月末頃に満開って感じだろうか。</p>
<p>楽しみなことである。</p>
<h2>参考</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B08L4WKDZ7?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41MZe0XgHdL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B08L4WKDZ7?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Canon コンパクトデジタルカメラ PowerShot ZOOM 写真と動画が撮れる望遠鏡 PSZOOM</a></dt>
<dd>キヤノン (Release 2020-12-10)</dd>
<dd>エレクトロニクス</dd>
<dd>B08L4WKDZ7 (ASIN), 4549292179675 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">望遠鏡型コンパクトデジカメ。メモリと充電器(要 Power Delivery)は別に用意する必要がある。使い勝手はまぁまぁ。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2022-12-04">2022-12-04</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- PowerShot ZOOM -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51au0wo+jpL._SL160_.jpg" width="112" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">群論への第一歩 集合、写像から準同型定理まで</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2024-03-02 (Release 2024-03-02)</dd>
<dd>Kindle版</dd>
<dd>B0CR18XWZW (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">タイトルにあるように「群論」へ至る道を指し示す良書。学生時代に読みたかった orz</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-02">2024-03-02</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 群論への第一歩 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CKGZ68P9?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51HYEz55zlL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CKGZ68P9?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">LETTER☆彡</a></dt>
<dd>白上フブキ (メインアーティスト)</dd>
<dd>cover corp. (Release 2023-10-06)</dd>
<dd>MP3 ダウンロード</dd>
<dd>B0CKGZ68P9 (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description"><a href="https://www.youtube.com/watch?v=LEeFwC4wvpI">100万再生突破</a>おめでとう。正しくアイドル曲で可愛らしい曲。 mora で<a href="https://mora.jp/package/43000066/PA00124218-0-2/">高解像度版</a>が買える。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-13">2024-03-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 白上フブキ LETTER☆彡 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B008BR7OM6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/614099rA2HL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B008BR7OM6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">アニソン・コレクションVol.1</a></dt>
<dd>永井ルイ (アーティスト)</dd>
<dd>ストレンジ・デイズ 2012-07-13 (Release 2012-07-14)</dd>
<dd>CD</dd>
<dd>B008BR7OM6 (ASIN), 4562392610015 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">アニメ「THE ビッグオー」のOP曲「BIG-O! Show Must Go On」が収録されてるというので衝動買い。他にあの名曲「乙女のポリシー」とかもある。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-13">2024-03-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 永井ルイ ビッグオー BIG-O!Show Must Go On -->
お散歩カメラ 2024-04-16
tag:text.Baldanders.info,2024-03-16:/remark/2024/03/16-osanpo-camera/
2024-03-16T13:25:09+00:00
2024-03-17T10:19:01+00:00
冬インナーを脱ごう / 玉造温泉に行こう / 史跡出雲玉作跡 / 昼飯→定点観測 / 今日の宍道湖(夕景)
Spiegel
https://baldanders.info/profile/
<h2>冬インナーを脱ごう</h2>
<p>松江はここのところ晴天続きで,朝方は放射冷却でそこそこ寒いが,昼間は結構暖かい。
今日の最高気温なんて20℃超えですやん。</p>
<p>というわけで,いよいよ<a href="https://text.baldanders.info/remark/2023/11/base-layer-for-winter/" title="冬用インナー(Base Layer)買うた">冬用インナー</a>を脱ぐときが来た。</p>
<p>冬の間は大変お世話になりました <abbr class="emoji-chars" title="ペコン">🙇</abbr> お陰様で真冬に凍えることもなく快適なサイクリングを楽しめた。
唯一のミスは,<a href="https://text.baldanders.info/remark/2023/11/base-layer-for-winter/" title="冬用インナー(Base Layer)買うた">買った</a>当時はお腹周りに少し贅肉が残ってたので,ワンサイズ上を選択したのだが,冬の間に服が伸びたのか私が痩せたのか,ただの長Tになっちゃって(笑) 次の冬までには買い直さなきゃ。
ちなみに下半身は適正サイズを買ってたので冬の間ほどよい締めつけ感でいい感じに過ごせた。</p>
<h2>玉造温泉に行こう</h2>
<p>暖かくなったら行こうと思ってたところがあるのですよ。
<a href="https://www.tama-yuuyu.com/" title="玉造温泉ゆ~ゆ|島根県松江市玉湯町">玉造温泉ゆ~ゆ</a>。
うちの親も日帰りで気軽に行ける温泉施設と言ってたので気にはなっていたのだが,松江市内からだと宍道湖沿いを通るか<ruby><rb>布志名</rb><rp> (</rp><rt>ふじな</rt><rp>) </rp></ruby>峠を越えるかしないといけないのね。
宍道湖沿いの9号線は車の量が多くて自転車に優しくないエリアがあるのでパス。
んで,布志名峠って確かアップダウンが結構あったよなぁ,と忌避していたのだ。</p>
<p>まぁ,でも,<a href="https://www.kumanokan.jp/" title="八雲温泉ゆうあい熊野館">八雲温泉</a>行くよりは近いし,布志名峠コースを挑戦してみるか,となった。
コースは<a href="https://text.baldanders.info/remark/2023/07/cyclocomputer/" title="サイクルコンピュータ買うた(お散歩カメラ 2023-07-29)">ナビ先生</a>におまかせ。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590508713/"><img src="./53590508713_701fd4ce07_e.jpg" srcset="./53590508713_701fd4ce07_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="玉造温泉へGo | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590508713/">玉造温泉へGo | Flickr</a></div></figcaption>
</figure>
<p>まずは松江バイパスの側道を西進する。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590510198/"><img src="./53590510198_d92435452d_e.jpg" srcset="./53590510198_d92435452d_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="乃木二子塚古墳 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590510198/">乃木二子塚古墳 | Flickr</a></div></figcaption>
</figure>
<p><a href="https://maps.app.goo.gl/2fR7ruLZhfGJ2gDF7">乃木二子塚古墳</a>は個人的に松江バイパスの側道を通るときのランドマークにしている。
ここから西に向かい,浜乃木湯町線(県道263)に入る。</p>
<p>おっと,トンネル。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53589432917/"><img src="./53589432917_26d047e6d6_e.jpg" srcset="./53589432917_26d047e6d6_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="仙石トンネル | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53589432917/">仙石トンネル | Flickr</a></div></figcaption>
</figure>
<p>トンネル2つ目。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53589434052/"><img src="./53589434052_18fb80d5da_e.jpg" srcset="./53589434052_18fb80d5da_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="花仙トンネル | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53589434052/">花仙トンネル | Flickr</a></div></figcaption>
</figure>
<p>ぐはっ。
左車線は歩道がない。
流石にトンネルの車道を自転車で通りたくないので反対車線に渡らなきゃ。</p>
<p>で,ここまで来て気がついた。
あれ? 布志名峠は? そうか。
布志名峠って旧道だから今の浜乃木湯町線なら全然楽勝で走れるぢゃん。
ちゃんと調べずに今まで忌避してた私って <code>orz</code></p>
<p>そんなこんなで玉造温泉に到着。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590856535/"><img src="./53590856535_11df4ffe1d_e.jpg" srcset="./53590856535_11df4ffe1d_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="玉湯川 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590856535/">玉湯川 | Flickr</a></div></figcaption>
</figure>
<p>玉造温泉はこんな感じに玉湯川を挟んで温泉旅館が建ち並んでいる。
でも,今回は旅館じゃなくてここ。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590755180/"><img src="./53590755180_358ababda5_e.jpg" srcset="./53590755180_358ababda5_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="玉造温泉ゆ〜ゆ | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590755180/">玉造温泉ゆ〜ゆ | Flickr</a></div></figcaption>
</figure>
<p>自転車を停めるところはないかとキョロキョロしてたら奥の方にあった。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590408776/"><img src="./53590408776_d5604a8745_e.jpg" srcset="./53590408776_d5604a8745_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="玉造温泉ゆ〜ゆ 駐輪場 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590408776/">玉造温泉ゆ〜ゆ 駐輪場 | Flickr</a></div></figcaption>
</figure>
<p>ありがたや。
駐輪場があるなら安心して通えるな。
それにしても温泉むすめ?</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590410416/"><img src="./53590410416_b89635a981_e.jpg" srcset="./53590410416_b89635a981_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="温泉むすめ? | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590410416/">温泉むすめ? | Flickr</a></div></figcaption>
</figure>
<p><a href="https://onsen-musume.jp/" title="温泉むすめ公式サイト">そんなん</a>あるのか。
まぁ,いいや。
気を取り直して…</p>
<p><a href="https://www.tama-yuuyu.com/" title="玉造温泉ゆ~ゆ|島根県松江市玉湯町">玉造温泉ゆ~ゆ</a>は1階が売店,3階が会議室,4階が多目的室,5階が大浴場となっている。
今回の目的は5階の大浴場である。
ちなみに4階も覗いてみたがマッサージ室になっていた。
自由に寛げる空間ならここで読書とか考えていたのだが,無理かな。</p>
<p>初めての場所なので受付の方にシステムを訊く。
ふむふむ。
入浴料は600円(税込),ボディシャンプー等は備え付け,タオルは持参か別途購入,と。
さっそく入浴タイム&湯上がりのコーヒー牛乳。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590629724/"><img src="./53590629724_be0dd69ee3_e.jpg" srcset="./53590629724_be0dd69ee3_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="温泉上がりのコーヒー牛乳 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590629724/">温泉上がりのコーヒー牛乳 | Flickr</a></div></figcaption>
</figure>
<p>やっぱ風呂上がりの一杯は<a href="https://www.kisuki-milk.co.jp/" title="木次乳業">木次乳業</a>のコーヒー牛乳だよね。</p>
<p>折角なので温泉街を少し歩いてみることにした。
あわよくばどっかで昼飯をと考えたが,食堂とか開いてるかよく分からん感じだったのでパスした。
飯を食うなら市内まで戻ったほうがいいな<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。</p>
<h2>史跡出雲玉作跡</h2>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590859675/"><img src="./53590859675_fdd4a44834_e.jpg" srcset="./53590859675_fdd4a44834_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="史跡公園があるのか | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590859675/">史跡公園があるのか | Flickr</a></div></figcaption>
</figure>
<p>おっ,史跡公園があるのか。
登ってみよう。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590425751/"><img src="./53590425751_45095d74ca_e.jpg" srcset="./53590425751_45095d74ca_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="史跡出雲玉作跡 解説 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590425751/">史跡出雲玉作跡 解説 | Flickr</a></div></figcaption>
</figure>
<p>どうやらこの辺りは古代の「玉」の工房があったらしい。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590626213/"><img src="./53590626213_23fcba7486_e.jpg" srcset="./53590626213_23fcba7486_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="玉作工房跡 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590626213/">玉作工房跡 | Flickr</a></div></figcaption>
</figure>
<p>しかし,なんで古代遺跡って丘や山の上にあるのかね。
「馬鹿と煙と権力者は高いところへ上る」ってやつ? 近くに資料館もあったが,丘に登って微妙に疲れたので,今回はパスした。
次回次回。</p>
<h2>昼飯→定点観測</h2>
<p>では市内に戻りますか。
空腹に負けて途中のコメダで昼食。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590871870/"><img src="./53590871870_9c223a1c34_e.jpg" srcset="./53590871870_9c223a1c34_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="コメダで昼食 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590871870/">コメダで昼食 | Flickr</a></div></figcaption>
</figure>
<p>お腹が落ち着いたら,いつもの定点観測。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590926825/"><img src="./53590926825_5575a5aa8d_e.jpg" srcset="./53590926825_5575a5aa8d_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="今日の宍道湖 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590926825/">今日の宍道湖 | Flickr</a></div></figcaption>
</figure>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590486501/"><img src="./53590486501_f406c361d8_e.jpg" srcset="./53590486501_f406c361d8_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="今日の松江城 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590486501/">今日の松江城 | Flickr</a></div></figcaption>
</figure>
<p>今日も快晴ではあったのだが,花粉か黄砂か,春霞。
おかげで松江城から大山は視認できなかった。</p>
<p>松江城のある城山公園は桜のころにお城まつりがあるのだが,着々と準備が進んでいるようだ。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53589612022/"><img src="./53589612022_c7b632b667_e.jpg" srcset="./53589612022_c7b632b667_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="花見の準備OK | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53589612022/">花見の準備OK | Flickr</a></div></figcaption>
</figure>
<p>このあとは<a href="https://www.library.pref.shimane.lg.jp/" title="島根県立図書館">県立図書館</a>やら喫茶店やらで夕方まで読書。</p>
<h2>今日の宍道湖(夕景)</h2>
<p>夕方になったので移動。
まず<a href="https://maps.app.goo.gl/p5CjNcoySbBfARus8">松江大橋</a>から<a href="https://maps.app.goo.gl/tHtD38EUdh52HXRY9">宍道湖大橋</a>越しに夕日を撮ろうと思ったのだが</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53589857442/"><img src="./53589857442_b4c9ca5af5_e.jpg" srcset="./53589857442_b4c9ca5af5_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="宍道湖大橋(夕景) | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53589857442/">宍道湖大橋(夕景) | Flickr</a></div></figcaption>
</figure>
<p>ありゃ,思ったより北寄りだったな。
撮るなら2月末か3月頭にすべきだったか。
まぁ2月末は仕事で死にそうになってたので,どっちみち無理か。
次のチャンスは秋(10月?)だな。</p>
<p>じゃあ,宍道湖に移動するか。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53590732106/"><img src="./53590732106_fc0c65542f_e.jpg" srcset="./53590732106_fc0c65542f_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="今日の宍道湖(夕景) | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53590732106/">今日の宍道湖(夕景) | Flickr</a></div></figcaption>
</figure>
<p>む。
日没は無理だが,夕日はぎりぎり撮れたな。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53591050834/"><img src="./53591050834_b906ba9535_e.jpg" srcset="./53591050834_b906ba9535_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="夕日 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53591050834/">夕日 | Flickr</a></div></figcaption>
</figure>
<p>春霞と低空の薄曇りでいい感じに夕日が撮れました。</p>
<p>これから更に日没時刻が遅くなるので夕日を撮りにくくなるなぁ。
夏至あたりなら仕事帰りにちょっと宍道湖沿いに寄るとかしても面白いかもしれないが。</p>
<p>ほんじゃあ帰りますか。</p>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B08L4WKDZ7?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41MZe0XgHdL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B08L4WKDZ7?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Canon コンパクトデジタルカメラ PowerShot ZOOM 写真と動画が撮れる望遠鏡 PSZOOM</a></dt>
<dd>キヤノン (Release 2020-12-10)</dd>
<dd>エレクトロニクス</dd>
<dd>B08L4WKDZ7 (ASIN), 4549292179675 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">望遠鏡型コンパクトデジカメ。メモリと充電器(要 Power Delivery)は別に用意する必要がある。使い勝手はまぁまぁ。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2022-12-04">2022-12-04</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- PowerShot ZOOM -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0BLNFPWTQ?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41YvUM53eFL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0BLNFPWTQ?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">trimm ROLLIN サイクルコンピュータ GPS 自転車 速度計 ワイヤレス ナビゲーション ANT+センサー対応 Bluetooth 心拍数 高度計 2.7インチ スピードセンサー(device only)</a></dt>
<dd>Trimm</dd>
<dd></dd>
<dd>B0BLNFPWTQ (ASIN), 8809748020286 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">韓国企業だけどモノは made in Chaina って書いてあった。ナビ機能付きで2万円以下というのは安い。スマホアプリと連携させて操作する。モノクロ液晶だがバッテリ消費は少なめ。各種センサーやスマートウォッチと連携可能。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-07-29">2023-07-29</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- trimm ROLLIN サイクルコンピュータ -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51au0wo+jpL._SL160_.jpg" width="112" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">群論への第一歩 集合、写像から準同型定理まで</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2024-03-02 (Release 2024-03-02)</dd>
<dd>Kindle版</dd>
<dd>B0CR18XWZW (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">タイトルにあるように「群論」へ至る道を指し示す良書。学生時代に読みたかった orz</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-02">2024-03-02</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 群論への第一歩 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B005SY3GS6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/317g8kNr-4L._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B005SY3GS6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">おたふく手袋 冬用インナー 長袖 ハイネック [保温 吸汗速乾 コンプレッション メンズ] JW-170 ホワイト L</a></dt>
<dd>おたふく手袋(Otafuku Glove)</dd>
<dd>Tools & Hardware</dd>
<dd>B005SY3GS6 (ASIN), 4970687608683 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">主に通勤で使うので白を選択。カタログで指定されているサイズよりワンサイズ上を着ている。着ている間はそれほどの締めつけ感はないし(スポーツ用なので当たり前だが)動きを阻害しない。寒くない。自転車を漕いでいても,いい感じに汗を排出している感じ。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-11-15">2023-11-15</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- インナー base layer 上 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0044W4MYU?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/31ihKoaN1-L._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0044W4MYU?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">おたふく手袋 冬用インナー ロングタイツ [保温 吸汗速乾 コンプレッション メンズ] JW-162 ブラック M</a></dt>
<dd>おたふく手袋(Otafuku Glove)</dd>
<dd>Tools & Hardware</dd>
<dd>B0044W4MYU (ASIN), 4970687608522 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">主に通勤用に使っている。着ている間はそれほどの締めつけ感はないし(スポーツ用なので当たり前だが)動きを阻害しない。寒くない。自転車を漕いでいても,いい感じに汗を排出している感じ。前とじで「社会の窓」は空いてないので注意。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-11-15">2023-11-15</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- インナー base layer 下 タイツ -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CKGZ68P9?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51HYEz55zlL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CKGZ68P9?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">LETTER☆彡</a></dt>
<dd>白上フブキ (メインアーティスト)</dd>
<dd>cover corp. (Release 2023-10-06)</dd>
<dd>MP3 ダウンロード</dd>
<dd>B0CKGZ68P9 (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description"><a href="https://www.youtube.com/watch?v=LEeFwC4wvpI">100万再生突破</a>おめでとう。正しくアイドル曲で可愛らしい曲。 mora で<a href="https://mora.jp/package/43000066/PA00124218-0-2/">高解像度版</a>が買える。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-13">2024-03-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 白上フブキ LETTER☆彡 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B008BR7OM6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/614099rA2HL._SL160_.jpg" width="160" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B008BR7OM6?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">アニソン・コレクションVol.1</a></dt>
<dd>永井ルイ (アーティスト)</dd>
<dd>ストレンジ・デイズ 2012-07-13 (Release 2012-07-14)</dd>
<dd>CD</dd>
<dd>B008BR7OM6 (ASIN), 4562392610015 (EAN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description">アニメ「THE ビッグオー」のOP曲「BIG-O! Show Must Go On」が収録されてるというので衝動買い。他にあの名曲「乙女のポリシー」とかもある。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-13">2024-03-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 永井ルイ ビッグオー BIG-O!Show Must Go On -->
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>後で親に聞いたら,温泉街の奥の方,玉造温泉行バスの終点の更に奥に食べ物屋さんがあるらしい。次に行く機会があればちょいと寄ってみるか? <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
渡し守 hyuki さんによる『群論への第一歩』
tag:text.Baldanders.info,2024-03-10:/remark/2024/03/first-step-into-group-theory/
2024-03-10T12:02:43+00:00
2024-03-28T23:00:18+00:00
少なくともプログラマ(を目指す)なら群論もしくは群論の考え方は絶対に必要なのよ。
Spiegel
https://baldanders.info/profile/
<p>今朝は放射冷却で氷点下まで下がったけど,よいお天気だったので,いつものように <a href="https://www.kumanokan.jp/" title="八雲温泉ゆうあい熊野館">八雲温泉</a>でひとっ風呂 → 宍道湖・松江城定点観測 → <a href="https://www.library.pref.shimane.lg.jp/" title="島根県立図書館">県立図書館</a>で読書三昧 というコース。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53577137362/"><img src="./53577137362_6db5084321_e.jpg" srcset="./53577137362_6db5084321_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="今日の大山 from 松江城 | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53577137362/">今日の大山 from 松江城 | Flickr</a></div></figcaption>
</figure>
<p>まぁ,この辺は特筆するようなこともなかったのでさらっと流すとして,今回は最近読んでいる本の紹介など。</p>
<h2>群論に至る智慧もしくは彼岸への渡し船</h2>
<p>私は宗教関係者ではなく,うろ覚えで申し訳ないのだが,仏教用語の「般若(prajna)」は「悟りに至る智慧」みたいな意味らしい。
そこから転じて彼岸へ渡る渡し船のようなイメージができ,更に「船」から女性的なイメージができたみたいな話を聞いたことがある(真偽は不明)。</p>
<p>とするなら『<a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1" title="群論への第一歩 集合、写像から準同型定理まで | 結城 浩 | 数学 | Kindleストア | Amazon">群論への第一歩</a>』は群論に至る智慧もしくは彼岸への渡し船と言っていいだろう。
それじゃあ著者の<a href="https://www.hyuki.com/" title="結城浩 / Hiroshi Yuki / The Essence of Programming / プログラミングのエッセンス">結城浩</a>さんは,さしずめ彼岸(=群論)への渡し守かな(笑)</p>
<p>群論で挫折する人の話はたまに聞くが,私も例にもれず学生時代に群論に挫折した口でして。
いや「丸覚え」するなら単位は取れるのよ。
でもそれじゃあ理解したって言えないぢゃん。
それに暗記が壊滅的に苦手な私では,丸覚えしてもすぐ忘れるし。</p>
<p>まだ巡回群あたりを読んでいるところなのだが,この本を読んだ最初の感想は「学生時代に読みたかった <code>orz</code>」である。
これって書籍版の「<a href="https://www.hyuki.com/pub/books#girl">数学ガール</a>」シリーズを読んだときにも思ったな。</p>
<p>授業で習う群論の何が難しいって,それまで刷り込まれた「読み書き算盤」をベースにした古典数学からのギャップを感じるからなんだよね。
んで「慣れる」前に授業としては終わってしまったりするの。
そして「日常生活で使うわけじゃないし,いっかぁ」みたいな感じで諦める。</p>
<p>でもね。
少なくともプログラマ(を目指す)なら群論もしくは群論の考え方は絶対に必要なのよ。
何故ならプログラミングは論理のコード化だから。
これは,この業界に入って歳をとるほどに痛切に感じるようになった。</p>
<p>何より(数学を含めた)理学とは「真理の探求」であり,それを駆動する好奇心こそが人たらしめるのよ。</p>
<figure>
<blockquote>
<q>理学は、真理の探究であり、工学は善の実現である。そして、藝術は美の表現である--これで所謂「真美善」が揃う</q>
</blockquote>
<figcaption><div><q><a href="https://www.amazon.co.jp/dp/4344980158?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">はやぶさ―不死身の探査機と宇宙研の物語</a></q>より</div></figcaption>
</figure>
<h2>読んでる途中なのに読書感想文</h2>
<p>というわけで『<a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1" title="群論への第一歩 集合、写像から準同型定理まで | 結城 浩 | 数学 | Kindleストア | Amazon">群論への第一歩</a>』の感想文。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://www.flickr.com/photos/spiegel/53562362934/"><img src="./53562362934_25f491f454_e.jpg" srcset="./53562362934_25f491f454_e.jpg 500w" sizes="(min-width:600px) 500px, 80vw" alt="『群論への第一歩』配信されてた | Flickr" loading="lazy"></a><figcaption><div><a href="https://www.flickr.com/photos/spiegel/53562362934/">『群論への第一歩』配信されてた | Flickr</a></div></figcaption>
</figure>
<p>ラノベ・漫画や軽い読み物ならともかく,こういう真面目な本は自宅だと(他に目移りするものが沢山あるので)なかなか読み進められないのね。
なので,週末の図書館の学習室とかでチマチマと読んでたりする。</p>
<p>前述したように群論に「慣れる」には,如何にして「読み書き算盤」の此岸からスムーズに渡って行けるかにかかっている。
その点で『<a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1" title="群論への第一歩 集合、写像から準同型定理まで | 結城 浩 | 数学 | Kindleストア | Amazon">群論への第一歩</a>』は抜群に上手いと思う。</p>
<p>他の『<a href="https://www.amazon.co.jp/dp/B079JLW5YN?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">プログラマの数学</a>』や『<a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門</a>』にはなかったと思うんだけど「ちょっと一言」というミニコラムみたいなものがかなりの頻度で(しかも煩くない程度に)差し込まれているのね。
ミニコラムというか著者によるミニブログみたいな感じ。
こういうのって今風だなぁと思ったのだが,どうだろう。</p>
<p>あと,<a href="https://www.hyuki.com/" title="結城浩 / Hiroshi Yuki / The Essence of Programming / プログラミングのエッセンス">結城浩</a>さんの他の著書と同じく,この本でも章ごとに演習問題(と解答&解説)が載ってるんだけど,演習だからとうっかり読み飛ばしたりすると,後の章に</p>
<figure>
<blockquote><ul>
<li><strong>なぜ</strong>、 $(S_3,\circ)$ が <span class="box"> G1 </span> を満たすといえるのですか<br>
<strong>なぜなら</strong>、写像の合成は結合律を満たすからです(p. 59 の問題 2-3)。</li>
</ul>
</blockquote>
<figcaption><div><q><a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">『群論への第一歩』p.76</a></q>より</div></figcaption>
</figure>
<p>とか書いてあって「おぅふ」となり慌ててページを戻ったり。
実に<del>鬼畜</del>上手い。
まぁ,これで演習問題も丁寧に読もうという気になるんだけどね。</p>
<p>これを読めば富士山の5合目くらいの高さまでは行けるだろうか。
仕事と違って締切はないので,ゆっくり読み込んでいくことにしよう。</p>
<h2>参考</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51au0wo+jpL._SL160_.jpg" width="112" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CR18XWZW?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">群論への第一歩 集合、写像から準同型定理まで</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2024-03-02 (Release 2024-03-02)</dd>
<dd>Kindle版</dd>
<dd>B0CR18XWZW (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">タイトルにあるように「群論」へ至る道を指し示す良書。学生時代に読みたかった orz</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-02">2024-03-02</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 群論への第一歩 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B079JLW5YN?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51QDhrqqEtL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B079JLW5YN?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">プログラマの数学 第2版</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2018-01-16 (Release 2018-02-08)</dd>
<dd>Kindle版</dd>
<dd>B079JLW5YN (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">タイトル通りプログラマ必読書。第2版では機械学習に関する章が付録に追加された。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2018-03-19">2018-03-19</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- プログラマの数学 第2版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51t6yHHVwEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門 第3版 秘密の国のアリス</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2015-08-25 (Release 2015-09-17)</dd>
<dd>Kindle版</dd>
<dd>B015643CPE (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-09-20">2015-09-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号技術入門 第3版 -->
github.com/goark/mt/v2 をリリースした
tag:text.Baldanders.info,2024-03-09:/release/2024/03/goark-mt-v2/
2024-03-09T11:45:42+00:00
2024-03-09T11:45:46+00:00
Mersenne Twister 疑似乱数生成器を実装した拙作のパッケージを math/rand/v2 に対応することにした
Spiegel
https://baldanders.info/profile/
<p><a href="https://go.dev/">Go</a> 1.22 で <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand - pkg.go.dev"><code>math/rand/v2</code></a> パッケージが登場したため, <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.html" title="Mersenne Twister: A random number generator (since 1997/10)">Mersenne Twister</a> 疑似乱数生成器を実装した拙作の <a href="https://github.com/goark/mt" title="goark/mt: Mersenne Twister; Pseudo Random Number Generator, Implemented by Golang"><code>github.com/goark/mt</code></a> パッケージも <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand - pkg.go.dev"><code>math/rand/v2</code></a> に対応することにした。</p>
<p>まずはバージョンを v2 に上げて,以下のインポート・パスに変更した。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span> <span class="s">"github.com/goark/mt/v2"</span>
</span></span></code></pre></div><p>また <code>go.mod</code> も同様に</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">require github.com/goark/mt/v2 v2.0.1
</span></span></code></pre></div><p>とする。</p>
<p>例として <a href="https://github.com/goark/mt" title="goark/mt: Mersenne Twister; Pseudo Random Number Generator, Implemented by Golang"><code>github.com/goark/mt/v2</code></a> パッケージと <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand - pkg.go.dev"><code>math/rand/v2</code></a> パッケージを組み合わせて標準正規分布する値を1万個生成してみる。
こんな感じ。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"fmt"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"math"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"math/rand/v2"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="s">"github.com/goark/mt/v2/mt19937"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">rnd</span> <span class="o">:=</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">mt19937</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nf">Int64</span><span class="p">()))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">points</span> <span class="o">:=</span> <span class="p">[]</span><span class="kt">float64</span><span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">max</span> <span class="o">:=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl"> <span class="nx">min</span> <span class="o">:=</span> <span class="mf">1.0</span>
</span></span><span class="line"><span class="cl"> <span class="nx">sum</span> <span class="o">:=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="k">range</span> <span class="mi">10000</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">point</span> <span class="o">:=</span> <span class="nx">rnd</span><span class="p">.</span><span class="nf">NormFloat64</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">points</span> <span class="p">=</span> <span class="nb">append</span><span class="p">(</span><span class="nx">points</span><span class="p">,</span> <span class="nx">point</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">min</span> <span class="p">=</span> <span class="nx">math</span><span class="p">.</span><span class="nf">Min</span><span class="p">(</span><span class="nx">min</span><span class="p">,</span> <span class="nx">point</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">max</span> <span class="p">=</span> <span class="nx">math</span><span class="p">.</span><span class="nf">Max</span><span class="p">(</span><span class="nx">max</span><span class="p">,</span> <span class="nx">point</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">sum</span> <span class="o">+=</span> <span class="nx">point</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">n</span> <span class="o">:=</span> <span class="nb">float64</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nx">points</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">ave</span> <span class="o">:=</span> <span class="nx">sum</span> <span class="o">/</span> <span class="nx">n</span>
</span></span><span class="line"><span class="cl"> <span class="nx">d2</span> <span class="o">:=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">p</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">points</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">d2</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">p</span> <span class="o">-</span> <span class="nx">ave</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="nx">p</span> <span class="o">-</span> <span class="nx">ave</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">" minimum: "</span><span class="p">,</span> <span class="nx">min</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">" maximum: "</span><span class="p">,</span> <span class="nx">max</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">" average: "</span><span class="p">,</span> <span class="nx">ave</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"standard deviation: "</span><span class="p">,</span> <span class="nx">math</span><span class="p">.</span><span class="nf">Sqrt</span><span class="p">(</span><span class="nx">d2</span><span class="o">/</span><span class="nx">n</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>これを実行するとこんな感じになる。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$ go run sample.go
</span></span><span class="line"><span class="cl"> minimum: -4.465497509270884
</span></span><span class="line"><span class="cl"> maximum: 4.409945906326592
</span></span><span class="line"><span class="cl"> average: 0.010399867661332784
</span></span><span class="line"><span class="cl">standard deviation: 1.0027323703801945
</span></span></code></pre></div><p>まぁまぁ妥当な感じ?</p>
<p><a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> および <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand - pkg.go.dev"><code>math/rand/v2</code></a> パッケージのトップレベル関数群の疑似乱数生成器が ChaCha8 になったおかげで seed を与えるのがめっちゃ楽になった。
これだけでもありがたい。
ともかくこれで,乱数生成周りの調査と対応は一通り完了かな。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="https://text.baldanders.info/release/mersenne-twister-by-golang/">疑似乱数生成器 goark/mt</a></li>
<li><a href="https://text.baldanders.info/golang/pseudo-random-number-generator-v2/">Go 1.22 における疑似乱数生成器</a></li>
<li><a href="https://zenn.dev/spiegel/articles/20240309-golang-math-rand-v2">Go 1.22 の math/rand/v2 を使ってみる</a></li>
</ul>
<h2>参考図書</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B099928SJD?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/416Stewy0NS._SL160_.jpg" width="123" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B099928SJD?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">プログラミング言語Go</a></dt>
<dd>アラン・ドノバン (著), ブライアン・カーニハン (著), 柴田芳樹 (著)</dd>
<dd>丸善出版 2016-06-20 (Release 2021-07-13)</dd>
<dd>Kindle版</dd>
<dd>B099928SJD (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">Kindle 版出た! 一部内容が古びてしまったが,この本は Go 言語の教科書と言ってもいいだろう。感想は<a href="https://text.baldanders.info/remark/2016/07/go-programming-language/" >こちら</a>。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2021-05-22">2021-05-22</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- プログラミング言語Go -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CFL1DK8Q?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51BmDUG6D0L._SL160_.jpg" width="125" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CFL1DK8Q?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Go言語 100Tips ありがちなミスを把握し、実装を最適化する impress top gearシリーズ</a></dt>
<dd>Teiva Harsanyi (著), 柴田 芳樹 (著)</dd>
<dd>インプレス 2023-08-18 (Release 2023-08-18)</dd>
<dd>Kindle版</dd>
<dd>B0CFL1DK8Q (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description"><a href="https://book.impress.co.jp/books/1122101133">版元</a>で PDF 版を購入可能。事実上の Effective Go とも言える充実の内容。オリジナルは敢えてタイトルに “tips” という単語を入れるのを避けたのに邦題が「100 Tips」とかなっていて,原作者がお怒りとの噂(あくまで噂)</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-08-18">2023-08-18</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Go言語 100Tips -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4814400535?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41+ew2wl2jL._SL160_.jpg" width="125" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4814400535?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">効率的なGo ―データ指向によるGoアプリケーションの性能最適化</a></dt>
<dd>Bartłomiej Płotka (著), 山口 能迪 (翻訳)</dd>
<dd>オライリー・ジャパン 2024-02-24</dd>
<dd>単行本(ソフトカバー)</dd>
<dd>4814400535 (ASIN), 9784814400539 (EAN), 4814400535 (ISBN)</dd>
</dl>
<p class="description">ついに Effective Go のタイトルを冠した本の邦訳が出た。<a href="https://www.oreilly.co.jp/books/9784814400539/">版元</a>で Ebook を買える。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-02-22">2024-02-22</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 効率的なGo : Effective Go -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51t6yHHVwEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門 第3版 秘密の国のアリス</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2015-08-25 (Release 2015-09-17)</dd>
<dd>Kindle版</dd>
<dd>B015643CPE (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-09-20">2015-09-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号技術入門 第3版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B00I8AT1FO?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41353H+BzFL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B00I8AT1FO?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">数学ガール/乱択アルゴリズム</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2011-02-25 (Release 2014-03-12)</dd>
<dd>Kindle版</dd>
<dd>B00I8AT1FO (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">工学ガール,リサちゃん登場!</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-04-19">2015-04-19</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 数学ガール/乱択アルゴリズム -->
Go 1.22 における疑似乱数生成器
tag:text.Baldanders.info,2024-03-07:/golang/pseudo-random-number-generator-v2/
2024-03-07T13:20:40+00:00
2024-03-09T06:48:01+00:00
時代は math/rand/v2 かな
Spiegel
https://baldanders.info/profile/
<p><a href="https://go.dev/">Go</a> 1.22 の <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> パッケージと追加された <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> パッケージを眺めている。</p>
<p>おそらく <a href="https://go.dev/">Go</a> 1.22 における疑似乱数関連の最大のトピックは ChaCha8 がランタイムに組み込まれ,疑似乱数生成器の既定アルゴリズムになったことだろう。</p>
<ul>
<li><span><a href="https://cr.yp.to/snuffle/salsafamily-20071225.pdf">The Salsa20 family of stream ciphers <sup><i class="far fa-file-pdf"></i></sup></a></span> : これがベースになる論文かな</li>
<li><a href="https://en.wikipedia.org/wiki/Salsa20">Salsa20 - Wikipedia</a></li>
<li><a href="https://github.com/C2SP/C2SP/blob/main/chacha8rand.md">C2SP/chacha8rand.md at main · C2SP/C2SP · GitHub</a></li>
<li><a href="https://convto.hatenablog.com/entry/2024/02/26/121013">つくって理解するストリーム暗号 ChaCha20 - ちりもつもればミルキーウェイ</a> : <a href="https://go.dev/">Go</a> でサンプルコードを書いておられる。ありがたや</li>
</ul>
<p>ChaCha はストリーム暗号の一種で,簡単に言うと,疑似乱数を生成してそれを平文と XOR するというものらしい。
このうちの疑似乱数を生成する部分を切り出しているようだ。
ストリーム暗号に使うものなので,暗号技術的にセキュアでかつ速いというのが特徴になるだろうか。
ちなみに ChaCha の後ろについている 20 とか 8 とかはラウンド数を示しているそうな。</p>
<p>ChaCha は OpenSSL だか OpenSSH だかでも見かけたような(うろ覚え)。
もし結城浩さんが『<a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1" title="Amazon.co.jp: 暗号技術入門 第3版 秘密の国のアリス eBook : 結城 浩: Kindleストア">暗号技術入門</a>』の第4版を出される機会があれば,付録でいいので是非 ChaCha にも言及して欲しい。</p>
<h2>ランタイムに ChaCha8 疑似乱数生成器を組み込む</h2>
<p>ChaCha8 疑似乱数生成器のアルゴリズムは <a href="https://pkg.go.dev/internal/chacha8rand" title="chacha8rand package - internal/chacha8rand - Go Packages"><code>internal/chacha8rand</code></a> パッケージに実装されている。
中身については割愛させてもらう。
Internal パッケージなので,サードパーティのパッケージからは直接参照できない。</p>
<p>まずは <a href="https://pkg.go.dev/runtime" title="runtime package - runtime - Go Packages"><code>runtime</code></a> パッケージに組み込んでいる部分を見てみる。
ちょっと長いけどご容赦。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// OS-specific startup can set startupRand if the OS passes
</span></span></span><span class="line"><span class="cl"><span class="c1">// random data to the process at startup time.
</span></span></span><span class="line"><span class="cl"><span class="c1">// For example Linux passes 16 bytes in the auxv vector.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">startupRand</span> <span class="p">[]</span><span class="kt">byte</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// globalRand holds the global random state.
</span></span></span><span class="line"><span class="cl"><span class="c1">// It is only used at startup and for creating new m's.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Otherwise the per-m random state should be used
</span></span></span><span class="line"><span class="cl"><span class="c1">// by calling goodrand.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">globalRand</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">lock</span> <span class="nx">mutex</span>
</span></span><span class="line"><span class="cl"> <span class="nx">seed</span> <span class="p">[</span><span class="mi">32</span><span class="p">]</span><span class="kt">byte</span>
</span></span><span class="line"><span class="cl"> <span class="nx">state</span> <span class="nx">chacha8rand</span><span class="p">.</span><span class="nx">State</span>
</span></span><span class="line"><span class="cl"> <span class="nx">init</span> <span class="kt">bool</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">readRandomFailed</span> <span class="kt">bool</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// randinit initializes the global random state.
</span></span></span><span class="line"><span class="cl"><span class="c1">// It must be called before any use of grand.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">randinit</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">lock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">init</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">fatal</span><span class="p">(</span><span class="s">"randinit twice"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">seed</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">seed</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">startupRand</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">c</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">startupRand</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">seed</span><span class="p">[</span><span class="nx">i</span><span class="o">%</span><span class="nb">len</span><span class="p">(</span><span class="nx">seed</span><span class="p">)]</span> <span class="p">^=</span> <span class="nx">c</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nb">clear</span><span class="p">(</span><span class="nx">startupRand</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">startupRand</span> <span class="p">=</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nf">readRandom</span><span class="p">(</span><span class="nx">seed</span><span class="p">[:])</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// readRandom should never fail, but if it does we'd rather
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// not make Go binaries completely unusable, so make up
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// some random data based on the current time.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">readRandomFailed</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"> <span class="nf">readTimeRandom</span><span class="p">(</span><span class="nx">seed</span><span class="p">[:])</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Init</span><span class="p">(</span><span class="o">*</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">clear</span><span class="p">(</span><span class="nx">seed</span><span class="p">[:])</span>
</span></span><span class="line"><span class="cl"> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">init</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"> <span class="nf">unlock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// readTimeRandom stretches any entropy in the current time
</span></span></span><span class="line"><span class="cl"><span class="c1">// into entropy the length of r and XORs it into r.
</span></span></span><span class="line"><span class="cl"><span class="c1">// This is a fallback for when readRandom does not read
</span></span></span><span class="line"><span class="cl"><span class="c1">// the full requested amount.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Whatever entropy r already contained is preserved.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">readTimeRandom</span><span class="p">(</span><span class="nx">r</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Inspired by wyrand.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// An earlier version of this code used getg().m.procid as well,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// but note that this is called so early in startup that procid
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// is not initialized yet.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">v</span> <span class="o">:=</span> <span class="nb">uint64</span><span class="p">(</span><span class="nf">nanotime</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p">></span> <span class="mi">0</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="p">^=</span> <span class="mh">0xa0761d6478bd642f</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="o">*=</span> <span class="mh">0xe7037ed1a0b428db</span>
</span></span><span class="line"><span class="cl"> <span class="nx">size</span> <span class="o">:=</span> <span class="mi">8</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p"><</span> <span class="mi">8</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">size</span> <span class="p">=</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="p"><</span> <span class="nx">size</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="p">^=</span> <span class="nb">byte</span><span class="p">(</span><span class="nx">v</span> <span class="o">>></span> <span class="p">(</span><span class="mi">8</span> <span class="o">*</span> <span class="nx">i</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span> <span class="p">=</span> <span class="nx">r</span><span class="p">[</span><span class="nx">size</span><span class="p">:]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="p">=</span> <span class="nx">v</span><span class="o">>></span><span class="mi">32</span> <span class="p">|</span> <span class="nx">v</span><span class="o"><<</span><span class="mi">32</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/runtime">runtime/rand.go</a></q></div></figcaption>
</figure>
<p>これは疑似乱数生成器の状態(主に seed)を管理してる部分かな。
最初の seed は乱数デバイスから取ってるんだね。
これに失敗すると時刻から生成する,と。
ユーザ側は明示的に seed を指定する必要がなくなるということやね。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// readTimeRandom stretches any entropy in the current time
</span></span></span><span class="line"><span class="cl"><span class="c1">// into entropy the length of r and XORs it into r.
</span></span></span><span class="line"><span class="cl"><span class="c1">// This is a fallback for when readRandom does not read
</span></span></span><span class="line"><span class="cl"><span class="c1">// the full requested amount.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Whatever entropy r already contained is preserved.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">readTimeRandom</span><span class="p">(</span><span class="nx">r</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Inspired by wyrand.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// An earlier version of this code used getg().m.procid as well,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// but note that this is called so early in startup that procid
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// is not initialized yet.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">v</span> <span class="o">:=</span> <span class="nb">uint64</span><span class="p">(</span><span class="nf">nanotime</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p">></span> <span class="mi">0</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="p">^=</span> <span class="mh">0xa0761d6478bd642f</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="o">*=</span> <span class="mh">0xe7037ed1a0b428db</span>
</span></span><span class="line"><span class="cl"> <span class="nx">size</span> <span class="o">:=</span> <span class="mi">8</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p"><</span> <span class="mi">8</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">size</span> <span class="p">=</span> <span class="nb">len</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="p"><</span> <span class="nx">size</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="p">^=</span> <span class="nb">byte</span><span class="p">(</span><span class="nx">v</span> <span class="o">>></span> <span class="p">(</span><span class="mi">8</span> <span class="o">*</span> <span class="nx">i</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span> <span class="p">=</span> <span class="nx">r</span><span class="p">[</span><span class="nx">size</span><span class="p">:]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">v</span> <span class="p">=</span> <span class="nx">v</span><span class="o">>></span><span class="mi">32</span> <span class="p">|</span> <span class="nx">v</span><span class="o"><<</span><span class="mi">32</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// bootstrapRand returns a random uint64 from the global random generator.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">bootstrapRand</span><span class="p">()</span> <span class="kt">uint64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">lock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">!</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">init</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">fatal</span><span class="p">(</span><span class="s">"randinit missed"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Next</span><span class="p">();</span> <span class="nx">ok</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">unlock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">x</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Refill</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// bootstrapRandReseed reseeds the bootstrap random number generator,
</span></span></span><span class="line"><span class="cl"><span class="c1">// clearing from memory any trace of previously returned random numbers.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">bootstrapRandReseed</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">lock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">!</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">init</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">fatal</span><span class="p">(</span><span class="s">"randinit missed"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">globalRand</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Reseed</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nf">unlock</span><span class="p">(</span><span class="o">&</span><span class="nx">globalRand</span><span class="p">.</span><span class="nx">lock</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// rand32 is uint32(rand()), called from compiler-generated code.
</span></span></span><span class="line"><span class="cl"><span class="c1">//go:nosplit
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">rand32</span><span class="p">()</span> <span class="kt">uint32</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">uint32</span><span class="p">(</span><span class="nf">rand</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// rand returns a random uint64 from the per-m chacha8 state.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Do not change signature: used via linkname from other packages.
</span></span></span><span class="line"><span class="cl"><span class="c1">//go:nosplit
</span></span></span><span class="line"><span class="cl"><span class="c1">//go:linkname rand
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">rand</span><span class="p">()</span> <span class="kt">uint64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Note: We avoid acquirem here so that in the fast path
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// there is just a getg, an inlined c.Next, and a return.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// The performance difference on a 16-core AMD is
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// 3.7ns/call this way versus 4.3ns/call with acquirem (+16%).
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">mp</span> <span class="o">:=</span> <span class="nf">getg</span><span class="p">().</span><span class="nx">m</span>
</span></span><span class="line"><span class="cl"> <span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">mp</span><span class="p">.</span><span class="nx">chacha8</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Note: c.Next is marked nosplit,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// so we don't need to use mp.locks
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// on the fast path, which is that the
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// first attempt succeeds.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">x</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">c</span><span class="p">.</span><span class="nf">Next</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">ok</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">x</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">mp</span><span class="p">.</span><span class="nx">locks</span><span class="o">++</span> <span class="c1">// hold m even though c.Refill may do stack split checks
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">c</span><span class="p">.</span><span class="nf">Refill</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">mp</span><span class="p">.</span><span class="nx">locks</span><span class="o">--</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// mrandinit initializes the random state of an m.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">mrandinit</span><span class="p">(</span><span class="nx">mp</span> <span class="o">*</span><span class="nx">m</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">seed</span> <span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="kt">uint64</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">seed</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">seed</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="p">=</span> <span class="nf">bootstrapRand</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nf">bootstrapRandReseed</span><span class="p">()</span> <span class="c1">// erase key we just extracted
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">mp</span><span class="p">.</span><span class="nx">chacha8</span><span class="p">.</span><span class="nf">Init64</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">mp</span><span class="p">.</span><span class="nx">cheaprand</span> <span class="p">=</span> <span class="nf">rand</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/runtime">runtime/rand.go</a></q></div></figcaption>
</figure>
<p><code>mrandinit()</code> 関数でランタイムを初期化して,それを使って実際に乱数を取得してるのが <code>rand()</code> 関数だね。
ふむふむ。</p>
<h2>math/rand パッケージのトップレベル関数群にランタイムの ChaCha8 を組み込む</h2>
<p>それじゃあ <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> パッケージの方を見てみよう。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">//go:linkname runtime_rand runtime.rand
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">runtime_rand</span><span class="p">()</span> <span class="kt">uint64</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand">math/rand/rand.go</a></q></div></figcaption>
</figure>
<p><code>go:linkname</code> ディレクティブの説明は割愛する。
こうやってリンクしてるということで飲み込んでいただければ(笑) そうそう。
<code>go:linkname</code> ディレクティブは <a href="https://pkg.go.dev/unsafe" title="unsafe package - unsafe - Go Packages"><code>unsafe</code></a> パッケージを要求するので,真似するときは要注意だよ。</p>
<p>ともかく,この <code>runtime_rand()</code> 関数を使って <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>rand</code></a><code>.Source</code> インタフェース互換の構造体 <code>runtimeSource</code> を定義している。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// runtimeSource is an implementation of Source64 that uses the runtime
</span></span></span><span class="line"><span class="cl"><span class="c1">// fastrand functions.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">runtimeSource</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// The mutex is used to avoid race conditions in Read.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">mu</span> <span class="nx">sync</span><span class="p">.</span><span class="nx">Mutex</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><span class="nx">runtimeSource</span><span class="p">)</span> <span class="nf">Int63</span><span class="p">()</span> <span class="kt">int64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">int64</span><span class="p">(</span><span class="nf">runtime_rand</span><span class="p">()</span> <span class="o">&</span> <span class="nx">rngMask</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><span class="nx">runtimeSource</span><span class="p">)</span> <span class="nf">Seed</span><span class="p">(</span><span class="kt">int64</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nb">panic</span><span class="p">(</span><span class="s">"internal error: call to runtimeSource.Seed"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><span class="nx">runtimeSource</span><span class="p">)</span> <span class="nf">Uint64</span><span class="p">()</span> <span class="kt">uint64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nf">runtime_rand</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand">math/rand/rand.go</a></q></div></figcaption>
</figure>
<p><code>Seed()</code> メソッドを呼び出したら panic 吐くとか容赦ないな(笑) <code>runtimeSource</code> はこんな風に使う。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// globalRandGenerator is the source of random numbers for the top-level
</span></span></span><span class="line"><span class="cl"><span class="c1">// convenience functions. When possible it uses the runtime fastrand64
</span></span></span><span class="line"><span class="cl"><span class="c1">// function to avoid locking. This is not possible if the user called Seed,
</span></span></span><span class="line"><span class="cl"><span class="c1">// either explicitly or implicitly via GODEBUG=randautoseed=0.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">globalRandGenerator</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">[</span><span class="nx">Rand</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">randautoseed</span> <span class="p">=</span> <span class="nx">godebug</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">"randautoseed"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// globalRand returns the generator to use for the top-level convenience
</span></span></span><span class="line"><span class="cl"><span class="c1">// functions.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">globalRand</span><span class="p">()</span> <span class="o">*</span><span class="nx">Rand</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">r</span> <span class="o">:=</span> <span class="nx">globalRandGenerator</span><span class="p">.</span><span class="nf">Load</span><span class="p">();</span> <span class="nx">r</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">r</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// This is the first call. Initialize based on GODEBUG.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kd">var</span> <span class="nx">r</span> <span class="o">*</span><span class="nx">Rand</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">randautoseed</span><span class="p">.</span><span class="nf">Value</span><span class="p">()</span> <span class="o">==</span> <span class="s">"0"</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">randautoseed</span><span class="p">.</span><span class="nf">IncNonDefault</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span> <span class="p">=</span> <span class="nf">New</span><span class="p">(</span><span class="nb">new</span><span class="p">(</span><span class="nx">lockedSource</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span><span class="p">.</span><span class="nf">Seed</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span> <span class="p">=</span> <span class="o">&</span><span class="nx">Rand</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">src</span><span class="p">:</span> <span class="o">&</span><span class="nx">runtimeSource</span><span class="p">{},</span>
</span></span><span class="line"><span class="cl"> <span class="nx">s64</span><span class="p">:</span> <span class="o">&</span><span class="nx">runtimeSource</span><span class="p">{},</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">!</span><span class="nx">globalRandGenerator</span><span class="p">.</span><span class="nf">CompareAndSwap</span><span class="p">(</span><span class="kc">nil</span><span class="p">,</span> <span class="nx">r</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Two different goroutines called some top-level
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// function at the same time. While the results in
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// that case are unpredictable, if we just use r here,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// and we are using a seed, we will most likely return
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// the same value for both calls. That doesn't seem ideal.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Just use the first one to get in.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="nx">globalRandGenerator</span><span class="p">.</span><span class="nf">Load</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">r</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand">math/rand/rand.go</a></q></div></figcaption>
</figure>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Seed uses the provided seed value to initialize the default Source to a
</span></span></span><span class="line"><span class="cl"><span class="c1">// deterministic state. Seed values that have the same remainder when
</span></span></span><span class="line"><span class="cl"><span class="c1">// divided by 2³¹-1 generate the same pseudo-random sequence.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Seed, unlike the [Rand.Seed] method, is safe for concurrent use.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// If Seed is not called, the generator is seeded randomly at program startup.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Prior to Go 1.20, the generator was seeded like Seed(1) at program startup.
</span></span></span><span class="line"><span class="cl"><span class="c1">// To force the old behavior, call Seed(1) at program startup.
</span></span></span><span class="line"><span class="cl"><span class="c1">// Alternately, set GODEBUG=randautoseed=0 in the environment
</span></span></span><span class="line"><span class="cl"><span class="c1">// before making any calls to functions in this package.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Deprecated: As of Go 1.20 there is no reason to call Seed with
</span></span></span><span class="line"><span class="cl"><span class="c1">// a random value. Programs that call Seed with a known value to get
</span></span></span><span class="line"><span class="cl"><span class="c1">// a specific sequence of results should use New(NewSource(seed)) to
</span></span></span><span class="line"><span class="cl"><span class="c1">// obtain a local random generator.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span> <span class="kt">int64</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">orig</span> <span class="o">:=</span> <span class="nx">globalRandGenerator</span><span class="p">.</span><span class="nf">Load</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// If we are already using a lockedSource, we can just re-seed it.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="nx">orig</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">orig</span><span class="p">.</span><span class="nx">src</span><span class="p">.(</span><span class="o">*</span><span class="nx">lockedSource</span><span class="p">);</span> <span class="nx">ok</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">orig</span><span class="p">.</span><span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Otherwise either
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// 1) orig == nil, which is the normal case when Seed is the first
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// top-level function to be called, or
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// 2) orig is already a runtimeSource, in which case we need to change
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// to a lockedSource.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Either way we do the same thing.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span> <span class="o">:=</span> <span class="nf">New</span><span class="p">(</span><span class="nb">new</span><span class="p">(</span><span class="nx">lockedSource</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">r</span><span class="p">.</span><span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">!</span><span class="nx">globalRandGenerator</span><span class="p">.</span><span class="nf">CompareAndSwap</span><span class="p">(</span><span class="nx">orig</span><span class="p">,</span> <span class="nx">r</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Something changed underfoot. Retry to be safe.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand">math/rand/rand.go</a></q></div></figcaption>
</figure>
<p>つまり,環境変数 <code>GODEBUG</code> で明示的に指定(<code>randautoseed=0</code>)するか最初に <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>rand</code></a><code>.Seed()</code> 関数を呼び出すかしない限りランタイムに組み込んだ ChaCha8 疑似乱数生成器が有効になるっちうわけだ。
ちなみに <code>lockedSource</code> は <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> パッケージに従来からある疑似乱数生成器で,名前の通り,ちゃんと mutex で排他処理している。</p>
<h2>math/rand/v2 パッケージにおける Source インタフェースの定義</h2>
<p>では,いよいよ <a href="https://go.dev/">Go</a> 1.22 で追加された <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> パッケージを見てみよう。</p>
<p><a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> パッケージと <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> パッケージとの大きな違いは <code>rand.Source</code> インタフェースが非互換になっていることだろう。</p>
<p><a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> パッケージの <code>Source</code> インタフェースの定義は以下の通り。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// A Source represents a source of uniformly-distributed
</span></span></span><span class="line"><span class="cl"><span class="c1">// pseudo-random int64 values in the range [0, 1<<63).
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// A Source is not safe for concurrent use by multiple goroutines.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">Source</span> <span class="kd">interface</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">Int63</span><span class="p">()</span> <span class="kt">int64</span>
</span></span><span class="line"><span class="cl"> <span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span> <span class="kt">int64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// A Source64 is a [Source] that can also generate
</span></span></span><span class="line"><span class="cl"><span class="c1">// uniformly-distributed pseudo-random uint64 values in
</span></span></span><span class="line"><span class="cl"><span class="c1">// the range [0, 1<<64) directly.
</span></span></span><span class="line"><span class="cl"><span class="c1">// If a [Rand] r's underlying [Source] s implements Source64,
</span></span></span><span class="line"><span class="cl"><span class="c1">// then r.Uint64 returns the result of one call to s.Uint64
</span></span></span><span class="line"><span class="cl"><span class="c1">// instead of making two calls to s.Int63.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">Source64</span> <span class="kd">interface</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Source</span>
</span></span><span class="line"><span class="cl"> <span class="nf">Uint64</span><span class="p">()</span> <span class="kt">uint64</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand">math/rand/rand.go</a></q></div></figcaption>
</figure>
<p>これに対して <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> ではこう定義されている。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// A Source is a source of uniformly-distributed
</span></span></span><span class="line"><span class="cl"><span class="c1">// pseudo-random uint64 values in the range [0, 1<<64).
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// A Source is not safe for concurrent use by multiple goroutines.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">Source</span> <span class="kd">interface</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">Uint64</span><span class="p">()</span> <span class="kt">uint64</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand/v2">math/rand/v2/rand.go</a></q></div></figcaption>
</figure>
<p>どえらシンプル! <code>Seed()</code> メソッドがなくなったのは大きいね。
これによって <code>runtimeSource</code> やトップレベル関数群が参照する <code>globalRand</code> の定義もめっさシンプルになった。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// globalRand is the source of random numbers for the top-level
</span></span></span><span class="line"><span class="cl"><span class="c1">// convenience functions.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">globalRand</span> <span class="p">=</span> <span class="o">&</span><span class="nx">Rand</span><span class="p">{</span><span class="nx">src</span><span class="p">:</span> <span class="o">&</span><span class="nx">runtimeSource</span><span class="p">{}}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//go:linkname runtime_rand runtime.rand
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">runtime_rand</span><span class="p">()</span> <span class="kt">uint64</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// runtimeSource is a Source that uses the runtime fastrand functions.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">runtimeSource</span> <span class="kd">struct</span><span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><span class="nx">runtimeSource</span><span class="p">)</span> <span class="nf">Uint64</span><span class="p">()</span> <span class="kt">uint64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nf">runtime_rand</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand/v2">math/rand/v2/rand.go</a></q></div></figcaption>
</figure>
<p>うんうん。
シンプルが一番だね。</p>
<h2>ChaCha8 を rand.Source にする</h2>
<p>ChaCha8 疑似乱数生成器を疑似乱数の <code>Source</code> として明示的に組み込む場合は, <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>rand</code></a><code>.NewChaCha8()</code> 関数を使って生成する。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span> <span class="s">"internal/chacha8rand"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// A ChaCha8 is a ChaCha8-based cryptographically strong
</span></span></span><span class="line"><span class="cl"><span class="c1">// random number generator.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">ChaCha8</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">state</span> <span class="nx">chacha8rand</span><span class="p">.</span><span class="nx">State</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// NewChaCha8 returns a new ChaCha8 seeded with the given seed.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">NewChaCha8</span><span class="p">(</span><span class="nx">seed</span> <span class="p">[</span><span class="mi">32</span><span class="p">]</span><span class="kt">byte</span><span class="p">)</span> <span class="o">*</span><span class="nx">ChaCha8</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">c</span> <span class="o">:=</span> <span class="nb">new</span><span class="p">(</span><span class="nx">ChaCha8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">c</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Init</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">c</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Seed resets the ChaCha8 to behave the same way as NewChaCha8(seed).
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><span class="nx">ChaCha8</span><span class="p">)</span> <span class="nf">Seed</span><span class="p">(</span><span class="nx">seed</span> <span class="p">[</span><span class="mi">32</span><span class="p">]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">c</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Init</span><span class="p">(</span><span class="nx">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Uint64 returns a uniformly distributed random uint64 value.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><span class="nx">ChaCha8</span><span class="p">)</span> <span class="nf">Uint64</span><span class="p">()</span> <span class="kt">uint64</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">x</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">c</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Next</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">ok</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">x</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">c</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nf">Refill</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand/v2">math/rand/v2/chacha8.go</a></q></div></figcaption>
</figure>
<p>ランタイムに組み込まれているものと違って,こちらは排他処理を行っていない。
並行的に安全(concurrency safe)ではないわけだ。
なので平行処理下で <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> の ChaCha8 を扱う場合は要注意である。
つか,平行処理下で ChaCha8 疑似乱数生成器を使うならトップレベル関数群を使うべきだろう。</p>
<h2>PCG を rand.Source にする</h2>
<p><a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> にはもうひとつ疑似乱数生成器が用意されている。
PCG (Permuted Congruential Generator) というそうな。</p>
<figure lang="en">
<blockquote class="nobox"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// A PCG is a PCG generator with 128 bits of internal state.
</span></span></span><span class="line"><span class="cl"><span class="c1">// A zero PCG is equivalent to NewPCG(0, 0).
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">type</span> <span class="nx">PCG</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">hi</span> <span class="kt">uint64</span>
</span></span><span class="line"><span class="cl"> <span class="nx">lo</span> <span class="kt">uint64</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// NewPCG returns a new PCG seeded with the given values.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">NewPCG</span><span class="p">(</span><span class="nx">seed1</span><span class="p">,</span> <span class="nx">seed2</span> <span class="kt">uint64</span><span class="p">)</span> <span class="o">*</span><span class="nx">PCG</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">PCG</span><span class="p">{</span><span class="nx">seed1</span><span class="p">,</span> <span class="nx">seed2</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></blockquote>
<figcaption><div>via <q><a href="https://pkg.go.dev/math/rand/v2">math/rand/v2/pcg.go</a></q></div></figcaption>
</figure>
<p>PCG は線形合同法(LCG)のバリエーションなんだそうで, LCG の統計学上の欠点を改善したものらしい。
2014年に発表された比較的新しいアルゴリズムのようだが,今のところは欠点のようなものは特に指摘されてないとか。
当然ながら暗号技術分野では使えない。</p>
<ul>
<li><a href="http://www.pcg-random.org/index.html">PCG, A Family of Better Random Number Generators | PCG, A Better Random Number Generator</a></li>
<li><a href="https://en.wikipedia.org/wiki/Permuted_congruential_generator">Permuted congruential generator - Wikipedia</a></li>
<li><a href="https://ja.wikipedia.org/wiki/Permuted_congruential_generator">Permuted congruential generator - Wikipedia</a> : 日本語</li>
</ul>
<p>こちらも並行的に安全ではないのでご注意を。</p>
<h2>これから math/rand を使う理由はないかな</h2>
<p>今までは <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> で用意されている疑似乱数生成器は暗号技術的にセキュアではない(要件である「予測困難性」を満たさない)ため使いどころを考えなければならなかったが <a href="https://go.dev/">Go</a> 1.22 から <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a>, <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> ともに ChaCha8 が既定の疑似乱数生成器なったため用途を選ばずカジュアルに使えるようになるだろう。
そうなると,これから疑似乱数生成器を使おうというとききに,わざわざ <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> を使う理由はないかな。
<a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> って無駄に複雑になってる感じだもんなぁ。</p>
<p>ちなみに <a href="https://pkg.go.dev/math/rand/v2" title="rand package - math/rand/v2 - Go Packages"><code>math/rand/v2</code></a> では <code>Read()</code> 関数もなくなっているが, <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>math/rand</code></a> でも <a href="https://pkg.go.dev/math/rand" title="rand package - math/rand - Go Packages"><code>rand</code></a><code>.Read()</code> 関数は Deprecated になってるし,<a href="https://go.dev/doc/go1.22#math_rand_v2" title="Go 1.22 Release Notes - The Go Programming Language">リリースノート</a>を見ると, <code>Read()</code> 関数が使いたきゃ <a href="https://pkg.go.dev/crypto/rand" title="rand package - crypto/rand - Go Packages"><code>crypto/rand</code></a> パッケージを使え,みたいなことが書いてあるので,まぁそういうことなんだろう。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="https://go.dev/doc/go1.22">Go 1.22 Release Notes - The Go Programming Language</a></li>
<li><a href="https://tools.ietf.org/html/rfc4086">RFC 4086 - Randomness Requirements for Security</a> (<a href="https://www.nic.ad.jp/ja/tech/ipa/RFC4086JA.html" title="セキュリティのための乱雑性についての要件">日本語訳</a>)</li>
<li><a href="https://text.baldanders.info/golang/pseudo-random-number-generator/">Go の疑似乱数生成器は並行的に安全ではないらしい(追記あり)</a></li>
<li><a href="https://zenn.dev/spiegel/articles/20240309-golang-math-rand-v2">Go 1.22 の math/rand/v2 を使ってみる</a></li>
</ul>
<h2>参考図書</h2>
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B099928SJD?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/416Stewy0NS._SL160_.jpg" width="123" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B099928SJD?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">プログラミング言語Go</a></dt>
<dd>アラン・ドノバン (著), ブライアン・カーニハン (著), 柴田芳樹 (著)</dd>
<dd>丸善出版 2016-06-20 (Release 2021-07-13)</dd>
<dd>Kindle版</dd>
<dd>B099928SJD (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">Kindle 版出た! 一部内容が古びてしまったが,この本は Go 言語の教科書と言ってもいいだろう。感想は<a href="https://text.baldanders.info/remark/2016/07/go-programming-language/" >こちら</a>。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2021-05-22">2021-05-22</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- プログラミング言語Go -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B0CFL1DK8Q?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51BmDUG6D0L._SL160_.jpg" width="125" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B0CFL1DK8Q?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Go言語 100Tips ありがちなミスを把握し、実装を最適化する impress top gearシリーズ</a></dt>
<dd>Teiva Harsanyi (著), 柴田 芳樹 (著)</dd>
<dd>インプレス 2023-08-18 (Release 2023-08-18)</dd>
<dd>Kindle版</dd>
<dd>B0CFL1DK8Q (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="4"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="far fa-star"></i></abbr></dd>
</dl>
<p class="description"><a href="https://book.impress.co.jp/books/1122101133">版元</a>で PDF 版を購入可能。事実上の Effective Go とも言える充実の内容。オリジナルは敢えてタイトルに “tips” という単語を入れるのを避けたのに邦題が「100 Tips」とかなっていて,原作者がお怒りとの噂(あくまで噂)</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2023-08-18">2023-08-18</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Go言語 100Tips -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4873118468?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51pUKQajnaL._SL160_.jpg" width="125" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4873118468?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">Go言語による並行処理</a></dt>
<dd>Katherine Cox-Buday (著), 山口 能迪 (翻訳)</dd>
<dd>オライリージャパン 2018-10-26</dd>
<dd>単行本(ソフトカバー)</dd>
<dd>4873118468 (ASIN), 9784873118468 (EAN), 4873118468 (ISBN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description"><a href="https://www.oreilly.co.jp/books/9784873118468/">Eブック版もある</a>。感想は<a href="https://text.baldanders.info/remark/2018/11/concurrency-in-go/">こちら</a>。 Go 言語で並行処理を書くならこの本は必読書になるだろう。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2020-01-13">2020-01-13</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- Go言語による並行処理 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/4814400535?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/41+ew2wl2jL._SL160_.jpg" width="125" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/4814400535?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">効率的なGo ―データ指向によるGoアプリケーションの性能最適化</a></dt>
<dd>Bartłomiej Płotka (著), 山口 能迪 (翻訳)</dd>
<dd>オライリー・ジャパン 2024-02-24</dd>
<dd>単行本(ソフトカバー)</dd>
<dd>4814400535 (ASIN), 9784814400539 (EAN), 4814400535 (ISBN)</dd>
</dl>
<p class="description">ついに Effective Go のタイトルを冠した本の邦訳が出た。<a href="https://www.oreilly.co.jp/books/9784814400539/">版元</a>で Ebook を買える。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-02-22">2024-02-22</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 効率的なGo : Effective Go -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51t6yHHVwEL._SL160_.jpg" width="113" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B015643CPE?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">暗号技術入門 第3版 秘密の国のアリス</a></dt>
<dd>結城 浩 (著)</dd>
<dd>SBクリエイティブ 2015-08-25 (Release 2015-09-17)</dd>
<dd>Kindle版</dd>
<dd>B015643CPE (ASIN)</dd>
<dd>評価<abbr class="rating fa-sm" title="5"> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i></abbr></dd>
</dl>
<p class="description">SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2015-09-20">2015-09-20</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 暗号技術入門 第3版 -->
<div class="hreview">
<div class="photo"><a href="https://www.amazon.co.jp/dp/B00I8ETG96?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1"><img src="https://m.media-amazon.com/images/I/51bXS7crIjL._SL160_.jpg" width="117" alt="photo"></a></div>
<dl>
<dt class="item"><a class="fn url" href="https://www.amazon.co.jp/dp/B00I8ETG96?tag=baldandersinf-22&linkCode=ogi&th=1&psc=1">赤ずきんチャチャ 1 (りぼんマスコットコミックスDIGITAL)</a></dt>
<dd>彩花みん (著)</dd>
<dd>集英社 1993-02-15 (Release 2014-02-25)</dd>
<dd>Kindle版</dd>
<dd>B00I8ETG96 (ASIN)</dd>
</dl>
<p class="description">そういえばコミックは読んでないかな。「リボン」は読まなかったからなぁ...</p>
<p class="powered-by">reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2024-03-07">2024-03-07</abbr> (powered by <a href="https://affiliate.amazon.co.jp/assoc_credentials/home">PA-APIv5</a>)</p>
</div> <!-- 赤ずきんチャチャ -->