Bitcoinマイニング計算をjavaで。

とても久々の投稿です。

最近Bitcoinを初めとした仮想通過関係の技術調査行っています。

ちなみに2018年1月はBitcoin価格が200万円から100万円に大暴落したりと、とっても面白い一カ月でした。
まだまだこれからどうなる事やら。という感じです。

さて、Bitcoinに関する技術情報ですが、もちろんJavaでの実装も世の中にはあるのですが、ピンポイントでマイニングを行っている箇所を探すのはちょっと厳しそうです。

wikiにはご丁寧にサンプルコードも載っているのですが、残念な事にJava版はありません。
https://en.bitcoin.it/wiki/Block_hashing_algorithm

という事で、上記のサンプルコードをもとに、Java版を作ってみました。
パラメータも全部同じものを使っています。
Read more »

VMWareでコピーしたマシンがネット接続できなくなった(Macアドレス的な)

VMWareが好きです。

とても好きです。

IEとか全バージョンの環境揃えています。

Officeも全部のバージョン揃えたいです。

OSも全部揃えたいです。

掛け算式に全パターン揃えたいです。

リンゴの形したOSも動かしたいです。

自分のローカルPCでVMWareを3つとか同時起動していると訳も無く強気になれます。

何故か自分が凄いやつのように思えてきます。錯覚です。でも気持ちいいです。

さて、仮想マシンをコピーしまっくているうちにブリッジでネットに接続できない可哀想な子が出てきました。WindowsXPです。

おそらく、コピー後に出てくる質問で「移動しました」を選択してしまったのでしょう。

調べてみたらMacアドレスが他の仮想マシンと被っていました。

ipconfig -all

とかやってPhysical Address.とか出てくるアレの事ね。

まずは仮想マシン設定の「ネットワークアダプタ」「詳細ボタン」からMacアドレスを新しく生成してあげます。

でもコレだけではWindows側で保存されているMacアドレスは変わってくれません。レジストリのどっかにでも抱えているんでしょう。

次にコチラで紹介されている手順でさきほど生成したMacアドレスと同じ値を指定してあげます。

自分のVMWareの場合、プロパティ名は「ローカル管理されるアドレス」では無く「Network Address」でした。

http://www.atmarkit.co.jp/fwin2k/win2ktips/356macaddr/macaddr.html

Macアドレスの変更をOKしたら反射的にOS再起動しておきます。

すると繋がるようになりました。

さて、繋がるようになったのでIE7での検証がんばりますか。(半泣き)

プログラミング一般化について

「全ての人よ、プログラミングを!」

http://life-is-tech.com/blog/programming/messagefrompresidentobama-5843

オバマ大統領からアメリカ全国民へ向けたメッセージ。らしい。

「我が国の将来に必要なのです。」

この言葉は、かなり強いものがある。

仮に全国民がプログラミングを習得した場合。

どのような未来が世界に訪れるのか。

家庭の主婦は、自分の家の家計簿をマクロで組むだろうし、スーパーのオーナーは自分で会計システムを構築してしまうかもしれない。

学生達はLineよりも、よりクローズドなコミュニティシステムを自作し、大人達に決して覗かれないような自分達にとって最も都合の良いコミュニティを構築するのかもしれない。

社会人に至っては(営業職でさえも)自身のタスクを管理するシステムを作り、それらを業務に大いに活用するかもしれない。

伴い世界中のシステムはもっと高度なものになるだろうし、プログラマーのレベルも今とは比較にならないほど高くなる。はず。

そしてプログラミングを生業としている我々は商売あがったりになるかもしれない。

しかし、国や世界レベルの発展においては「誰しもがプログラミング」は非常に大きな要素になると思っている。

これって「字を書く」「掛け算ができる」と同レベルの話で、数百年前では読み書きも算数もできない大人は沢山いたんだろうけど

現代においては、できないとアウトなレベルであって。

これと同じ事がプログラミングにも当てはまる世の中が訪れるのかもしれない。

利便性や世の中の発展性において、「誰しもが掛け算ができる」といった要素は大いに貢献している事実があり、それと同等の可能性をプログラミングは秘めている。と。

周囲で字の書ける人間が少ない環境においては字を書ける事はビジネスとして成り立つだろうし、計算についても同様。

プログラミングについても同様。これが現代。

世界的な発展性のためにはプログラミングの一般化は必要。

そして、そのうち字を書くのと同レベルでの常識化するんだと思う。

そうなったら、本当の意味でITによって世界が変わる日が訪れるんじゃないかと。

【AWS】AMIからインスタンスLaunch時にStatus Checksが1/2で止まってしまう件

とんでもなく久しぶりの更新です。

最近、手持ちのサーバをAWSに移行していたりします。

これまでは、別の担当者が用意してくれたインスタンスを使わせてもらう程度で、せいぜいセキュリティグループ編集したりスナップショット作ったりするくらいの程度のいじり具合でしたが、一から作成などをやっています。

そのため、リージョンをアメリカになっているのに気付かず「AWSのmicro遅すぎワロタ」とか恥ずかしい事言ってたりしました。

リージョン移動なんかに際してハマってしまったのでメモ。

・Volumeからスナップショット作成

・スナップショットのCopyメニューから我が国日本を選択

・スナップショットからAMI作成

・AMIをLaunch

でインスタンスのコピーが作成できるのだけれども、インスタンス一覧でStatus Checksが1/2で止まってしまい

エラーによりうまく起動してくれない、という問題が起きた。

必死でググりましたよええ。

どうやらスナップショットを取ったインスタンスのKernelIDと、コピー先でインスタンス起動する際のKernelIDの種類なるものがかみ合っていないとダメらしい。

解決策としては、

・まずコピー元のインスタンス表示からKernelIDを確認する(例えばaki-919dcaf8)。

http://thecloudmarket.com でそれを検索する。

・検索結果のDetailsに出ているNameを確認する(例えばpv-grub-hd0_1.04-x86_64.gz)

・そのKernelNameを更にhttp://thecloudmarket.com で検索する。

・その検索結果一覧にてAmazonマークになっているもの&国のアイコンが日本になっているものを探す(こんなやつ⇒

・そこに表示されているKernelID(例えばaki-176bf516)をAWSインスタンスLaunch時のConfigure Instance Details: Advanced Detailsで指定する。

・それで全てがうまくいく。

はずだったのだが、インスタンス作成完了時にアメリカ語で「アーキテクチャが違うよばか」みたいな事言われた。

そこで手順を一から繰り返してみたら、スナップショットからAMIを作成するタイミング(Create Image from EBS Snapshot)の画面に「Architecture」なるそのものズバリなのがありました。

ここで正しいアーキテクチャ(この時はx86_64)に選び直してインスタンス作成をやってみたら無事に成功しました。

なんでもかんでもデフォルトで「yes」「OK」ボタンを押してしまう悪いクセは良くないな、と思いました。

おわり。

【mysql】group byで30分刻みで集計

例えば、1分刻みで1レコードを保持するテーブルがあったとする。
まあ要件にもよるけど、1分刻みのレコードを1時間単位で集計する場合なんかは普通にgroup by使うよね。
date_format()とか使うよね。

ただ、最近こんな要件がありました。
「30分刻みで集計を取りたい」

はて、、、、
date_formatにそんなフォーマット文字あったっけ、、、?
まあ、ある訳ないっつう話ですよね。

Read more »

PHPで設定値。defineだのconstだの

PHPで設定値。
これって実は人によってやり方が様々で、それぞれの実装方法によって使い勝手も違うらしい。

単純に、組み込みで用意されているものを使うのであれば

define("CONF_A", "設定値");
echo CONF_A;

的な。

他にも

final class Config {
  const DATA_A  = "設定値";
}
echo Config::DATA_A;

とか。

クラス&const方式はまあ悪くないのかな?って思ってた。
設定の種類ごとにクラス名を変えるって事も可能だしね。

でもコイツって、

class Config {
	const B = "aa"."asd";
}

ができないんだよね。
式は基本何も使えない。

文字列結合くらい許せや。っていう・・・

実際問題、URLなんかを定義する時って
1) トップのURLを定義
2) 1で定義した設定値に文字列結合で配下のURLを設定
っていうのが当たり前だと思うんだ。

ドメイン変更とかURL変更に伴って大量の設定値の変更なんてやりたくありませんからね割とマジで。

constが悪いのかと思い

class Config {
	public static $B = "aa"."asd";
}

みたいしてみてもやっぱりダメ。

って事でclassで設定値を定義するのは諦めました。
やっぱdefineさん最高だよね。

で、defineについては基本的に式を受け付けてくれる

define("AAA", dirname(__FILE__)."/aaa.php");
define("BBB", "aaa"."bbb");

なんでもOK。

でもdefineって配列使えないんだよね。

define("CONF_A", array(1, 2, 3));

これはエラーがでます。

実際システム作っている時って設定値に配列使いたいときってよくあるんだよね。
で、みんなどうしているかっていうと、よく見かける設定値はこんな感じです。

define("CONF_A", "123456");
$CONF_B = array(1, 2, 3);

あれ?だったら全部いっその事変数にした方がいいんじゃないか?

$CONF_A = "123456";
$CONF_B = array(1, 2, 3);

これでglobalで呼び出す事で全部解決。
式も配列も全部使えて効率的だしスッキリした設定ファイルになるぞ。

あれ・・・・?ところで定数って何だっけ・・・

で、個人的には変数でも良いと思っています。
書き換えができてしまう。とは言ってもその辺はコーディングルールでカバーする形にできれば。
要はルール決めさえしっかりとあれば良くって、
必ず大文字で定義しましょう。でも効果も可読性もあると思う。

あとは好みの問題もあると思うけど、無理やりdefineでやる方法も何となくあみだした。

define("CONF", serialize(array(1, 2, 3)));
var_dump(unserialize(CONF));

serializeで無理やり文字列に変換して、
取り出す時はunserializeで配列に復元。

なんか一見微妙っぽいけど、ある意味やりたい事は全部できているような気がする。

・「定数」として定義したい
・配列を使いたい
・式を使いたい
・globalとか使わずに使いたい

うん、全部満たせているわ。なんか微妙っぽい感じもあるけど。

そして若干気に入りました。

jQueryのcssで何がなんでもstyle=”xxx”を効かせる

jQeuryで
$(“xxx”).css(“background-color”, “red”);
なんてやってcssを適用させたいときにcssの構造なんかの問題で、どうしてもうまくキマらない時がある。

普通にcssを書く場合なら!importantという最上級の優先ルールを使って適用する事も可能なんだけど、
jQueryの場合は下記のように記述する事で直接的な!importantルールが使えるようになる。

$("xxx").css('cssText', 'background-color:red !important;');

htmlを作ってくれるデザイナーさんによってcssの構造が違う事はよくあり、それをいちいち解析するのにも時間を大きく消費してしまう場合もあるので
若干強引ながらこういったやり方も知っておくと色々と捗る。

【AmazonAPIの仕様変更】リクエストには、必要なパラメータが含まれていません。必要なパラメータには、AssociateTagなどがあります。

運営しているサイトにてある日突然AmazonAPIで取得しているアフィリエイトリンクが出なくなってしまった。
これまで安定して動いていたのにある日突然だったので、
「うん?Amazonの調子が悪いのか?それともレンサバのcrontabでも狂ったのか?」
としばらく放置していた。
まあAmazon広告が出なくなったからといってサイトが動かなくなる訳じゃないしね。

が、何日たっても一向に治る気配がない。

やれやれとログを見てみるとこんなエラーが・・・

リクエストには、必要なパラメータが含まれていません。必要なパラメータには、AssociateTagなどがあります。

ん?んん???

どうやらAmazonAPIの仕様変更があって
「AssociateTag」
というパラメータが追加になったらしい。
しかも必須かよオイ・・・・

アフィリエイトIDを指定してやれば良いだけなので修正はすぐ何とかなったけれども。
これがカテゴリーやノードに関わってて何か調べごとが必要なパラメータとかだったら涙目になってたかもしれない。

そういえば、Amazonのデベロッパー向けメールに何か来ていたのかもしれない。
でも基本アメリカ語は良く分からないのでメールは来ていたけど無意識にスルーしてたぽい。

でもアレって頻繁にメール来るから思わずスルー安定になっちゃう罠。

ああいや、たまにしかメール来なかったとしてもスルーするな自分は。
間違いない。自身ある。

でも、てっきりこうゆのって「Version」パラメータで呼び出すAPIのバージョンをクライアント側が指定できるもんだと思ってた。

要はそんなものに甘えるなと、
そういう事ですね。

PHPでPOSTから取得したセッションIDでセッションを開始する

FlashのFileReferenceを使ったアップローダを作っていたところ
IE以外のブラウザではCookieが送信されない問題にぶち当たった。

そこで、CookieのデータをPOSTで送信してしまい、PHP側で無理矢理そのデータをsession_idとして認識できないかな?
と勘でやってみたところ、何故かうまくいってしまった。
ありがとうPHP。

$cookies = $_POST["cookie"];
$session_id = null;

foreach (mb_split(";", $cookies) as $cookie) {
	
	$cookie = trim($cookie);
	
	$arr = mb_split("=", $cookie);
	if (count($arr) != 2) continue;
	
	if (session_name() == $arr[0]) {
		$session_id = trim($arr[1]);
	}
	
}

$_COOKIE[session_name()] = $session_id;
	
ini_set("session.gc_probability", なんか数値);
ini_set("session.gc_divisor", なんか数値);
ini_set("session.gc_maxlifetime", なんか数値);
session_start();

これで正常にセッションが開始できた。

Flash側からはExternalInterfaceでJavascriptから
document.cookie
の値を取得して、それをPOSTしてやる。

document.cookie
の内容は、全てのCookieの値が連結された文字列なので、それをPHP側でsplit処理して解析してやり、
$_COOKIE[session_name()] = セッションID
としてやる事でPHPではクッキー内にセッションIDが入っていると認識してくれるらしい。

この
$_COOKIE[session_name()] = セッションID
が正直驚きだった。
事前にsetcookie()関数を呼び出すようなクッションページをかまさないと認識してくれないかと心配していたが、すんなりうまくいってしまった。

ちなみにFlash側のソースは以下

var _cookie = ExternalInterface.call("getCookie");	// javascriptで return document.cookie; をする関数を作成しておく

var req:URLRequest = new URLRequest(url); 
// req.requestHeaders.push(new URLRequestHeader("Cookie", _cookie));
// ↑これが使えれば一番良かったけど、FlashPlayerのセキュリティエラーになるので使えない

var variables:URLVariables = new URLVariables();
variables.cookie = _cookie;
req.data = variables;
req.method = "POST";

// アップロード
fileReference.upload(req);

Flashは素晴らしいUIが作れるものの、色々と制限やら実装抜けやら多いので苦労が絶えない。

レンタルサーバからメール送信した際にgmailで受信しない

レンタルサーバ稼動で、PHPからmb_send_mailするプログラムというのは定番かと思うけど
まれにgmailに対し送信した際に受信してくれない場合がある。

実際に体験したケースとしては、さくらレンタルサーバのスタンダードプランやVPSを利用していて、サイト上のPHPからメール送信
⇒Yahooメールには届くけれども、gmailには届いてくれない。

といったケース。

迷惑メールに分類される分にはまだいいんだけれども、gmail側が一切受信をしてくれないケースもある。

おそらく、サーバに同居している別ユーザがスパム送信などを行って(もしくは乗っ取られてスパムプログラムが動作して)gmailに大量にメールを送信しており
gmail側から「このサーバはスパムなのでメール受信しない」と判定されてしまっているのだと思う。

Yahooメールなど、他のwebメールに比べgmailはこの辺はかなり厳しい印象。

こうなってしまったら基本的には、こちら側はどうする事もできない。

とはいえ、ユーザ会員登録などでメール内に登録キー付きURLを仕込むような仕組みのサイトの場合、かなり致命的な問題となってしまう。

安プランなどで運営している場合は、サーバを移設してIPを変えてやるのが最も手っ取り早い対処となる。
もしくは経験上、数日から数十日ほど放置していると、突然なおったりもする。

段階としては、迷惑送信が停止してから数日から数十日のスパンで
・メール受信自体を拒否が解除
・迷惑メールに分類される事が解除
・通常メールに分類される
といったプロセスで状況が改善されていくらしい。

この辺はgmailのアルゴリズムによる所。

安プランのサーバは手軽な分、変な業者が同居している可能性も高まるので
なかなか判断も難しい所。

予算がある&確実なメール送信を求められているのならメール送信サービスなどを利用するのが間違いなさそう。
でもけっこう高いんだよなぁ・・