カウンター

2014年3月8日土曜日

Windowsでのプロンプト環境MinGW

今回はWindowsで利用できるプロンプト環境MinGW+MSYSをご紹介します。

■MinGWとは?(「みんじーだぶりゅー」と呼んでます)
Minimallest GNU for Windowsの略で、一言で言うとGNUのツール軍です。GNUとは、聞いたことがある方も多いとは思いますがUnix互換のフリーソフトウェアプロジェクト&ソフトウェア全体の名称です。このGNUプロジェクトで作成されたようなツールを、Windowsで利用できるパッケージとして提供しているわけです。

■MSYSとは?(「えむしす」と呼んでます)
minimal systemの略で、MinGWには無いユーティリティ系のコマンド(awk,tarとか)が入っています。MinGWだけだと利用できるコマンドが少ないので補完的に利用します。

・Windowsのコマンドプロンプトはへぼい&かっこ悪い
・Linuxのコマンドを利用して色々作業したい

等、Windowsを使っているエンジニアの方はよくある話だとおもいます。ので、MinGWをインストールして捗る環境を構築しましょう。

まずMinGWのホームページから、インストーラーをダウンロードします。
http://www.mingw.org/

mingw-get-setup.exeを実行すると、インストーラーがインストールされます。とりあえずbaseだけでよいでしょう。


mingw32-base
msys-base
にチェック。 Installation→Apply Changes
からインストール開始。

インストール完了後、C:\MinGW\msys\1.0\msys.batを叩いて起動してください。これで一応コマンドとか利用できるようになったのでOKなのですが、、、ターミナルソフトがへぼいですよね。Windows標準のコマンドプロンプトを利用しているからです。もちろん、このままでいいよ!コマンドプロンプトが好きだ!って人はいいですが私は嫌いなので、minttyという最高のターミナルソフトをダウンロードしましょう。 いま起動したコマンドプロンプトで、下記コマンドを叩くとインストールされます。
$ cd /c/MinGW/bin
$ mingw-get update
$ mingw-get install mintty
C:\MinGW\msys\1.0\bin\mintty.exe がダウンロードされているはず。早速起動、の前にminttyはデフォルトは/bin/shで起動しているので、起動オプションに"-"をつけて、ログインシェルを読み込むよう指定しておきます。さっきインストールしたmintty.exeのショートカットを適当な場所に作成し、ショートカットのプロパティから「リンク先」を下記のようにしておいてショートカットから起動します。
C:\MinGW\msys\1.0\bin\mintty.exe - 

ちなみに、読み込まれるログインシェルは
/etc/profile
になります。

○minttyの設定
Optinos→Looks
Transparency : High
とすると透明になってかっこいい!glassはちょっとやりすぎかな。。。
Optinos→Mouse
Right click action : High

とすると右クリックで貼り付け可となる。メモに書いていたコマンド等を貼り付けたりするときに非常に便利ですね。

○フォントの変更
フォントはお好みで。私は"Courier New"で9ptにしました。

○vimのインストール
$ mingw-get install msys-vim

○aliasの設定
これは好みですが、私は下記のように設定しています。
alias ls='ls --color=auto --show-control-chars'
alias ll='ls -l'
alias vi='vim'

個別のログインシェルとして、/home/.profileを作成しその中に記載しています。

○プロンプト表示変更
デフォルトのログインシェルの場合、何故か2行になっています。なんで2行やねん。ログインシェルの設定箇所を見ると、下記のようになっています。
export PS1='\[\033]0;$MSYSTEM:\w\007
          \033[32m\]\u@\h \[\033[33m\w\033[0m\]
          $ '
なので、さっき作った.profileに環境変数"PS1"を別途指定してやります。
export PS1='\t $ '

すごくシンプルに時間だけw

















これで完成!捗ります!


2014年2月23日日曜日

sshの鍵交換

今回はsshの鍵交換です。sshでサーバから別のサーバにアクセスする場合、基本的にはいちいちパスワードを入力しないといけないですよね。しかし、色々都合が悪いときがあります。例えばシェルでリモートサーバ上で処理をしたりscpでファイルを取得する際です。(パスワード必須でも、実行する手段はありますが。)

このような場合、あらかじめサーバ間で鍵を交換しておくことで、鍵による認証によってパスワード入力無しにsshを行えるようになります。

概念的には、サーバAが公開鍵、秘密鍵のペアを作成しサーバBに公開鍵を渡しておくことで、サーバB側でのsshのログイン認証をその鍵で行う、というものです。サーバAからサーバBに渡すと、サーバBへのログイン時のパスワード認証が省略されます。その逆を行うことで、サーバA、サーバB相互にパスワード認証せずにsshログインが可能になるというものです。

実際のコマンドで紹介します。

■サーバAで公開鍵・秘密鍵のペアを作成してサーバBに送る

$ su - hoge
まずsshでログインしたいユーザになっておきます。(ここではhoge)
$ ssh-keygen -t rsa
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_rsa):
で鍵を作成します。"-t"オプションは鍵の種類を指定します。"rsa"の他には"dsa","ecdsa"等あるようです。ファイル名の指定は無しでもいいです。しなければ/home/hoge/.ssh/id_rsaが鍵ファイルとして生成されます。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
上記のようにパスフレーズというのを聞かれますが、何も入れずそのままEnterでOKです。入れてしまうと後々ログインの度にパスフレーズが聞かれます。
$ ls /home/hoge/.ssh/
id_rsa id_rsa.pub
鍵ができました。 pubがついているほうが公開鍵です。中身を見てみましょう。
$ cat ./id_rsa.pub
sh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnU8j4jni2h/YxCloVDnxv447qr01PI8+ThDCT79edjOxHWAn8ai7mYdckkJiE2aIPPTqZbTEz09++J7druRw5ksUlmadtIoy9gx/XsyulqeNASv7sPG66bN3Zwf3GvlUzCn+3CbECMu24W9im4gtY1hq8R+L0iWvZRFKVpKUIPDNpzryJJwA+n3el+UUqcjWVZuTN5Z7M8dMdwDg/TshuQFwgG0yO8fJonc/y+dJR6rH05tCUL1cIHM8HFEfQHmSuewUpDMilNeZ3+KaALJPosBfZQ1/g71fb4fnIVfDyxz6MG2FKJOsoWFFatCdhMreo3lmetg4E4MJK5IlAOBLn hoge@hostA
こんな感じ。この鍵情報をサーバBにわたします。
$ scp ./id_rsa.pub hoge@hostB:/home/hoge/
テキストなので、コピーして貼り付けでもよいですが、ここではscpで送りました。以上でサーバA側での作業は完了です。


■サーバB側での設定

サーバB側では、
・sshサーバの設定変更
・サーバAで生成した鍵を登録
をおこないます。

まずはsshサーバ設定の変更を行っていきます。

$ vi /etc/ssh/sshd_config

でsshサーバの設定ファイルに対して、下記3行をコメントアウトからはずして有効化します。

=======================================
~
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
~
=======================================

RSAAuthentication
→RSAによる認証を許可するかどうかを設定する

PukeyAutentication
→公開鍵による認証を受け付けるかどうかを設定する

AuthorizedKeysFile
→公開鍵情報を持つファイルを指定します。上記設定の場合はこの"authorized_keys"というファイルに、実際の公開鍵を追記します。

$ service sshd restart

でsshdを再起動します。これで設定が反映されます。
次は、公開鍵の登録です。

公開鍵は、上記"AuthorizedKeyFiles"で鍵情報のファイルを指定しているので、

$ ls /home/hoge/
id_rsa.pub

で公開鍵が送られてきていることを確認し、

$ cat /home/hoge/id_rsa.pub >> /home/hoge/.ssh/authorized_keys

でキーファイルにサーバAの公開鍵を追記します。
以上でサーバB側の設定も完了です。

サーバAからサーバBにhogeユーザでsshログインがパスワード無しでできるはずです。
逆もやりたい場合は、上記手順を逆に読み替えて設定を入れればOKです。

2014年1月29日水曜日

SSL通信

最近お仕事で扱うことがあったので、備忘をかねてちょっとメモしておきます。

そもそもSSL通信とは、Secure Sockets Layerの略でhttp専用の暗号化通信のこと。公開鍵暗号を利用しています。

公開鍵暗号方式とは、ざっくりいうと暗号鍵と復号鍵が違う、という方式です。共通鍵方式の方が計算量は少ない、処理が早いのですが、知らない人同士が初めて通信する場合って当然共通鍵を持ってないので、共通鍵の交換にこの公開鍵暗号方式が使われるわけです。

SSLに戻ります。SSL通信を送信すると、まずWebサーバは自身のサーバ証明書を認証局の秘密鍵で暗号化して送ります。認証局とは、サーバ証明書を保証する第三者機関です。サーバ証明書とは、読んで字のごとく、自分のサーバの身分を証明するものです。当然第三者(認証局)によって証明されているものであり、これがあることで、なりすましを防ぐわけです。

サーバ証明書が届くと、クライアント側でそれを確認するフェーズになります。まず、認証局の秘密鍵によって暗号化されているので、認証局の公開鍵によってそれを復号化します。

認証局の公開鍵は、一般にはルート証明書という形式で既存のブラウザ等に既にインストールされていることが多いです。下記にIEのルート証明書一覧をのっけました。



ルート証明書が既にインストール済みであれば、復号化してサーバ証明書を確認できます。

サーバ証明書内には、サーバのFQDNが記載されています。これをアクセスしたURL(たとえばwww.google.com等)と一致しているかどうかを確認します。つまり、クライアント側は、本当に自分のアクセスしたかったサーバにアクセスしているのか、という検証を、アクセスしたURLとサーバ証明書内のFQDNと一致するかどうかを見て行うわけです。サーバ証明書自体の有効性はルート証明書が保証していますので問題ないわけです。

最終的に、確認が完了すると、クライアント側で共通鍵を作成しサーバ側と共有します。最初にサーバ証明書が来たときに併せてサーバの公開鍵を送っているので、この公開鍵を用いて共通鍵を暗号化しサーバに送ることで、共通鍵の共有は完了です。

で、ようやく暗号化通信ができるようになりました。

最初に、公開鍵暗号方式で証明書を送り、共通鍵を共有します。その後は、共通鍵で暗号化通信を行います。これが、SSL通信の概要になります。


ちょっと文字ばっかりになってしましました。。。

2014年1月3日金曜日

JavaVMのメモリ管理(Permanent領域編)

今回はPermanent領域に焦点を当てていきます。
※あまり経験が無い分野なので、間違っている箇所があるかもしれません。。。その際はご指摘ください。

JavaVMではクラスローダを利用してクラスファイルをPermanent領域に読み込みます。クラスファイルとは、Javaコンパイル時に生成される、中間ファイル(.classファイル)のことです。クラスローダには下記4種類あります。

  • ブートストラップクラスローダ
    • Javaの中核となるライブラリをロードする。ネイティブコード。(ネイティブコードとは、OS上で直接実行可能な形式、つまり機械語になっているものです)


  • 拡張クラスローダ
    • 拡張ディレクトリ(/lib/ext や java.ext.dirsプロパティで指定された他のディレクトリ)にあるコードをロードする。


  • システムクラスローダ
    • CLASSPATH変数に記述されたクラスをロードする。通常、ユーザが記述したコードはこちらのクラスローダによってロードされる。


  • ユーザ定義クラスローダ
    • ユーザが定義したClassLoaderクラスによってロードする。


無論Permanent領域にもGCがあり、当該領域がいっぱいになると発生し、Old領域と同じようにPermanennt領域のGC中はJava全体が止まってしまいます。ちなみに、私が経験したケースだと、Old領域のFullGCは0.2秒程度(コンカレントGC)だったのに対し、Permanent領域のFullGCには7秒もかかっていました。。。

上記のGC時間を見てもわかる通り、Permanent領域については極力防がないといけないものです。前回も記載した通り、定期再起動とかメモリ増設なんですが、今回はアプリケーションの観点で考察したいと思います。

最初に記載したとおり、Permanent領域ってクラスロードに利用されます。基本的には最初(起動時)にクラスをロードしたら一定のはず、、、なんですが、GCが発生するようなPermanent領域が次第に増えていくケースというのは、下記のような場合があると考えられます。

  1. 新規利用されるクラス
  2. ユーザ定義クラスローダ
  3. リフレクション


「1.新規利用されるクラス」

Javaの基本原則として、必要になって初めてクラスがロードされます。長い間稼働するプログラムで、呼び出されることのなかったクラスが呼び出されるとそこで初めてクラスがロードされますので、理論的には時間とともに微増していくと考えられます。

「2.ユーザ定義クラスローダ」

"ClassLoaderクラス"を継承ことによって、ユーザ定義のクラスローダを作成することができます。(ClassLoaderクラスは抽象クラスであるため、直接生成できない)こちらでクラスロードを実行すると、当然Permanent領域を利用することになり、当該領域が増えます。

「3.リフレクション」

リフレクションとは、プログラムの実行過程で自身の構造を読み取ったり書き換えたりする技術のことで、javaではjava6以降で導入されています。リフレクションの機能を利用することで、動的なクラス生成が可能です。例えば、生成したクラスorメソッドを、プログラムに渡す引数によって変えたり等の柔軟な処理が書けたりします。

ただ、一定回数以上の呼び出しがあると、当該クラスをバイトコード化して、Permanent領域に格納するためPermnent領域が増加していく、という現象があるようで、こちらもPermanent領域増加の原因となってしまうようです。

// リフレクション
Class sampleins = Class.forName("Hoge");
Method samplemethod = sampleins.getMethod("helloworld");
samplemethod.invoke(sampleins.newInstance());

Permanent領域のFullGC原因は一概には言えないですが、チューニングに際しては下記オプションが使えそうです。
  • -XX:+ TraceClassloading
    • クラスのロード時に情報を出力
  • -XX:+ TraceClassUnloading
    • クラスのアンロード時に情報を出力


JVMのメモリ管理

今回はJavaVMのメモリ管理について記載します。
#最近お仕事でシステムのリソース状況を見る機会が多いため、覚書として書いておきたいと思います。

まず、基本事項ですがJavaでプログラムを作成すると、C言語などとは違ってメモリを自動で管理してくれます。例えば、プログラム内で変数を宣言して正しく開放されない変数が残っていたりすると、次第にメモリ利用上不都合な状態(これをフラグメンテーション、或いは断片化と言います)になってしまいます。本来であればすべての変数に対して開放する処理を記述してあげる必要があるのですが、Javaではそういった面倒な記述が不要で、Java自身が自動で管理してくれます。具体的には、JavaVM内で利用しているメモリを自動整理する、という仕組み(ガーベジコレクション:GCと言います)が動きます。

もう少し詳しく見ていきます。
JavaVMでは、メモリ領域を下記図のように種別して管理します。


大きく分けると、
・New領域
 →生存期間の短いJavaオブジェクトが格納される
・Old領域
 →生存期間の長いJavaオブジェクトが格納される
・Permanent領域
 →ロードされたclassの情報が格納される
の3つになります。

New、Old領域の2つをJavaヒープ領域といいます。Javaヒープ領域では、オブジェクトを世代別に管理する仕組みになっており、新規に生成されたJavaオブジェクトはまずNew領域内のEden領域に格納されます。その後Edenがいっぱいになると、EdenのGC(YoungGC:YGCといいます)が発生し、まだ利用中であるオブジェクトのみをSurvivor領域の"To"に移動させ、利用していないオブジェクトは開放します。次のYGC時にはSurvivor領域のFromとToが入れ替わり、Eden領域のオブジェクトを"元々From:現To"に移し、同時に"元々To:現From"に格納されていたオブジェクトで利用中のものを"元々From:現To"の領域に移します。

さらにYGCを一定回数繰り返してもなおSurvivor領域に残っているオブジェクトが「生存期間の長いオブジェクト」だと判断され、Old領域に移されます。Old領域がいっぱいになってしまうと、FullGCと呼ばれるGCが発生し、JVMで稼働している全オブジェクトが停止してしまいます。。。(俗に、"Stop the World"といいます。なんかかっこいいw)なので、一般的にはFullGCが発生しないように、適切なチューニングを行います。

上記で記載した各領域のサイズは、Java実行時にオプションとして定義します。指定オプションを下記で紹介します。

  • -Xms
    • ヒープ初期サイズを指定
    • 例:-Xms2048k、-Xms2m
  • -Xmx
    • ヒープ領域最大サイズを指定
    • 例:-Xmx2048k、-Xmx2m
  • -XX:NewSize
    • New領域初期サイズを指定
  • -XX:MaxNewSize
    • New領域最大サイズを指定(初期サイズと同じがベター)
  • -XX:Permsize
    • Permanent領域初期サイズを指定
  • -XX:MaxPermsize
    • Permanent領域最大サイズを指定


Javaを利用しているWebアプリケーションでは、FullGC発生対策として一般に下記が考えられるのかなと思います。

・Javaアプリケーションサーバの定期再起動(一日1回とか)
 →サービス停止が必要
・割当メモリの増設
 →FullGC発生頻度は減るが、発生してしまった時の停止時間が増えてしまう。

"→"で記載したように、デメリットもあります。
 勿論、そもそものアプリケーションの作りが悪いから改修する、という方法もありますが現場だと中々そっちの手段は取れないのかな、、、と思います。

ただ、最近では「コンカレントGC」というFullGCで停止してしまう時間を最小化する仕組みもあり、Javaも進化してきておりますw

次回はPermanent領域について触れます。

2013年9月28日土曜日

DynamicDNS

前回の記事で、Wake on Lanについて書いた時に、ちらっとダイナミックDNSに触れたのでそれについて書こうと思います。

Dynamic DNSとは、ちょこちょこ変動するグローバルIPを、固定のFQDNに紐づけてくれるサービスのことです。登録しておくと、一定のFQDNでインターネットから自宅にアクセスできます。私の目的はもちろん、自宅PCの電源ONのためです。

サービス自体はDynDNS等プロバイダは様々ですが、今回は私がやってみた無料のmyDNSのやり方を紹介します。

URL:http://www.mydns.jp/

「JOIN US」ページでユーザ登録を行うと、メールでIDとパスワードが届きます。再度上記ページに行き、送られてきたIDでログインして、左側メニューの"DOMAIN INFO"のページでドメイン名を登録します。

???.mydns.jp
???.mydns.bz
???.mydns.vc
???.mydns.tw
???.0am.jp
???.0g0.jp
???.0j0.jp
???.0t0.jp
???.pgw.jp
???.wjg.jp
???.server-on.net
???.live-on.net
???.keyword-on.net
???.dix.asia(NEW!)
???.daemon.asia(NEW!)

無料ドメインだと上記で選択できるようです。おこのみで。






















DomainのところにアクセスしたいFQDN、したの"A"って書いてあるとこはサブドメインの名前解決用です。サブドメインを利用しない場合は"*"でOKです。

次はIPの登録です。"IP ADDRESS DIRECT"というメニューで、自宅のグローバルIPアドレスを登録してください。グローバルIPアドレスは、確認くん(http://www.ugtop.com/spill.shtml)で見れます。
何もしてなければ基本「動的IP」なのでそれを選んでください。
IPv6のところはそのままでOKです。

以上で登録自体は完了です。
思った以上に簡単でした。

待ってたらそのうちアクセスできます。
確認は、コマンドプロンプトを開いて、

nslookup [登録したFQDN]

でグローバルIPが返ってきたらOKです。
数時間でiphone 3Gからもアクセスで切るようになりました。

一応これで使えるのですが、もう少し設定をしないといけません。
ダイナミックDNSって、動的なIPと固定のドメインを紐付けてくれるのですが、IPが変わった時にDNSサーバに教えてあげる必要があります。(IPが変わるタイミングはわかりません、プロバイダによると思います。感覚的には1週間に1度くらいでしょう。)

なので、定期的に教えてあげる仕組みを作りましょう。myDNSでは、POP3・FTP・HTTP等で特定のアクセス先にアクセスすればOKです。電源つけっぱなしで定期的にアクセスしにいくような仕組みにしたくなかったので、今回はログインのたびに自動でFTPアクセスする、というbatを作りました。

下記2つのファイルを作成して適当なところに保存しておいてください。

1.ftp.bat
==================================
ftp -i-s:ftpcmd.txt
==================================

2.ftpcmd.txt
==================================
open ftp.mydns.jp
[ID]
[パスワード]
==================================

の3行でOKです。スタートアップのディレクトリにショートカットを作ってあげればログインのたびに勝手に実行され、FTPでアクセスしてくれます。


以上です。

無料でできるのはすばらしーですね!

2013年9月25日水曜日

Wake on Lan

現在我が家では、自作パソコンのstation TVにてTV録画しております。

予約録画のためには、電源が入っている必要があり、
録画して撮りためておくのが好きなのでちょいちょい予約するのですが、
つけっぱなしにしておくと相方に怒られますwww

予約を入れてても、電源が入っていないと録画されず、
家に帰ったら、あーーー撮れてなかったー、ってのがちょいちょいあります。。。

時間になったら勝手に電源が入ればいいのになあ。
→誰か知っていたら教えてください。。。


時間になったら電源オン、は無理そうなので、

出先でiphoneから自宅のPCの電源をつける!!!

という目的とします。
そこで、(天下り的ですが)前から話を聞いていた「Wake on Lan」を試してみることに。
wake on lan(wol)とは、リモートでPCのスイッチをオンにする、という機能です。
この時起動命令用に送信されるパケットを、”マジックパケット”と言います。

幸い、録画PCではwolに対応していたので下記設定
をして利用できる状態にしました。

・BIOS設定
・デバイスマネージャでNICのプロパティ→WOLをオン

まずは同セグメント(LAN内)の端末から起動させてみます。
起動は、Wake up On Lan tool・MagicBoot等のツールをダウンロードして、

・IPアドレス
・サブネットマスク
・MACアドレス

を設定します。IPアドレスは起動したいPCのIPでもいいですが、LANのブロードキャストアドレス(例えば、192.168.0.255)にすると、確実にいけます。

iphoneでもできます。私は下記アプリをインストールしました。(どっちでもOKでした)
・RemoteBoot
・mWOL

結構サクッとできました!うれしいですね。


本題はここからです。
当初の目的は、インターネット経由で家のPCの電源をつける、ということでした。


元々LAN内を想定した技術のようなので、これが中々厄介です。

色々調べたのですが、下記4つの方法ができそうだとわかりました。

1.ルータからWOL(VPN経由)
2.ルータからWOL(直アクセス)
3.l同セグメントの別端末からWOL
4.ルータからポートフォワード


最初に書いておきますが、インターネット経由で家のネットワークにアクセスするには、
グローバルIPが必要です。
通常のプロバイダ契約の方もグローバルIPが当然あるのでできますが、
通常契約の場合グローバルIPは頻繁に変わりますので、別途グローバルIPを取得するか、ダイナミックDNSを利用するか、という方法があります。

ダイナミックDNSは、myDNS等が無料で利用できるので、おすすめです。




では、改めて1個ずつ見ていきます。

1.ルータからWOL(VPN経由)

うちのルータは、バッファローのWHR-G301Nなのですが、
WOL機能がありました!!!
ルータの管理画面から操作するようです。

同ルータのPTPPサーバ機能を利用してVPNでアクセスし、
そこで管理画面→WOL、でできました。


2.ルータからWOL(直アクセス)

こっちは、管理画面にアクセスするのにインターネットから直でアクセスする、
というものです。
他のルータは知りませんが、バッファローのルータの管理画面の認証は
ベーシック認証という、古びた認証でリスクが高いです。。。(ID,PWが暗号化されない)

やめましょう。。。


3.同セグメントの別端末からWOL

こちらは、同セグメントにつけっぱなしの別PCがいて、
そいつを操作してマジックパケットを送信してもらうものです。

色々やり方はあると思いますが、
Webサーバとして構築しておいて、外部ネットワークから

http://[グローバルIP]/wol.cgi

にアクセスしたらcgiがマジックパケットを送る、というやり方があるのかな、と思います。
家でPCをつけっぱなしにできないので、この選択肢は残念ながら取れません。。。

4.ルータからポートフォワード

今回、これをやりたくて色々試行錯誤しました。 
このやり方では、ルータでポートフォワードの設定をしておいて、
ルータ経由で当該PCにマジックパケットを送付する、というものです。

具体的には、ルータ上で「このポートに来たパケットは、あのIPのPCに送ってね!」
という設定をしておきます。














↑設定はこんな感じです。
192.168.11.2は、電源を付けたいPCのプライベートIPです。

ここで大きな問題が、、、

イーサネットでは、MACアドレスを見てパケットを対象PCに送信します。
もうちょっと言うと、LAN内ではIPアドレスからMACアドレスに変換し、当該MACアドレスにパケットを送信します。その変換を実行するためのMACアドレスとIPアドレスの紐づけである、「arpテーブル」ってのを各機器で持っています。

この場合はルータの持っているarpテーブルですが、対象のPCの電源が消えてしばらくすると(5分程度で)消えてしまいます。(仕様にもよりますが、このルータはそうっぽい)
つまり、電源が消えて時間が経ったPCは、ルータから見てどこにいるかわかんないわけです。

「あのPCに送ってね!」ではできないようですので、
じゃなく「すべてのPCに送ってね!」とします。

つまり、ブロードキャストです。
ポートフォワードの設定で、ブロードキャストアドレス(例えば192.168.0.255)にフォワードする設定を入れましょう!!!


ルータの管理画面にて設定しようとしたら、
「そのアドレスは設定できません。」















ちーん。

できるルータもあるみたいですね。(NEC製ルータ等)
残念です。。。

2013年9月13日金曜日

おすすめ情報検索システム

久しぶりの更新です。

今日は自作システムの「おすすめ情報検索」を紹介したいと思います。
このシステムでは、あるキーワードに関連するキーワードを教えてくれます。
例えば、”iphone”というキーワードを入力すると、”docomo”と返したりします。

原理的にはツイッターのタイムラインから関連ワードを拾ってきてるだけです。


使い方はいたって簡単で、ツイッターで

@recTopic

というアカウントに、キーワードをリプライするだけです。

ご自由にお使いください。

なお、pythonで実装しています。
#日本語の扱いに苦労しました。。。


ご興味がある方は、下記サイトをご参考いただければ。
http://d.hatena.ne.jp/killinsun/20130606/1370542828


※注意
twitterの制約上1分につき1回しか稼働できません。。。
1分に複数のリプライが来ると、1リプライしか拾えません。。。

2013年5月14日火曜日

食玩問題その3

前回、誕生日のパラドックスをPRISMで解いたので、
調子に乗って食玩問題もモデル化してみたらできましたので
紹介させて頂きます。

いたって簡単です。

dtmc
const int NUM_BOX; // 購入数
const int OMAKE;   // おまけの種類

module omake

  n : [0..OMAKE] init 0;   // 既に手に入れたおまけの個数
  b : [0..NUM_BOX] init 1; // 購入済みの個数

  [] (n<OMAKE)&(b<NUM_BOX) -> (OMAKE-n)/OMAKE : (n'=n+1)&(b'=b+1) + 1-(OMAKE-n)/OMAKE : (n'=n)&(b'=b+1);
  [] (n=OMAKE)&(b<NUM_BOX) -> (b'=b+1);

endmodule

定数としては、単純に問題のパラメータとして、
購入する予定の数と、おまけがいくつ混入しているか、
というものを与えています。

状態遷移の定義ですが、おまけがまだ全種類集まっていないとき、かつ購入予定数に
到達していないときに、残りの当たっていないおまけが当たるか当たらないか、
に遷移します。
当たり終わったら購入予定数にいくまで買い続けます。


というシンプルなモデルで表現できました。


前回同様、「おまけがすべて揃う確率」をPRISMで求め、
購入数を増やしていったときのおまけの当たる確率を計算してみましょう。



横軸が商品の購入数で、凡例にある4つの数値がおまけの種類です。
おまけの種類が増えるにつれ、やはり揃う確率も減ってきていますね。
15種類だと100個買えばほぼ100%の確率で揃っていたのですが、20個となると
当たる確率の上昇がゆるやかになっていますね。

ただ、前の記事にも書いていましたが当たる確率って均等じゃないですよね。
ものによってはレアなおまけもあるでしょうし。

例えば、おまけが「正規分布」で出現する場合に、
いくつ買えば全種類揃う確率が高いのか、というような感じで、
おまけの出方を変えたりするとまた面白いのかなー。。。

2013年5月12日日曜日

誕生日のパラドックスその2


その2です。
これは、「同じクラスに、同じ誕生日の人がいる確率は?」という問題でした。
直感的には、1年365日なのでとても確率が低そうに見えます。

その1だと、同じ誕生月の人がいるか、という考察しかしていなかったので
今回きちんと解を算出したいと思います。


普通に解いても面白く無いので、今回PRISMというツールを利用して解析したいと思います。
学生時代研究で利用していたのですが、確率モデルを解析するツールです。

参考までに、公式ページです。
http://www.prismmodelchecker.org/


まず確率モデルを設計していきます。
PRISMで書くと下記になります。















=================================
文法を簡単に説明します。
dtmcってのは、モデルの種類を定義していて、今回は
「Discrete-Time Markov Chain(離散時間マルコフ連鎖)」というモデルです。
定数をNで定義し、モデルの変数を8行目~9行目で定義しています。
実際の遷移定義は13行目~16行目です。
例えば、ある状態から、0.3で遷移先状態①に遷移し、
0.7の確率で遷移先状態②に遷移する場合、下記のように記述します。

【ある状態】 -> 0.3 : 【遷移先状態①】 + 0.7 : 【遷移先状態②】
=================================

単純に"N"人分誕生日を同じか確認していく、というモデルです。

今回の問題は、普通に解くと場合分けが必要なのですが、
それを考えなくていいように、"day"という変数を使って、
 誕生日が同じ⇒dayを減らさない
 誕生日が違う⇒dayを減らす
という方法で「任意の誰かが誕生日が同じであるかどうか」
を解くようにしています。

各変数の意味:
 s   : "1"の時、計算終了状態
 n   : 誕生日確認済み人数
  day : 誕生日が違う人がいると-1される
 m   : 誕生日が同じ人の数

13行目が最もメインで、
 誕生日が違う場合は、dayを減らし、残りの確認人数nを減らします。
 誕生日が同じ場合は、誕生日が同じ人の数mを増やし、残りの確認人数nを減らします。
ってな感じです。
14行目は、「すべての誕生日で同じペアが存在した」という状態を想定しており、
確率1で遷移します。で、人数nが0になったら状態s=1に遷移し、計算を終了します。


では、計算してみましょう。

PRISMは、「モデルに対してある性質を満たす確率を計算する」ツールです。
今回は、「s=1かつmが1以上の状態に到達する確率」を求めることで、誕生日のパラドックスを解きたいと思います。


またPRISMでは、定数をある範囲で動かして、各値での計算結果をグラフに
出してくれます。便利ですね。

今回は、クラスにいる人数をNとしていますので、クラス内の人数を
3~100で動かしてみましょう。


40人のクラスだと、ほぼ90%ですね。
(値としては0.891でした)

問題を解くよりは「PRISMの紹介」メインになってしまいましたが、
同じ誕生日がいる確率って結構高いんですね。

私は自分と同じ誕生日の人に出会ったこと無いので、
この結果は信じておりませんがw


2013年5月11日土曜日

TVサーバの構築(1)


すっごく久しぶりの更新です。(3年空きました)

最近は仕事でもプライベートでも色々調べたり手を動かすことが
多いので、せっかくなのでそれらについて色々書いていこうとおもいます。

なので、元々「問題の解説」というテーマでしたが、IT関連の情報も発信していきます。


今回のテーマは、「TVサーバ」です。
最近、会社の先輩がnasneを買ったらしく、家の中で色々な端末で見れるだけでなく、
タブレットにダウンロードして、出先でも見れるようにしてるみたいです。

自分もそれしたい!と考えて、色々調べました。

nasneを買うのが早いのかなと思っていましたが、
FAT32というファイルシステムの制約で2GBまでだそうですので、なんか微妙だなと。

調べていると、今の自作PCに取り付けているPIXELA社の「PIX-DT230-PE0」
というキャプチャボードのStation TVというソフトにTVサーバの機能があるみたいです。

早速それを更新してサーバを立てて、試しにローカルでそのTVサーバにアクセスしてみました。
利用したのは、XBMCというDLNA接続ができるクライアントです。

TVサーバ、見つかった!
あれ、でも見れない。。。

どうやら、DLNAだけでなく、DTCP-IPというTVサーバ用の保護された接続方式に対応した
ソフトでないとダメなようです。

今のところ、フリーソフトは無いようで(当然か?)

・Dixim Digital TV plus
・SoftDMA

の2つが主だったツールのようです。
両方ともシェアウェアですが、体験版があったので使ってみました。

今回は「Dixim Digital TV plus」でやってみました。
TVサーバが見つからない!!なんでや!って一人で騒いでいましたが、
しばらく放置していたら見つかりました。(ちょっと読み込みに時間がかかるようです)


しかし、「著作権保護に対応していません」と出ました。
どうやらディスプレイの接続方式が、「HDCP」という映像データの暗号化技術に
対応しているディスプレイでないと再生させないようです。

今のディスプレイは接続方式がアナログのD-sub15ピン(青いやつ)なので、
だめです。厳しいですね。

これを解決するには、ディスプレイごと買えないとなので一旦こっちは保留、
もう一台のノートPCでLAN経由で接続してみましたが、今度は、

「お使いのパソコンのセキュリティ設定やネットワーク環境、
サーバー機器の症状を確認して下さい。」

って出ました。もう疲れました。
また今度トライします。

2010年5月25日火曜日

誕生日のパラドックスその1

久しぶりの更新です。

今回は、先日友人から勧められた、「誕生日のパラドックス」という問題を考察していこうかと思います。

これは、同じクラスに同じ誕生日の人がいる確率は?、という問題です。
これは、少なくとも二人は同じ誕生日である確率は?という問題としてとらえると、同じ誕生日の人が全くいない確率を、1から引くことで求められます。

ここでは、問題をもっと簡略化して考えてみましょう。
友達2人と3人でいます。誕生月が同じ人が存在する確率を考えてみます。
2人選ぶと3C2で、同じ月でない確率は11/12なので、

1 - 12/12*11/12*10/12 = (144-110)/144 = 34/144 = 17/72

これはwikipediaで紹介があった方法ですw
これではあまり価値がないので、別解を考えたので紹介しておきます。

別解とは、問題を場合分けによってそのまま解く方法です。
別解というレベルではないですが。
まずは、3人の中で2人が同じ月である確率です。
3人の中から2人を選ぶには、3C2ですね。その3パターンで、同じ月である、という確率を求めます。

二人が同じ誕生月である確率は、

12/12*1/12*3 = 1/4

次に、3人が同じ月なのは、12/12*1/12*1/12=1/144ですね。
和をとると、

1/4 + 1/144 = 36/144 + 1/144 = 37/144

あ、あれ???
正解と違いますねw

あ、2人の誕生月が同じ場合に、3人目も同じ可能性があり、重複した確率になってしまいました。
なので、結局「2人だけ同じ誕生月を持つ確率」を計算する必要があります。

12/12*1/12*11/12*3 = 33/144

で、同じ17/72になりました。
いやーよかったw

中々良い頭の体操になりました。
確率って面白いですね。

2010年5月11日火曜日

食玩問題その2

作ってみました。シミュレータ。

このシミュレーションは、乱数によって何番のおまけが当たったかを判定しています。
すべての番号が出れば、すべてのおまけがあたった、ということになります。
これを1000回試行して、そのうち何回すべてのおまけが当たったかによって大体の確率を出します。
その1000回の平均を取り、確率としています。

ということで、やってみましょう。
6個まで計算しているので、10個買ったときはどうでしょうか。

10個・・・52.2%

まだ意外と低いですね。

15回・・・82.7%

おしい!

16回・・・86.1%
17回・・・88.8%
18回・・・90.9%

お!超えました!
しかしあくまでシミュレーションなので、厳密な値は超えていないかもしれないですが、18個ぐらい買えば90%の確率で全部揃うだろうということが分かったのでよしとしましょう。

せっかく作ったので、もう少しおまけの種類の多いものをやってみましょう。
100種類ある場合は?(例えば、J○ーグチップスとか?)

これはかなり買わないと駄目な気がします。。。

200個・・・0.000%

・・・。そうですか。

500個・・・51%

むむ。

600個・・・78.4%
700個・・・91.4%
800個・・・96.7%
900個・・・98.7%
1000個・・・99.5%

700個ぐらいから伸びがなくなってます。確率値のグラフはS字曲線を描いていることがわかりますね。
とりあえずこのぐらいにしときましょう。

まあ実際のおまけは、ものによってはレアなおまけもあるでしょうから、「当たる確率にばらつきがある」、ということで、これらの値はあくまでも参考程度、ということになりますね。残念。

2010年5月10日月曜日

食玩問題その1

第一回の更新です。
このブログでは、何かパズルやゲーム的な問題を自分なりに考察していく形式にしようかなと考えております。
これから頑張って書いていきます。宜しくどうぞ。

今日の問題は、「食玩問題」です。
この問題について解説されている素晴らしいサイトがあるんですが、改めて自分で考えていこう、ということで取り上げました。

何種類かおまけがついているお菓子を買った時に、すべて揃うにはどのくらい買ったらよい?
というような問題です。
例えば「○ックリマンシールを全種類集めたい!」というような要望に似ていますね。

もちろん、5種類のおまけがついているお菓子では、5個買ったら揃うこともありますよね。
では、1.それはどのくらいの確率でしょうか?また、2.80%ぐらいになるのはいくつ買った時でしょうか?

まず1.を単純に考えて見ましょう。
最初の1個を買ったときはどんなおまけでもいいですね。
そして、2個目は、4/5です。続けて考えると、5/5*4/5*3/5*2/5*1/5=0.0384
4%です。。。残念なお知らせですね。

では、6個買ったら?

n回目で既に出たものが当たると考えた場合、(n-1)/5となります。結局確率は(5/5*..*n/5*(6-n)/5*..*1/5)で、
nが1-6のパターンがありますので、5/5*4/5*3/5*2/5*1/5*(1/5+2/5+3/5+4/5+5/5)=0.1152です。

お!グッと数値が上がりました。
では、2.90%になるのはいくつでしょうか。

簡単にシミュレーションプログラムを書いて、試行させてみましょう。

・・・それは次回にしましょう。