2014年10月25日土曜日

漢字プリント 簡易作成ページ

漢字の練習をしたいとき(させたいとき)に一度間違えた漢字だけを集めて練習をしたいようなときがある。
そんなときに、間違えた問題だけを集めたプリントがあると便利なのだが、自分で作るとなると形を整えるのが結構面倒。

てなわけで、間違えた問題をテキストで取っておいて貼り付けるとそこそこ整形するようなものを作ってみました。
印刷用画面生成ボタンを押して表示された画面をブラウザの印刷機能で印刷してください。A4縦だと収まりがいいです。
動作確認は、chrome,safariで行っています。詳しい使い方は、ボタンの下を見てね。

  

各行に漢字の問題を
  漢字の(問題,もんだい)を作る。
のように書きます。実際は、ここで書くのではなく、どこかのテキストファイルにでもまとめておきます。
()の中はカンマ区切りで前半が正解の漢字、後半に読みがなを入れておきます。
送り仮名まで問題にしたいときは、上の例の3行目のように送り仮名まで含めて書いてください。

また、問題文の難しい文字に読みがなを付けたいときは、上の例の2行目のように
  (*真相,しんそう)を(究明,きゅうめい)する。
漢字の前に*を付けてください。このように指定すると問題ではなくただのふりがなとして作成します。

このページを作成するにあたって、freefielderさんの縦書きhtml作成用javascript(h2v.js)を使用しました。すごく便利なscriptです。ありがとうございました。

2014年9月15日月曜日

ディズニー ツムツムにはまった

今日は、本当にどうでもいい話なんだけど(いつもどうでもいいんだけど)、最近ディズニーツムツムにはまっている( orた?)。
自分がツムツムをやるときは、手を使わずに必ず棒を使うようにしている。
こんなやつ、
このスタイラスは、su-penのフタがびよ~~~んとのびるバネで出来ている伝説のモデルで、残念ながら現在生産終了。su-penは、保護フィルム越しの反応が、何本か試した中で一番良かったので愛用している。
こういう棒を使うと、棒なだけあってちょっと指を動かしただけで、先端が大きく動くので高速にプレイできてやりやすいので、ゲームでは手放せなくなっていて、うちではこいつは「ツム棒」と呼ばれている。
で、この間、この棒を忘れて外出してしまい、移動時間にツムツムをやろうと思って、

{げ、ツム棒忘れたぜ・・・}

とあせったが、まあしょうがないので指でやってみた。
ほんでもって、いつものペースで指で限界プレイしたら、指がマジ暑い。 もちろん摩擦で・・・

{なんじゃこりゃ!これ、炎のコマじゃねえの?俺はゲームセンターあらしか・・・}

ツムツムを指でマジプレイしてる人って指紋なくなるんじゃね↑ と心配になりました。

2014年7月3日木曜日

PlayFramework 2.3.1 with Scala 2.11.1 へプロジェクトをアップグレードした時のメモ

最近、ScalaもPlayもいろいろアップデートしていて速くなったとか(Scala)、速くなったとか(Play)言っているから、
{まあ、入れてみるか}
とやってみたら、以前のプロジェクト(Play2.2.x with Scala2.10.x)をアップグレードしようとした時いろいろややこしかったので、別のプロジェクトをやるときに絶対忘れそうなのでメモっておく。

まず、新しいPlayとScalaを公式ページでdownloadしようとすると、activatorなるものをインストールするように誘導された。
{activatorってなんじゃい}
完全に浦島太郎状態。どうやら、Scala, Play, Akkaやらサンプルやらwebエディターやらwebデバッガーやらセットになっていて、これ入れれば全部OKみたいなものらしい。
しかもplayコマンドとかsbtコマンドとか、全部 activator コマンドでやれということらしい。
で、activatorインストール後、今までのPlayのprojectフォルダに行って、
activator compile
とかいきなりやったけど、エラーの山。
{ま、そりゃそうだよな。しかたないか。}
なので、projectのファイルを色々変更した。

まず、project/plugin.sbt のplayのバージョンを以下のように変更
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.1")
次に、project/build.propertiesのsbtバージョンを以下のように変更
sbt.version=0.13.5
そんで、project/Build.scalaをこのサイトのSbt sampleを参考にこんな感じ変えてみた。
import sbt._
import Keys._

object ApplicationBuild extends Build {

  val appName         = "xxxxx"
  val appVersion      = "1.0-SNAPSHOT"

  val main = Project(appName, file(".")).enablePlugins(play.PlayScala).settings(
    version := appVersion,
    scalaVersion := "2.11.1",
    libraryDependencies := {
   CrossVersion.partialVersion(scalaVersion.value) match {
     // if scala 2.11+ is used, add dependency on scala-xml module
     case Some((2, scalaMajor)) if scalaMajor >= 11 =>
       libraryDependencies.value ++ Seq(
         "org.scala-lang.modules" %% "scala-xml" % "1.0.1",
         "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1",
         "org.scala-lang.modules" %% "scala-swing" % "1.0.1",
         "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.3-1")
     case _ =>
       // or just libraryDependencies.value if you don't depend on scala-swing
       libraryDependencies.value :+ "org.scala-lang" % "scala-swing" % scalaVersion.value
   }
 },   
 scalacOptions += "-feature"
  )

}
参考ページのコードに追加したのは、scalaxのscala-io-fileの部分、モジュール名とかバージョンとかわからなかったけど、MVNRepositorysというサイトから持ってきた。このサイトは知らなかったけど、こういうときはメチャメチャ便利なところ。

これでとりあえず動くようになった。

2014年4月17日木曜日

[linux]sshで鍵認証を行う際、commandに任意の引数を与えたい!

自分は、以前は{Windows命}だったのですが、最近linuxを使うようになって、便利なツールやコマンドが大量にあるので、{あれ、もしかしてなんか自動でやらせたりする時にはすっごく便利かも}と思うようになってきました。
もちろん、コマンドがいっぱいあり過ぎてとても全貌はつかめないのですが、自分が思いつくような処理はだいたいやる方法があります。
今回は、あるマシンから別のマシンのコマンドをある程度セキュリティを保ちながら、ビシバシ自動で実行するというところまで、結構大変だったのでメモをだらだらと残します。

あるクライアントマシン(以下C)からサーバー(以下S)上のコマンドをC上のプログラムやらcronやらから自動で実行したいとします。
話が長いので先にまとめると、
・ CからSのいろんなコマンドを自動で実行したい。
→ Sにログインするとき、自動でsshのパスワード入力ができなくて困る。
→ パスフレーズ無しの秘密鍵を使用したssh鍵認証を使用する。
→ パスフレーズ無しなので、秘密鍵ファイルさえあればS上でやりたい放題なので困る。
→ Sのauthorized_keysにcommandを書いてそのコマンドしか実行できないようにする。
→ CからSに投げたいコマンドは1つじゃないし、パラメータとかも変えたいので困る。
→ sshの機能を使いCからSに環境変数を渡して解決。

1: ssh鍵認証でログインできるようにする。
まず、C上で、公開鍵と秘密鍵を作成します。(参考にしたページ)
client$ ssh-keygen -t rsa
# 途中で秘密鍵のパスフレーズを聞かれるので、ただエンターすればパスフレーズ無しになる。 
# ホームの.sshにできた、id_rsa.pubが公開鍵で、id_rsaが秘密鍵。
今度は、Sに先ほどCで作った公開鍵(id_rsa.pub)をどうにかして持っていって、ログインしたい「Sのユーザー」のホーム下の.ssh/authorized_keys
の一番最後に、id_rsa.pubの内容をコピーします。
.sshディレクトリやauthorized_keysがない時は、
server$ cd
server$ mkdir .ssh
server$ chmod 700 .ssh
server$ touch .ssh/authorized_keys
server$ chmod 600 .ssh/authorized_keys
# 他のユーザーが中身を見られないようにちゃんとchmodしておく。
これでクライアント側から
client$ ssh -i ~/.ssh/id_rsa user@serverAddress 
なんてやるとパスワード入力無しでログインできます。
ただし、秘密鍵がパスフレーズ無しなので、id_rsaを持っているひとはS上でやりたい放題になってしまい危険です。

2: 鍵認証でログインしたユーザーが好きなコマンドを打てないようにする。
これは、Sの~/.ssh/authorized_keys にオプションを書くことにより行います。
authorized_keysというファイルは、かなり高機能なオプション設定ができまして、このファイルをいじるだけで、「使用される公開鍵ごとに」接続ホストを限定できたり、対話コンソール禁止にしたり、ポートフォワーディングを禁止にしたりいろいろできます。
接続ホストを限定すれば、だいぶ安心なのですが、それだと誰かが勝手にCのマシンを使った時にパスワード無しでSに侵入できるので、今回は、commandオプションを使います。
commandオプションを設定すると、sshで接続してきたら特定のコマンド(サーバー側で設定)だけを実行して接続を切るようになります。sshコマンドで実行コマンドが指定されていても無視します。(参照:sshdのman)
オプションを書く場所は、authorized_keysの先ほどの公開鍵をコピーした行の先頭で、例えば
command="ls -al" ssh-rsa AAABBBCCC...
# ssh-rsa以降が公開鍵部分
としておくと、クライアント側から
client$ ssh -i ~/.ssh/id_rsa user@serverAddress 
なんてやると、ログイン先のホームディレクトリの内容がずらずらと出て、すぐにSからログアウトされます。
これで、誰かが秘密鍵を使ってログインしても好きなことが出来なくなります。
しかし、この状態だと自分もcommandで指定したコマンドしか実行できないし、コマンドに可変で引数とか渡せないので不便です。

3: sshの機能でサーバーに環境変数を渡す。
sshの機能でCからSに環境変数を渡すことができます。(ここのページをヒントにしました。)
まず、S側の/etc/ssh/sshd_config を下のようにいじります。
# 環境変数の変更を許可する設定
PermitUserEnvironment yes
# クライアントから値を受け取る環境変数の指定
# SSH_ARGは自分でテキトーに決めた環境変数名
AcceptEnv SSH_ARG
PermitUserEnvironmentはyes/noなので、値を上書きします。
AccveptEnvは、上書きでなく追加してください。追加した環境変数がクライアントから変更可能になります。
なお、sshd_configを変更したらsshdの再起動が必要です。
これで今度は、authorized_keysのcommandを、例えば
command="echo SSH_ARG=$SSH_ARG" ssh-rsa AAABBBCCC...
# ssh-rsa以降が公開鍵部分
としておくと、クライアント側で
client$ env SSH_ARG=AHO ssh -i ~/.ssh/id_rsa -oSendEnv="SSH_ARG" \
     user@serverAddress  // ここまでコマンド
SSH_ARG=AHO  // ← これが表示結果
client$ 
となり、めでたく環境変数が渡せました。もちろん複数の環境変数も渡せます。
ここで、例のechoの代わりに自分で書いたscript等を使えば、CからSを自由にコントロールでき、また、意図しないコマンドの実行を抑えることが出来ます。

2014年4月11日金曜日

[scala][akka] microkernelを使って独立したプロセスに立てたRemote Actorとの通信サンプル

自分は、akkaの「Let it crash」というという発想が大好きなんです。
初めて「Let it crash」というスローガンを見たとき
{だよね。それでいいんだよね。}
と感激しました。

ただ、crashさせるためのSupervisor(docサンプル)の仕組みは、Actorはcrashさせるけど、jvmまでは殺してくれない。自分の場合、ヘビーな計算をscalaからloadLibraryしたc++のモジュールをJNA経由で使ってやっているので、jvmごとcrashさせたいんです。(外部libraryのunloadはできないようなので・・・)

そこで、登場するのがakkaのmicrokernelで、こいつを使うと簡単に独立したプロセスのjvmでActorを立てることが出来る。
必要に時は、こいつをjvmごとkillして復活させればいい ← もっとスマートな仕組みがきっとある気がする

で、HelloWorldのサンプルを書いてみた。
listenポートを可変にしたかったので、confファイルを使わない形で作ってみた。
application.confとかに設定が分かれてないほうがサンプルとしてもわかりやすいし。
まず、リモートで接続される側のmicrokernel
パラメータは、起動時に引数として渡せないので、起動する時は、
env AKKA_PORT=12345 akka hello.world.Sample.HelloLauncher
て感じで、環境変数経由にする。
あと、実行時にクラスが見つかんないみたいに怒られた時は、とりあえずjarに固めて、akkaのdeployフォルダに置けば見つかるようになります。
package hello.world.Sample

import akka.actor.{ Actor, ActorSystem, Props }
import akka.kernel.Bootable

class HelloLauncher extends Bootable {
    val port = System.getenv("AKKA_PORT")

    val conf = ConfigFactory.parseString(s"""
      akka.actor.provider = akka.remote.RemoteActorRefProvider
      akka.remote.netty.tcp.hostname = 127.0.0.1
      akka.remote.netty.tcp.port = ${port}
    """.stripMargin).withFallback(ConfigFactory.load());    
    val system = ActorSystem("HelloSystem", conf)

    def startup = {
        system.actorOf(Props[Hello], "hello")
    }

    def shutdown = {
        system.shutdown()
    }  
}

class Hello extends Actor {
  def receive = {
    case msg: String =>
      println("Hello: msg = " + msg)
  }
}
つぎに、Helloにメッセージを投げる側のサンプル
env AKKA_PORT=12345 akka hello.world.Sample.HelloLauncher
env AKKA_PORT=23456 akka hello.world.Sample.HelloLauncher
のように、別コンソールで2つのmicrokernelを起動した前提で動作させる。
object HelloCaller {

import akka.actor.{ Actor, ActorSystem, Props }
    
  def main(args: Array[String]) {
    System.setProperty("akka.actor.provider", "akka.remote.RemoteActorRefProvider")
    // このポートはリモート側でsenderにメッセージを戻す時に使用する
    System.setProperty("akka.remote.netty.tcp.port", "10000")
    val system = ActorSystem("CallerSystem")
    val actor1 = system.actorSelection("akka.tcp://HelloSystem@127.0.0.1:12345/user/hello")
    val actor2 = system.actorSelection("akka.tcp://HelloSystem@127.0.0.1:23456/user/hello")
    actor1 ! "Hello,"
    actor2 ! "Hello,"
    Thread.sleep(1000)
    actor1 ! "World."
    actor2 ! "Another actor."
    Thread.sleep(1000)
    actor1 ! "Yeaaahhh!!!"
    actor2 ! "Hooooooo!!!"
    Thread.sleep(1000)
    system.shutdown
  }

}
なお、mainから呼ぶ側のlibraryDependenciesには、akka-kernel, akka-actor, akka-remote を追加しています。

[sacla] akkaのmicrokernelに引数を渡す

akkaのmicrokernelは、Actorを別プロセスで簡単にバンバン立てられるので、便利なんですけど、今のバージョン(akka 2.3.2)だと、引数を渡せないので困った。

自分はlinuxのコマンドに不慣れで、解決法を忘れそうなのでメモ。

まず、akkaのbinにパスが通っているとして、普通のmicrokernelの起動は
akka com.xxx.packageName.ClassName
でやるんだけど、引数を渡したい時に、
akka com.xxx.packageName.ClassName arg1 arg2
とかやっても、Bootableにargsを渡してくれない。(そういうインターフェースになっていない)
なんでかというと、akkaコマンドが、複数のパラメータが
akka Class1 Class2 Class3
なんてあったときに、3つのBootableを一気に立ち上げるというふうに使っているから(参照)っぽい。

で、解決としては、linuxのenvコマンド(環境を変更してプログラムを実行する)を使用してmicrokernelを
env AHO=xxx BAKA=yyy akka com.xxx.packageName.ClassName
のように起動し、Bootableの中で
  val aho = System.getenv("AHO")
  val baka = System.getenv("BAKA")
とやって引数を取得しました。

2014年2月28日金曜日

[scala] PlayFrameworkでJson文字列の取得で一瞬あせった

Play 使っててJsonの文字列取りたい時、
val jsonObj = ........ とかなんとかあった場合
ドキュメントとか世のブログとかでは、
Json.stringify(jsonObj)
とやれとのことなんだけど、何も考えずに
jsonObj.toString
ってやってて、後で、これでいいの?だめなの?
と疑問に思った。
ちょっと調べたらどうやらjavascriptでは違うらしいので、一瞬
{げっっ!!}
となったが、playのソース(JsValue)を見ると

override def toString = Json.stringify(this)

だってさ。取れるものは同じということで、安心したぜ。

2014年2月14日金曜日

[Java] マイナスの16進数文字列をLongに戻したい

javaで、マイナスの16進数文字列を数値に戻したい。ただそれだけなのに、はまってしまった。信じられん。ということで、運良く解決したのでメモ。
これ、絶対はまるやつ結構いると思うんだけどなぁ。javaめ。

まず、説明のため順序的にLong->16進数ね。
Long l = new Long(-1);
String s = Long.toHexString(l);
これ、当然sが"ffffffffffffffff"。 fが16個。これが欲しいのでOK。
で、今回のお題は、16進数->Longなので、とりあえずこうするわね。
Long rev = Long.parseLong(s, 16);
しかし、ここで実行時エラー。
{なぬーっ。そんなアホなーーっ。}
どうやら、parseLongは、sの中身を正の値だと決めてかかっているようで、"7fffffffffffffff"より大きい文字列を入れるとエラーになる仕様。
Long.decodeも試してみたが、同仕様。
{どうしよう。とほほ。}
ちなみに、
Long ll = Long.parseLong("-ff", 16);
とやると、-255になるんだそうな。誰が喜ぶんだそんな仕様・・・
で、なぜかいろいろググっても解決できなかったのだが、コードをごねごねいじってたらラッキーにも打開策を発見した。
答えは、
Long rev = (new java.math.BigInteger(s, 16)).longValue();
一度、BigIntegerにしてから、それをLongにする。見事revが-1になった。
ナイス、BigInteger.longValue()!!
こいつの仕様に助けられた。
あとは、勝手にlongValue()の仕様が変らないことを祈るだけだ。

2014年1月29日水曜日

L2TP over IPsec (UDP4500) のポート開放が効かなくて困った。解決メモ。

ローカルネットワーク内部に、SoftEther等のL2TP over IPsecを使用するVPNサーバーを置いて、iPhoneやmacやAndroidからVPN接続をしようとしていたのだが、どうもうまくいかなかった。

ルーターにポートフォーディングの設定を正しくして、ルーターを再起動すると「ちゃんと外部からVPN接続できる。」のだが、しばらくするとL2TP over IPsecのポートフォーディングが動かなくなる。
他のポートのポートフォーディングは、ちゃんと動いていて、ダメになるのはL2TP over IPsecのポートだけ。

ルーターを再起動すると復活するが、1日から1週間位運用していると、またダメになる。いつダメになるかは読めない。

という変な状況が続いていた。ルーターを再起動すると直るので、当初ルーターを疑ったのだが、真の原因が判明したので、メモっておく。

原因:ローカルネットワーク内部に存在するMacBookの「どこでもMy Mac」機能がUPnPを使って、ルーターのUDP4500を奪っていたので、VPNサーバーにUDP4500が転送されていなかった。

対処:ルーターのUPnP機能をOFFにした。

今まで知らなかったのだが、UPnPというのは、ルーターのポートフォワードテーブルを勝手に書き換える(詳しくはここ)という恐ろしいやつで、うちで使っているルーター(PR-S300SE)では、手動で設定したポートフォワードテーブルよりも優先度が高いため、ポートが奪われてしまっていたようだ。

ルーター再起動でVPNサーバーにつながるようになっていたのは、再起動でルーターのUPnPテーブルがクリアされるからだった。

PR-S300SEに限らず、UPnPがデフォルトでONになっているルーターはあるようなので、似たような症状の出ている人はチェックするといいかもしれません。