2017/03/28

[js]グローバル変数の初期値はundefinedという値らしい

未だにJavaScriptをやっている。
あと数日のりきれば、おさらばできる(はず)。。。

 

先日、関数間をまたがる変数がほしくて、グローバル変数を使った。

  • 関数の外でvarを付けて宣言
  • 関数の中でvarを付けずに使用

のどっちからしい。
今回は連想配列をグローバル変数にしたかったので、こんなコードを書いた。

if (global_val[xxx] == null) {
  global_val[xxx] = yyy;
}

どうせ初期値はnullだろうと思ったのだ。
が、これはダメだった。

どうやら、初期値はundefinedというグローバル変数らしい。
また、undefinedという変数は代入可能なようで、==で比較するのは良くないと書かれていた。
そんなの知るか!ということで、こう変更した。

if (global_val[xxx] == undefined) {
  global_val[xxx] = yyy;
}

が・・・これもダメ。

if ((global_val == undefined) || (global_val[xxx] == undefined)) {
  global_val[xxx] = yyy;
}

たしか、こんな感じに変更してようやく動いたと思う。
やれやれ。

 

個人の感想だが、先に入れ物の有無を確認する必要があるのだったら、入れ物を初期化する処理も書くようになっていた方がわかりやすかったんじゃなかろうかと思う。

if (global_val == undefined) {
  global_val = new 連想配列作る();
}
if (global_val[xxx] == undefined) {
  global_val[xxx] = yyy;
}

この辺りは、私がJavaScriptの気持ちになりきれていないからだろう。
説明を読んで勉強しておこう。
var - JavaScript | MDN

 

困ったことに、今使っているのがmeteorというフレームワークで、これはjsファイルをincludeして関数化してしまうらしい。
だから、関数外でvarを付けて変数宣言しても、グローバル変数にはなってくれないとのこと。
いきなり関数内で知らない変数名が出てくるとあせるので、関数の外にvar無しでundefinedでも代入しておくのが良いのかなぁ。

[bc]アドレスのこと

技術ネタが切れてきたので、仕事でやってることに触れない範囲で、ときどきBitcoinのことを書いてみよう。
そういうときは「あ、ネタがないんだな」と思ってほしい。。。

今回は、Bitcoinアドレスについて書こう。
昔のBitcoinについてはあまり知らないのと、お金がかかる方のBitcoinを使ったことが無いので、。


ビットコインアドレスとは

読んでもらえばわかるので、これでおしまい、ではあんまりなので、もう少し細かいことを書くことにする。

「標準のビットコインアドレスは1で始まり」とあるが、そもそも標準ってなによ?というのが気になると思う。
Bitcoinはいろいろと仕様があって、アドレスについても決まりがあるのだ。

まず、お金になるBitcoinのブロックチェーンと、お金にならないBitcoinのブロックチェーンがあることは知っておいても良いだろう。
お金になる方は「mainnet」、お金にならない方は「testnet」と呼ぶ。
まあ、他にもあると思うが、主にこの2つだ。

「1」で始まるアドレスは、mainnetの方に属するアドレスである。
同じタイプでtestnetに属するアドレスは「m」や「n」で始まる。
だまされないように注意しよう。

 

その隣に「よりセキュリティーの高いマルチシグアドレスは3で始まる」と書かれている。
https://bitflyer.jp/ja/glossary/Multisig
うーん、その説明はどうよ?という気がしなくもないが、長く説明してもどうしようもないので、ここら辺が落としどころなのかもしれん。

まず、マルチシグのアドレスは「3」で始まるが、「3」で始まるアドレスがマルチシグとは限らない、というところがある。
http://chimera.labs.oreilly.com/books/1234000001802/ch04.html#base58
(すまん、日本語版もどこかにあったと思うが、見つけられなかった。。。)

リンク先に飛んで、スクロールさせていき「Table 4-1」を見てほしい。
Typeが"Bitcoin Address"が、さっき出てきた「1」で始まるアドレスの話だ。
"Base58 result prefix"に"1"と書いてあるのがわかる。
その2つしたに"Bitcoin Testnet Address"が"m or n"となっているのもわかるだろう。

で「3」だ。
これのTypeは"Pay-to-Script-Hash Address"と書かれている。
通称「P2SH」で、「1」で始まるアドレスが直接口座に振り込まれるようなアドレスだとすれば、「3」で始まるアドレスはスクリプトというプログラムに対して振り込まれるアドレスで、そのプログラムを解けないと振り込まれたBitcoinを使うことができないしくみになっている。
マルチシグも「n人のうちm人の署名がないと使うことができない」というスクリプトで表現するようになっているので「3」で始まるのだ。

これもtestnetで使うアドレスだと違う文字で始まる。
表に載ってないけど「2」のはずだ。
数字で始まるからmainnetのアドレス、というわけではないのだ。。。


ちなみに、Bitcoinはアドレスが分かると、そのアドレスに振込が行われたり、誰かに振り込んだりしたという状況がネットで確認できる。
いくつかそういうサイトがあり、私はBlock Explorerというサイトをよく使っている。
https://blockexplorer.com/

"Latest Transactions"というところが更新され続けていると思うが、これが振込の状況だ。
どれか1つクリックすると画面が変わって、いくつかBitcoinアドレスと額が出てくると思う。
左側にBitcoinアドレスが振り込む側で、右側のBitcoinアドレスが振り込まれる側だ。

よくあるパターンは、左側が1つのBitcoinアドレス、右側が2つのBitcoinアドレスかな。
Bitcoinは銀行の口座と違って、一部だけ支払うということをしない。
だから、誰かへの支払いがあると、残りはお釣りとして自分が使うBitcoinアドレスに振り込むことになる。
振り込んだのと同じアドレスに入れても良いのだけど、セキュリティ的によろしくないので、普通は別のBitcoinアドレスを作って、そこに振り込むだろう。

そういう面倒なことは、だいたいBitcoinの財布に当たるウォレットアプリがやってくれる。
ただ、信頼性のないBitcoinウォレットを使ってしまうと、勝手に別のアドレスに振り込んだりするかもしれないので、とにかく有名で安心できるものを選ぶようにしよう。

ここで自作のウォレットアプリを紹介できるとよいのだろうけど、全然そういうものを作る自信がないですな。
心配だったら、ハードウェアウォレットというネットから物理的に切り離したウォレットがあるので、そういうのがよいのだろうね。

2017/03/26

[勉]最近のPCのブートを知る (3) : ブートマネージャー

ここまで調べたところで、パーティションテーブルの扱い方に新しいやり方が加わったということがわかった。
まあ「新しい」といってもずいぶん前からなのだが。。。

もう1つ気になっていることがある。
外付けUSB-HDDにLinuxをインストールしたのだが、起動ディスクを選択するときにOS名が出てきたのだ。
そして、そのUSB-HDDを同じ機種である別のPCに挿したのだが、OS名も出ないし、起動するドライブとしてインストールしたディスクやパーティションを選択しても起動できなかったのだ。

UEFIにブートマネージャーなるものがあるようだが、それが関係しているのだろうか?


https://ja.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#.E3.83.96.E3.83.BC.E3.83.88.E3.83.9E.E3.83.8D.E3.83.BC.E3.82.B8.E3.83.A3.E3.83.BC

どうも、特定のセクタ(ブートセクタ)を読込んで起動を始めるのではなく、「ここにロードするファイルがある」という情報をUEFIに教えておき、UEFIはNon-Volatileなメモリにそれを保持しておいて、それを使って起動するようだ。
ブートセクタに何も書いていないのなら、それはUSB-HDDだけ挿しても立ち上がらないはずだな。

そのロードするファイルは、OSに依存しない場所に置かれ、OSに依存しない形式のフォーマットで、OSに依存しない実行形式なり情報なりが書かれているはずだ。
そして、インストーラがそれをUEFIに教えることになるから、何かしらのAPIというかABIというか、そういうので通信していることになるだろう。
それがPEというやつか。

ここら辺までひっくるめて「UEFI」と呼んでいるような気がする。
ディスクだけ挿して起動するという時代は終わったのか。。。

ただ、USBメモリにISOファイルを書込んで起動することができるから、できないというわけではない。
そういうブート形式でインストールされていないだけなのだろう。
VirtualBoxみたいに、移動できてどこでも同じように動くLinux環境を作りたかったのだが。

ブートセクタにブートローダを書込んでおいて、UEFIから起動するときにブートセクタを読込んでくれるようであれば、動く気がする。
ブートローダをどこに書込むかは、インストーラが聞いてくるので指定できる。
ドライブの方に書込むのか、パーティションの方に書込むのかいつも迷うのだが、さっきの話からするとUEFIに登録するようなものになるから、どこでもよいのかもしれない。

ブートローダー - ArchWiki
読んだときは、2017年1月更新になっている。
Linuxのブートローダって、たくさんあるんだな。。

Ubuntu系はGRUB2というか、GRUB(Legacyではない方)が使われていたと思う。
GRUB - ArchWiki
保護用にパーティションを作るなどと手順が書かれているが、私は何も考えずに「/」とswapのパーティションしか作らずにインストールしたので、そこらへんがよくなかったのかも。
Linux 上の GRUB 2 がブートできなくなったときの対処方法
リムーバブルディスクから起動できると書いてあるしね。

そういえば、Raspberry PiもbootはFATパーティションに置いてあるから、そういうのがいるのかもしれん。
まあ、今回は最近の情報を調べたかっただけなので、これで終わるとしよう。

2017/03/24

[勉]最近のPCのブートを知る (2) : UEFIモードとBIOSモード

UEFIのWindowsをBIOSモードで起動させる « ライフボート 裏ブログ(非公式ブログ)
どうも、UEFIはBIOSとは別物のようだ。
前回見ていったMBRやGPTは、どちらかといえばディスクのフォーマットに関するものだが、それだけでは済まないらしい。

 

UEFI モードまたは従来の BIOS モードでの起動
Microsoftのページで、まだWindows10は入っていない(別のページにあるのかもしれんが)。
UEFIモードの場合はGPTで、BIOSモードの場合はMBRと書いてある。

うちのノートPCはどうだっけ、と管理画面を見てみると、UEFIモードのようだ(EFIという文字があったので)。

image

 

Unified Extensible Firmware Interface - Wikipedia
ディスクの管理についても書かれているが、MBRもあればGPTもある、という感じで、別にGPTだけとなっているわけではなさそうだ。
もしかすると、MBRもある、がBIOSモードのことかもしれんが、さすがにそこまではわからん。

読んでいくと、BIOS時代から考えるとかなり高機能になっていることがうかがえる。
組み込みでも、RedBootやuBootの用に1段目のブートローダを使うことがあるが、そういう位置づけなのかもしれん。
あれが提供されているおかげで、あまり考えずにLinuxなどが動かせたりするからな。


だんだんまとまりがなくなってきたが、そもそも「最近のPCブートを知る」という漠然とした内容だから仕方あるまい。

2017/03/22

[勉]最近のPCのブートを知る (1) : MBRとGPT

まずは、UEFIから調べる。

BIOSに代わるファームウェア“UEFI”とは一体何か? 1/2 | 震撼性能! Sandy Bridgeに死角なし!! | DOS/V POWER REPORT

DOS/V POWER REPORTだから、PCを自作する人向けの情報ではあるものの、ポイントが絞られている分わかりやすい。

  • 起動ドライブの容量制限がなくなる(実質的に)
  • 設定画面がGUIにできる

今回はブートのことを知りたいだけなので、前者だけ見ていく。


Master Boot Record(MBR)の管理しか知らなかったのだが、GUID Partition Table(GPT)という管理があるらしい。

MBRは、HDDなどのセクタ0にパーティション情報が書いてある形式・・・と思っていたが、セクタ0だけじゃなくてパーティション分けされた先頭セクタでも良いようだ。
マスターブートレコード - Wikipedia

昔のHDDはCHS方式でアクセスしていたけど、容量が足りなくなってLBA方式になった。
SATAになる前のパラレルなHDDは40ピンあって、けっこうな本数がLBA用に割り当てられていたような記憶がある。
Advanced Technology Attachment - Wikipedia

パーティションテーブルのオフセットが8byte目のところがLBA方式で、サイズが4byteしかないというのが「MBRは32bit管理」という部分だろうか。
でも、これは先頭位置だけだから、その次の「全セクタ数」が4byteになっている方が32bitで制限される原因としては大きいのか。


GUIDパーティションテーブル - Wikipedia
こちらがGPT。
なんとなく肝臓付近を意識してしまうが、γ-GTPなんかとは関係がない。

LBAのアドレス表記で言えば、こうなっているそうだ。

  • LBA0 : MBRに相当する情報
  • LBA1 : GPTヘッダ
  • LBA2~33 : パーティションエントリ

GPTで管理していても、GPTに管理していないツールなどのためにMBRを用意してあるのだと。
MBR部分をどう見るかはOSによって異なるらしいので、自分でパーティションテーブルを作るときには注意した方がよさそうだ。

 

名前の由来になっているGUIDがどこに出てくるかというと、パーティションエントリという部分のようだ。
図によると1つのセクタに4エントリ入るようなので、512byte / 4 = 128byte/エントリ、ということになる(HDD系の1セクタサイズって、まだ512byteでよいよね??)。

  • 0- 15 [16]: パーティションの種類を表すGUID
  • 16- 31 [16]: パーティション固有のGUID
  • 32- 39 [ 8]: パーティション開始LBA
  • 40- 47 [ 8]: パーティション最後LBA
  • 48- 55 [ 8]: 属性フラグ
  • 56-127 [72]: パーティション名(UTF-16LE)

後半はわからなかったので、英語版wikipediaの情報を使った。
https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries


そこそこに衝撃だったのは、fdiskではGPTを扱えない、ということを知ったことだろうか。
まあ、Raspberry Piくらいだったらfdiskで済んでいるのだけど、PC Linuxが起動しないときに自分で対応しようとして悩まないように・・・というか、よけい破壊しないように覚えておいた方が良かろう。