<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>kur.jp &#187; programming</title>
	<atom:link href="http://kur.jp/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://kur.jp</link>
	<description>バイオリンと自転車をこよなく愛するkurのチラシの裏．たまには技術的なことを書いたりするかも知れません．</description>
	<lastBuildDate>Mon, 06 Sep 2010 19:08:19 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/tag/programming/feed/" />
		<item>
		<title>PHPでTwitterのOAuth認証</title>
		<link>http://kur.jp/2010/07/12/twitter-oauth-php/</link>
		<comments>http://kur.jp/2010/07/12/twitter-oauth-php/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 17:03:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/07/12/twitter-oauth-php/</guid>
		<description><![CDATA[				今年の一月に、LogTwitと言うTwitterネイティブWebアクセス解析LogTwitをリリースしたのですが、1月の時点では何も考えずにBasic認証を使っていました。（リリース時のブログエントリ）
				 [...]]]></description>
			<content:encoded><![CDATA[				<p>今年の一月に、LogTwitと言うTwitterネイティブWebアクセス解析LogTwitをリリースしたのですが、1月の時点では何も考えずにBasic認証を使っていました。（<a href="http://kur.jp/2010/01/15/logtwit/">リリース時のブログエントリ</a>）</p>
				<p>ところが8月末からBasic認証が使えなくなってしまうということなので、現在、<a href="http://github.com/abraham/twitteroauth">twitteroauth</a>というライブラリを使いOAuth認証に対応させる作業をしています。ちなみに、利用したtwitteroauthのバージョンは0.0.2-beta3でした。<br />
				<span id="more-1033"></span></p>
				<p>今回、私がアプリでやりたいこととしては「ユーザ登録してくれたユーザのアカウントでポストする」ということ。そのためにはまず、下記の事が必要になります。</p>
				<ol>
				<li>OAuthでユーザに承認してもらう</li>
				<li>TwitterにPOSTする</li>
				</ol>
				<h2>OAuthでユーザに承認してもらう</h2>
				<p>まず、ユーザに承認してもらうためのURLを作成します。</p>
				<p>[php]<br />
				require_once(&#8220;twitteroauth/twitteroauth.php&#8221;);<br />
				// Consumer keyの値<br />
				$consumer_key = &#8220;xxxxxxxxxxxxxxxxxxxxxx&#8221;;<br />
				// Consumer secretの値<br />
				$consumer_secret = &#8220;yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&#8221;;<br />
				$connection = new TwitterOAuth($consumer_key, $consumer_secret);<br />
				$request_token = $connection->getRequestToken(&#8220;<a href="http://example.com/callback.php");">http://example.com/callback.php&#8221;);</a><br />
				$_SESSION['oauth_token'] = $token = $request_token['oauth_token'];<br />
				$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];<br />
				$auth_url = $connection->getAuthorizeURL($token, FALSE);<br />
				[/php]</p>
				<p>で、$auth_url に対してリンクを張るなり、header関数などを使うなりしてリダイレクトさせます。この時、getRequestTokenでコールバックURLを指定しないと、認証がうまくいかないので注意。</p>
				<p>$auth_urlに飛ぶと、こんな感じの画面が表示されます。ここでユーザがAllowを押すと、getRequestTokenで指定したコールバックURLに自動的に移動します。</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/07/image.png"><img src="http://kur.jp/wp-content/uploads/2010/07/image_thumb.png" border="0" alt="image" title="image" width="504" height="224" /></a></p>
				<p>コールバックURLに異動するとき、ユーザはoauth_verifierという引数を連れて帰ってきますので、下記のようにaccess_tokenを取得します。</p>
				<p>[php]<br />
				$access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']);<br />
				[/php]</p>
				<p>この$access_tokenをデータベースなどに保存しておくことで、PHPからTwitterにPOST等をすることが出来ます。</p>
				<h2>TwitterにPOSTする</h2>
				<p>TwitterにPOSTするためのコードはこんな感じです。</p>
				<p>[php]<br />
				require_once(&#8220;twitteroauth/twitteroauth.php&#8221;);<br />
				// Consumer keyの値<br />
				$consumer_key = &#8220;xxxxxxxxxxxxxxxxxxxxxx&#8221;;<br />
				// Consumer secretの値<br />
				$consumer_secret = &#8220;yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&#8221;;<br />
				$connection = new TwitterOAuth($consumer_key,$consumer_secret,$access_token["oauth_token"], $access_token["oauth_token_secret"]);<br />
				$connection ->OAuthRequest(&#8220;<a href="https://twitter.com/statuses/update.xml","POST",array("status"=">https://twitter.com/statuses/update.xml&#8221;,&#8221;POST&#8221;,array(&#8220;status&#8221;=>&#8221;Test Post&#8221;));<br />
				[/php]</p>
				<p>これで、Twitterに”Test Post”というメッセージが投稿されるはずです。なお、Twitterは同じメッセージの二重投稿が出来ないようになっているので、デバッグする際は投稿メッセージの末尾にUNIXタイム等をつけるなどするとよいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/07/12/twitter-oauth-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/07/12/twitter-oauth-php/" />
	</item>
		<item>
		<title>PHPでヒートマップを生成する</title>
		<link>http://kur.jp/2010/06/03/heatmap/</link>
		<comments>http://kur.jp/2010/06/03/heatmap/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 14:00:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/06/03/heatmap/</guid>
		<description><![CDATA[				自分専用Webアクセス解析を作っていると、ヒートマップ画像を生成したくなる時ありますよね。PHPでは簡単に画像を生成することが出来るので、色の設定さえやってしまえば、お手軽にヒートマップを生成することが出来ます。 [...]]]></description>
			<content:encoded><![CDATA[				<p>自分専用Webアクセス解析を作っていると、ヒートマップ画像を生成したくなる時ありますよね。PHPでは簡単に画像を生成することが出来るので、色の設定さえやってしまえば、お手軽にヒートマップを生成することが出来ます。</p>
				<p>以下、PHPを使ったヒートマップの作り方です。というか、どの言語でも基本的なやり方は同じなので応用できるはず。</p>
				<p><span id="more-1022"></span></p>
				<h2>1.データを用意する</h2>
				<p>まず、ヒートマップを生成するために0～255の256段階で構成される2次元配列を用意します。この配列の各要素の値に応じて色をつけて行きます。</p>
				<p>下の画像は、0～255の256段階で構成される2次元配列を画像にしたものです。ちなみに配列の中で0と指定した場所が黒に、255と指定した場所が白になっています。</p>
				<p><img src="http://kur.jp/wp-content/uploads/2010/06/image.png" border="0" alt="image" title="image" width="516" height="104" /></p>
				<h2>2.色を割り当てる</h2>
				<p>用意した0～255のモノクロデータ の各値にカラーを割り当てて行きます。色の割り当ては好みで良いと思うのですが、良くあるヒートマップだと青→緑→赤と変化するようになっていますので、それに習って色を設定してみます。まぁ、このへんはお好みで。</p>
				<p><img src="http://kur.jp/wp-content/uploads/2010/06/image3.png" border="0" alt="image" title="image" width="504" height="302" /></p>
				<h2>3.ヒートマップ画像を生成する</h2>
				<p>0～255に割り当てた色を画像に反映させます。</p>
				<p><img src="http://kur.jp/wp-content/uploads/2010/06/image4.png" border="0" alt="image" title="image" width="516" height="104" /></p>
				<h2>おまけ：ヒートマップ生成コード</h2>
				<p>最後に、上記画像を生成するためのPHPコードを貼り付けます。何かの参考になれば。</p>
				<pre>&lt;?php

function getR($i){
	if($i &lt; 128){
		$ret = 0;
	}else if($i &gt; 127 &amp;&amp; $i &lt; 191){
		$ret = ($i-127)*4;
	}else if($i &gt; 190){
		$ret = 255;
	}
	return $ret;
}
function getG($i){
	if($i &gt;= 64 &amp;&amp; $i &lt;= 191){
		$ret = 255;
	}else if($i &lt; 64){
		$ret =  $i * 4;
	}else{
		$ret = 256-($i-191)*4;
	}
	return $ret;
}
function getB($i){
	if($i &lt;= 64){
		$ret = 255;
	}else if($i &gt; 64 &amp;&amp; $i &lt; 127){
		$ret = 255-($i-64)*4;
	}else if($i &gt;= 127){
		$ret = 0;
	}
	return $ret;

}
header("content-type: image/png");
$image = imagecreate(512,100);
for($i = 0; $i &lt; 256;$i++){
	$tmp = imagecolorallocate($image, GetR($i), GetG($i), GetB($i));
	imagefilledrectangle($image, $i * 2 , 0, ($i * 2)+2, 99 , $tmp );
}
imagepng($image);
imagedestroy($image);
?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/06/03/heatmap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/06/03/heatmap/" />
	</item>
		<item>
		<title>ページ読み込み完了前にgBrowserオブジェクトにアクセス出来てしまう</title>
		<link>http://kur.jp/2010/05/03/firefox-gbrowser/</link>
		<comments>http://kur.jp/2010/05/03/firefox-gbrowser/#comments</comments>
		<pubDate>Sun, 02 May 2010 15:15:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[XUL]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/05/03/firefox-gbrowser/</guid>
		<description><![CDATA[				引き続きFirefoxの機能拡張を作ってるんだけど、不思議な現象に遭遇した。
				Firefoxを初回に起動したときにはgBrowserが定義されているのに、二度目に起動したときにはgBrowserが未定義と [...]]]></description>
			<content:encoded><![CDATA[				<p>引き続きFirefoxの機能拡張を作ってるんだけど、不思議な現象に遭遇した。</p>
				<p>Firefoxを初回に起動したときにはgBrowserが定義されているのに、二度目に起動したときにはgBrowserが未定義となる。このことに気がつかずに、ちょっとハマってしまったのでメモ。</p>
				<p> <span id="more-968"></span>
				<p>この現象に遭遇するためのコードはこんな感じ。</p>
				<pre>if(gBrowser){
	Application.console.log(&quot;gBrowser is defined&quot;);
}else{
	Application.console.log(&quot;gBrowser is not defined&quot;);
}
if(gBrowser.selectedTab){
	Application.console.log(&quot;gBrowser.selectedTab is defined&quot;);
}else{
	Application.console.log(&quot;gBrowser.selectedTab is not defined&quot;);
}
window.addEventListener(
  &quot;load&quot;,
  function () {
	Application.console.log(&quot;Loaded&quot;);
  },
  false
);</pre>
				<p><code>これを実行してみると、Firefox初回起動時は以下のような結果になる。</code></p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/05/image.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="197" alt="image" src="http://kur.jp/wp-content/uploads/2010/05/image_thumb.png" width="404" border="0" /></a> </p>
				<p>ところが、二度目以降に起動すると、以下のような結果になる。gBrowserオブジェクトは存在しているが、gBrowser.selectedTabオブジェクトは定義されていない事がわかる。</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/05/image1.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="198" alt="image" src="http://kur.jp/wp-content/uploads/2010/05/image_thumb1.png" width="404" border="0" /></a> </p>
				<p>実際、<a href="https://developer.mozilla.org/Ja/Code_snippets/Tabbed_browser">mozillaのWebサイト</a>を見て見ると、以下のように書いてあるので、挙動としては後者のほうが正しい気がする。</p>
				<blockquote>
				<p><code>gBrowser</code> が未定義ならば、あなたのコードはブラウザウィンドウのスコープで実行されていないか、もしくは早い段階で実行されすぎています。<code>gBrowser</code> にはブラウザウィンドウが完全にロードされた後でのみアクセス出来ます。</p>
				</blockquote>
				<p>では、初回起動時にオブジェクトが存在するのは何故なんだろうか？不思議です。ちなみに、ブラウザウィンドウが完全にロードされた後でコードを実行するにはこんな感じでコードを書けばいい。</p>
				<pre>this.onPageLoad = function() {
	if(gBrowser){
		Application.console.log(&quot;gBrowser is defined&quot;);
	}else{
		Application.console.log(&quot;gBrowser is not defined&quot;);
	}
	if(gBrowser.selectedTab){
		Application.console.log(&quot;gBrowser.selectedTab is defined&quot;);
	}else{
		Application.console.log(&quot;gBrowser.selectedTab is not defined&quot;);
	}
}

var self = this;
window.addEventListener(
  &quot;load&quot;,
  function () {
	self.onPageLoad();
  },
  false
);</pre>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/05/03/firefox-gbrowser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/05/03/firefox-gbrowser/" />
	</item>
		<item>
		<title>C#でBitmapの比較</title>
		<link>http://kur.jp/2010/03/03/bitmap-compare/</link>
		<comments>http://kur.jp/2010/03/03/bitmap-compare/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 15:16:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/03/03/bitmap-compare/</guid>
		<description><![CDATA[				一定時間毎にWebブラウザのウィンドウをキャプチャして，変更の有無を検出するコードを書いていたんだけど，ちょっと引っかかってしまったのでメモ．
				最初，BitmapクラスにはGetHashCodeというメン [...]]]></description>
			<content:encoded><![CDATA[				<p>一定時間毎にWebブラウザのウィンドウをキャプチャして，変更の有無を検出するコードを書いていたんだけど，ちょっと引っかかってしまったのでメモ．</p>
				<p>最初，BitmapクラスにはGetHashCodeというメンバ関数があるから，ハッシュを取得してそれを比較すれば良いだろう，と簡単に考えていた．ところが，GetHashCodeというのはオブジェクトのハッシュを返す関数であり，画像データのハッシュを返すわけではない．つまり，この関数の返り値を比較しても，画像の内容が等しいか否かを判断することが出来ない．</p>
				<p>じゃぁ，1pixelごと比較すれば良いのかと考えたのだけれども，BitmapクラスのGetPixelメソッドって，メチャクチャ遅い．そこで，Bitmapの中身をbyte配列に代入して，そのMD5をとることでハッシュ値を取得し，それを比較することで画像の変更の有無を検出することにした．</p>
				<p>以下，具体的なコード．これだけの事なんだけど，思ったよりも時間を取ってしまった・・・．</p>
				<p> <span id="more-859"></span>
				<pre>Bitmap CurrentImg = GetScreenCaputureOf(Firefox);
BitmapData bmpdata = CurrentImg.LockBits(new Rectangle(0, 0, CurrentImg.Width, CurrentImg.Height), ImageLockMode.ReadWrite, CurrentImg.PixelFormat);
IntPtr ptr = bmpdata.Scan0;
int bytes = bmpdata.Stride * CurrentImg.Height;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
byte[] CurrentHash = new MD5CryptoServiceProvider().ComputeHash(rgbValues);

bool bEqual = false;
if (PrevHash!=null &amp;&amp; PrevHash.Length == CurrentHash.Length)
{
    int i = 0;
    while ((i &lt; PrevHash.Length) &amp;&amp; (PrevHash[i] == CurrentHash[i]))
    {
        i += 1;
    }
    if (i == PrevHash.Length)
    {
        bEqual = true;
    }
}

PrevHash = (byte[])CurrentHash.Clone();
if (!bEqual)
{
    Console.WriteLine(&quot;Image Changed!&quot;);
}</pre>
				<p>参考にしたページ</p>
				<ul>
				<li><a href="http://support.microsoft.com/kb/307020/ja">Visual C# を使用してハッシュ値を計算し比較する方法</a> </li>
				<li><a href="http://msdn.microsoft.com/ja-jp/library/system.drawing.imaging.bitmapdata_members(VS.80).aspx">.NET Framework クラス ライブラリ BitmapData メンバ</a> </li>
				</ul>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/03/03/bitmap-compare/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/03/03/bitmap-compare/" />
	</item>
		<item>
		<title>&#8220;人生を書き換える者すらいた。&#8221;の迷路問題を解いてみた</title>
		<link>http://kur.jp/2010/01/26/meiro/</link>
		<comments>http://kur.jp/2010/01/26/meiro/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 11:27:40 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/01/26/meiro/</guid>
		<description><![CDATA[				今更感はあるのだけれど，気分転換に下記のブログで紹介されてた問題を解いてみた．
				人生を書き換える者すらいた。 人材獲得作戦・４ 試験問題ほか 
				かかった時間はたぶん60分ぐらい．アルゴリズム的には [...]]]></description>
			<content:encoded><![CDATA[				<p>今更感はあるのだけれど，気分転換に下記のブログで紹介されてた問題を解いてみた．</p>
				<p><a href="http://okajima.air-nifty.com/b/2010/01/post-abc6.html">人生を書き換える者すらいた。 人材獲得作戦・４ 試験問題ほか</a> </p>
				<p>かかった時間はたぶん60分ぐらい．アルゴリズム的にはA*アルゴリズムを使えば良いらしいけど，正直なところ，よく知らないので，適当に自分で考えてみた．</p>
				<p>基本的な考え方としては，距離1で行ける場所，距離2で行ける場所，距離nで行ける場所を順にピックアップしていき，距離nでゴールまで行けるようになったら，そこから逆に最短となる経路を探す，といった感じ．</p>
				<p>コメント欄を見てると30分とかで解いてる人も居るっぽいので，私はまだまだだなぁという感じですね．せっかくなので，ソースコードを公開してみます．あんまり綺麗なコードじゃないので，参考にはしないほうがよいと思うけど．</p>
				<p>&#160;</p>
				<p> <span id="more-836"></span>
				<pre>static void Main(string[] args)
        {
            /*
                ファイルを読み込みrawdata上に展開
             */

            string line = &quot;&quot;;
            ArrayList rawdata = new ArrayList();
            StreamReader sr = new StreamReader(@&quot;data.txt&quot;, Encoding.GetEncoding(&quot;Shift_JIS&quot;));
            while ((line = sr.ReadLine()) != null)
            {
                rawdata.Add(line);
            }
            /*
             *  rawdata上のデータをint型二次元配列dataに展開
             *  壁：-1
             *  スタート位置：1
             *  ゴール位置：-10
             *  道：0
             */
            int[,] data;
            string tmp = rawdata[0] as string;
            int width = tmp.Length;
            int height = rawdata.Count;
            data = new int[width, height];
            for (int i = 0; i &lt; height; i++) {
                tmp = rawdata[i] as string;
                for (int j = 0; j &lt; width; j++)
                {
                    if (tmp[j] == '*')
                    {
                        data[j, i] = -1;
                    }
                    else if (tmp[j] == 'S')
                    {
                        data[j, i] = 1;
                    }
                    else if (tmp[j] == 'G')
                    {
                        data[j, i] = -10;
                    }
                    else
                    {
                        data[j, i] = 0;
                    }
                }
            }

            /*
             * data配列をスタート位置から走査して，
             * スタート位置からの距離を格納する．
             * ゴール（-10）を見つけたらループを抜ける．
             */
            int cur = 1;
            bool loopflag = true;
            while (loopflag)
            {
                for (int i = 0; i &lt; height; i++)
                {
                    for (int j = 0; j &lt; width; j++)
                    {
                        if (data[j, i] == cur)
                        {
                            if (data[j, i - 1] == -10 || data[j - 1, i] == -10 || data[j, i + 1] == -10 || data[j + 1, i] == -10)
                            {
                                loopflag = false;
                                break;
                            }

                            if (data[j, i - 1] == 0)
                            {
                                data[j, i - 1] = cur + 1;
                            }
                            if (data[j - 1, i] == 0)
                            {
                                data[j - 1, i] = cur + 1;
                            }
                            if (data[j, i + 1] == 0)
                            {
                                data[j, i + 1] = cur + 1;
                            }
                            if (data[j + 1, i] == 0)
                            {
                                data[j + 1, i] = cur + 1;
                            }
                        }

                    }
                    if (!loopflag) {
                        break;
                    }
                }
                cur++;
            }

            /*
             * data配列をゴール位置から走査して，
             * スタート位置に向けて-2を格納していく．
             * スタート位置を見つけたらループを抜ける．
             */
            loopflag = true;
            while (loopflag)
            {
                cur--;
                if (cur == 1) {
                    break;
                }
                for (int i = 0; i &lt; height; i++)
                {
                    for (int j = 0; j &lt; width; j++)
                    {
                        if (data[j, i] == -10 || data[j, i] == -2)
                        {
                            if (data[j, i - 1] == cur)
                            {
                                data[j, i - 1] = -2;
                            }else if (data[j - 1, i] == cur)
                            {
                                data[j - 1, i] = -2;
                            }
                            else if (data[j, i + 1] == cur)
                            {
                                data[j, i + 1] = -2;
                            }
                            else if (data[j + 1, i] == cur)
                            {
                                data[j + 1, i] = -2;
                            }

                        }
                    }
               }
            }

            /*
             * 画面に表示を行う．
             */

            for (int i = 0; i &lt; height; i++)
            {
                for (int j = 0; j &lt; width; j++)
                {
                    if (data[j, i] == -1)
                    {
                        Console.Write('*');

                    }
                    else if (data[j, i] == 1)
                    {
                        Console.Write('S');
                    }
                    else if (data[j, i] == -10)
                    {
                        Console.Write('G');
                    }
                    else if (data[j, i] &gt;= 0)
                    {
                        Console.Write(' ');
                    }
                    else if (data[j, i] == -2)
                    {
                        Console.Write('$');
                    }
                    else
                    {
                        Console.Write(data[j, i]);
                    }

                }
                Console.Write('\n');
            }
            Console.Write('\n');
            Console.Read();
        }</pre>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/01/26/meiro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/01/26/meiro/" />
	</item>
		<item>
		<title>TwitterネイティブWebアクセス解析 LogTwitを作りました．</title>
		<link>http://kur.jp/2010/01/15/logtwit/</link>
		<comments>http://kur.jp/2010/01/15/logtwit/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 16:53:52 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[logtwit]]></category>

		<guid isPermaLink="false">http://kur.jp/2010/01/15/logtwit/</guid>
		<description><![CDATA[				LogTwit.com という新しいサービスを作ったのでちょっと宣伝．
				 
				以下，本サービスについて説明します．
				 
				このサービスをWebサイトにインストールすることによって，Lo [...]]]></description>
			<content:encoded><![CDATA[				<p><a href="http://logtwit.com/">LogTwit.com</a> という新しいサービスを作ったのでちょっと宣伝．</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/01/image14.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="245" alt="image" src="http://kur.jp/wp-content/uploads/2010/01/image_thumb2.png" width="351" border="0" /></a> </p>
				<p>以下，本サービスについて説明します．</p>
				<p> <span id="more-834"></span>
				<p>このサービスをWebサイトにインストールすることによって，LogTwitに設定されたアカウントが，ユーザのWebサイトへのアクセスをTwitterを通じてリアルタイムにつぶやきます．<a href="http://twitter.com/kurjp">実際に動作している様子はこんな感じです</a>．なお，このサンプルでは誰でもログを見れるように設定してありますが，TwitterのアカウントをPrivateにする＆LogTwit管理画面から非公開設定にすることで，他人にはログを見せないように設定することができます．</p>
				<p>Webアクセスログをつぶやくアカウントをfollowしておくだけで，他の方のつぶやきに混じって，お客様のWebサイトへの訪問を知ることができます．例えばこれはTwitterクライアントから見た私のタイムラインの様子です．こんな感じで，自然にWebサイトへのアクセスを知ることができます．</p>
				<p>また，各つぶやきには，詳細な情報を表示するためのURLがついており，それをクリックすることで，詳細な情報を表示することができます．</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/01/image15.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://kur.jp/wp-content/uploads/2010/01/image_thumb3.png" width="409" border="0" /></a> </p>
				<p>Google Analyticsと異なるのは，このお客様が，Webサイトの中でどのように移動したかがわかること．例えば，上記の例だと，7時22分11秒に<a href="http://kur.jp/2010/01/13/lab/">http://kur.jp/2010/01/13/lab/</a>にアクセスがあって，その6分後に，ブログのトップページ<a href="http://kur.jp">http://kur.jp</a> にアクセスして，その後，<a href="http://kur.jp/2009/12/27/yarisugosu/">http://kur.jp/2009/12/27/yarisugosu/</a> にアクセスしたんだな，というのがわかります．</p>
				<p>また，日付が変わると，昨日のアクセス数とともに，一日分の集計ページのアドレスを教えてくれます．</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/01/image16.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="206" alt="image" src="http://kur.jp/wp-content/uploads/2010/01/image_thumb4.png" width="351" border="0" /></a> </p>
				<p>Google Analyticsだと，日毎のアクセス数しかわかりませんが，LogTwitでは．時間帯別のアクセス数もわかります．例えば下記の画像は，1月13日のアクセスの様子なのですが，21時台から急にアクセス数が伸びていることが分かります．これは私が1月13日の21時26分にブログをアップし，アクセスが集まったからです．このように，何らかのイベントがアクセスログに反映されるのが直感的にわかるので，非常に面白いです．</p>
				<p><a href="http://kur.jp/wp-content/uploads/2010/01/image17.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://kur.jp/wp-content/uploads/2010/01/image_thumb5.png" width="467" border="0" /></a> </p>
				<p>LogTwitは下記のサイトから登録すれば誰でも使えるようになっていますので，実際に使ってみて，要望・感想など頂けると嬉しいです．ただし，Twitterのタイムラインがひどいことになると思われるので，1000PV/Day以上のWebサイトでお使いになるのはおススメしません．</p>
				<p><a href="http://logtwit.com/">LogTwit.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2010/01/15/logtwit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2010/01/15/logtwit/" />
	</item>
		<item>
		<title>PHPからTwitterに投稿する</title>
		<link>http://kur.jp/2009/12/28/php-twitter-update/</link>
		<comments>http://kur.jp/2009/12/28/php-twitter-update/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 17:18:39 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://kur.jp/2009/12/28/php-twitter-update/</guid>
		<description><![CDATA[				今さら出遅れた感も満載なんですが，Twitter連携のサービスを作ってみたくなったので，どうやったらTwitterAPIを使えるのか調べてみた．
				TwitterからPHPに投稿するためには，色々な方法があ [...]]]></description>
			<content:encoded><![CDATA[				<p>今さら出遅れた感も満載なんですが，Twitter連携のサービスを作ってみたくなったので，どうやったらTwitterAPIを使えるのか調べてみた．</p>
				<p>TwitterからPHPに投稿するためには，色々な方法があるみたいなんだけど，とりあえず手っ取り早い方法として，PEARパッケージの<a href="http://labs.transrain.net/products/services_twitter/">Services_Twitter</a>を利用することにしてみた．</p>
				<p> <span id="more-821"></span>
				<p>PEARパッケージのインストール自体は<a href="http://labs.transrain.net/products/services_twitter/">Services_Twitter</a>のサイトの通りにやればすぐに終わる．ただし，<a href="http://www.hawklab.jp/">Hawk氏のサイト</a>っていうのはすでに存在しないらしいので，注意．</p>
				<p>ただし，Jsphonは有志の方がサーバにアップしてくださっているので，下記からダウンロードできる．<a href="http://ryus.co.jp/modules/d3blog/details.php?bid=13">Jsphonをcodereposにアップロードしました。</a></p>
				<p>だが，実際にはPHP5.2.0以降であれば標準でJSON関数が入っているので，Jsphonはインストールしなくても特に不自由しないはず．</p>
				<p>実際に，このパッケージを使ってTwitterに投稿するにはこんな感じ．非常に簡単です．</p>
				<blockquote><p>include_once &#8216;Services/Twitter.php&#8217;;     <br />$service =&amp; new Services_Twitter(&#8216;username&#8217;, &#8216;password&#8217;);      <br />$service-&gt;setUpdate(&quot;test&quot;);</p>
				</blockquote>
				<p>これを使って，何か面白ものを作れないか，ちょっと考えているところです．</p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2009/12/28/php-twitter-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2009/12/28/php-twitter-update/" />
	</item>
		<item>
		<title>仮想シリアルポートを用いた快適デバッグ環境の構築</title>
		<link>http://kur.jp/2009/12/27/com0com/</link>
		<comments>http://kur.jp/2009/12/27/com0com/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 19:07:09 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kur.jp/2009/12/27/com0com/</guid>
		<description><![CDATA[				PCと他のデバイスを連携させて動作するアプリを開発するのって，実は結構面倒なんです．なので，いかにして効率よく開発するかが至上命題なわけです．
				あまりにも不便なので，こんな感じでUSB2シリアルケーブル2 [...]]]></description>
			<content:encoded><![CDATA[				<p>PCと他のデバイスを連携させて動作するアプリを開発するのって，実は結構面倒なんです．なので，いかにして効率よく開発するかが至上命題なわけです．</p>
				<p>あまりにも不便なので，こんな感じでUSB2シリアルケーブル2本と，クロスのメスーメスシリアルケーブルを使って，簡単な動作確認に使おうかなぁとか思っていました，</p>
				<p><a href="http://kur.jp/wp-content/uploads/2009/12/image12.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="220" alt="image" src="http://kur.jp/wp-content/uploads/2009/12/image_thumb.png" width="476" border="0" /></a></p>
				<p>で，これができるならパソコンの中に仮想的にCOMポートを作ってやって，それ同士で通信させれば良いんじゃないの？ということで，それっぽいソフトがないか探してみたところ，<a href="http://com0com.sourceforge.net/">Null-Modem emulator(com0com)</a>というソフトの存在を知りました．</p>
				<p> <span id="more-818"></span>
				<p>ところが，実際にインストールして使おうとして，私の愛用の仮想ターミナルエミュレータであるPoderosaから仮想COMポートに接続して送信しようとすると，「送信に失敗しました」と表示されてしまう．puttyなどからだと問題なく接続できるのに，なんでだろう．</p>
				<p><a href="http://kur.jp/wp-content/uploads/2009/12/image13.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="316" alt="image" src="http://kur.jp/wp-content/uploads/2009/12/image_thumb1.png" width="387" border="0" /></a> </p>
				</p>
				<p>Aki-H8などの開発にPoderosaを使っていたときや，KURO-RSなどの，他のシリアル通信を用いるデバイスと通信するときも，このようなエラーは出たことがなかったので，仮想COMに関係する問題なのかなぁとか思ったりもするのですが原因は不明．</p>
				<p>一応，調べてみると仮想COMポートと.Netの組み合わせは，いろいろ問題が報告されているっぽいですね．PoderosaもC#で.NetFramework上で動いてるので，そのあたりの問題なのかもしれません．</p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2009/12/27/com0com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2009/12/27/com0com/" />
	</item>
		<item>
		<title>MySQLでAuto Increment利用による速度低下</title>
		<link>http://kur.jp/2009/12/27/mysql-auto-increment/</link>
		<comments>http://kur.jp/2009/12/27/mysql-auto-increment/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 15:51:24 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://kur.jp/2009/12/27/mysql-auto-increment/</guid>
		<description><![CDATA[				Webアプリを開発する時に切っても切れない関係にあるのがMySQLなどのRBBMSです．これらをいかに上手に扱うかが，エンジニアリングの面白いところでもあり，難しいところでもあります．
				私は今までデータベ [...]]]></description>
			<content:encoded><![CDATA[				<p>Webアプリを開発する時に切っても切れない関係にあるのがMySQLなどのRBBMSです．これらをいかに上手に扱うかが，エンジニアリングの面白いところでもあり，難しいところでもあります．</p>
				<p>私は今までデータベースでテーブルの設計をするときには，各テーブルに通し番号を記憶するためのフィールドを作成して，Auto Incrementで番号を振っていました．</p>
				<p>こうしておくと，私が何も考えなくても（Insert文でNULLを指定しておけば），各レコードに連番が付与されるので，非常に便利です．</p>
				<p>ただ，知ってる人からすると当たり前じゃんと思われるかもしれませんが，Auto Increment属性を指定すると，Insertの速度が遅くなってしまうんですよね．というわけで，どれぐらい速度が遅くなるのか，実際に調べてみました．</p>
				<p> <span id="more-807"></span><br />
				<h2>実験環境</h2>
				<p>実験環境は下記のとおり．私の手元にあったSONY製のノートPC上にApache + PHP + MySQLをインストールしています．</p>
				<ul>
				<li>Sony VGN-Z90NS </li>
				<li>Microsoft Windows Vista </li>
				<li>Apache 2.2.12 </li>
				<li>PHP 5.3.0 </li>
				<li>MySQL 5.1.37 </li>
				</ul>
				<h2>実験コード</h2>
				<p>実験に利用したコードはこんな感じです．</p>
				<p>Auto Incrementありのテーブル定義</p>
				<blockquote><p>CREATE TABLE IF NOT EXISTS `autoinc` (      <br />&#160; `id` int(11) NOT NULL AUTO_INCREMENT,       <br />&#160; `data` text NOT NULL,       <br />&#160; PRIMARY KEY (`id`)       <br />) ENGINE=MyISAM&#160; DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;</p>
				</blockquote>
				<p>Auto Incrementありのテーブルに10000件のデータを突っ込むコード</p>
				<blockquote><p>list($micro, $Unixtime) = explode(&quot; &quot;, microtime());      <br />$time1 = $Unixtime + $micro;       <br />$pdo = new PDO($dsn, $db_username, $db_pass);       <br />$data&#160; = &quot;hoge&quot;;       <br />for($i = 0; $i &lt; 10000; $i++){       <br />&#160;&#160;&#160; try {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $stmt = $pdo-&gt;prepare(&quot;INSERT INTO autoinc (id,data) VALUES (NULL, :data)&quot;);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $stmt-&gt;bindParam(&quot;:data&quot;, $data);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $data = $stmt-&gt;execute();       <br />&#160;&#160;&#160; } catch(PDOException $e){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var_dump($e-&gt;getMessage());       <br />&#160;&#160;&#160; }       <br />}       <br />$pdo = null;       <br />list($micro, $Unixtime) = explode(&quot; &quot;, microtime());       <br />$time2 = $Unixtime + $micro;       <br />echo $time2 &#8211; $time1; </p>
				</blockquote>
				<p>Auto Incrementなしのテーブル定義</p>
				<blockquote><p>CREATE TABLE IF NOT EXISTS `noinc` (      <br />&#160; `id` int(11) NOT NULL,       <br />&#160; `data` text NOT NULL,       <br />&#160; PRIMARY KEY (`id`)       <br />) ENGINE=MyISAM DEFAULT CHARSET=latin1;</p>
				</blockquote>
				<p>Auto Incrementなしのテーブルに10000件のデータを突っ込むコード</p>
				<blockquote><p>list($micro, $Unixtime) = explode(&quot; &quot;, microtime());      <br />$time1 = $Unixtime + $micro;       <br />$pdo = new PDO($dsn, $db_username, $db_pass);       <br />$pdo-&gt;beginTransaction();       <br />$data&#160; = &quot;hoge&quot;;       <br />for($i = 0; $i &lt; 10000; $i++){       <br />&#160;&#160;&#160; try {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $stmt = $pdo-&gt;prepare(&quot;INSERT INTO noinc (id,data) VALUES (:id, :data)&quot;);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $stmt-&gt;bindParam(&quot;:id&quot;, $i);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $stmt-&gt;bindParam(&quot;:data&quot;, $data);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $data = $stmt-&gt;execute();       <br />&#160;&#160;&#160; } catch(PDOException $e){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var_dump($e-&gt;getMessage());       <br />&#160;&#160;&#160; }       <br />}       <br />$pdo-&gt;commit();       <br />$pdo = null;       <br />list($micro, $Unixtime) = explode(&quot; &quot;, microtime());       <br />$time2 = $Unixtime + $micro;       <br />echo $time2 &#8211; $time1; </p>
				</blockquote>
				<h2>実験の結果</h2>
				<p>上記のコードを用いて何度か実験して平均を取ってみたところ，こんな感じの結果になった．</p>
				<ul>
				<li>Auto Incrementあり：1.72秒</li>
				<li>Auto Incrementなし：1.52秒</li>
				</ul>
				<p>1割程度の差だが，明らかにAuto Incrementを利用することによって速度低下が起こっている．この1割の速度差を大きいと見るか，小さいと見るかについては，開発するアプリケーションの性質によって異なってくるものだと思うので，実際に，データのCreate，Read，Update，Deleteの頻度を考慮して検討すると良いと思います．</p>
				<p>最近，データベースは非常に奥が深いことがわかってきました．もっと真面目に勉強しないといけませんね．</p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2009/12/27/mysql-auto-increment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2009/12/27/mysql-auto-increment/" />
	</item>
		<item>
		<title>mixiアプリ開発の落とし穴</title>
		<link>http://kur.jp/2009/10/20/mixiappsec/</link>
		<comments>http://kur.jp/2009/10/20/mixiappsec/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 16:28:20 +0000</pubDate>
		<dc:creator>kur</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[MixiApp]]></category>
		<category><![CDATA[Securiy]]></category>

		<guid isPermaLink="false">http://kur.jp/2009/10/20/mixiappsec/</guid>
		<description><![CDATA[				mixiアプリが流行しているようです．
				参考：mixiアプリ効果 PC版mixi、9月のPV・滞在時間が急拡大
				この機会に，mixiアプリでも作ってみようかなという方も居るのではないでしょうか．
 [...]]]></description>
			<content:encoded><![CDATA[				<p>mixiアプリが流行しているようです．</p>
				<p>参考：<a href="http://www.itmedia.co.jp/news/articles/0910/19/news092.html">mixiアプリ効果 PC版mixi、9月のPV・滞在時間が急拡大</a></p>
				<p>この機会に，mixiアプリでも作ってみようかなという方も居るのではないでしょうか．</p>
				<p>そこで，Webアプリの開発に慣れていない人がmixiアプリを開発するにあたって，見落としがちなポイントについて紹介します．</p>
				<p><span id="more-736"></span></p>
				<h2>ソースコードは誰でも見ることができる．</h2>
				<p>mixiアプリのソースコードはJavaScriptです．JavaScriptは仕組み上，Webブラウザに読み込まれて，Webブラウザの上で動作します．ですので，誰でもがソースコードを読むことが可能だと思ってください．</p>
				<p>ですので，ソースコードにパスワードを直接記述したり，自作の暗号アルゴリズムを実装したり等は避けたほうが無難です．また，mixiアプリでゲームを開発する場合，アルゴリズム等が流出してしまうと，その知識をもとに高得点を狙うユーザも出現するでしょう．</p>
				<p>mixiアプリのソースコードは見られることを前提で，見られてまずい処理は自前でサーバを用意して処理する等が望ましいと思います．</p>
				<h2>ソースコードは誰でも書き換えることができる</h2>
				<p>mixiアプリは外部のサーバと通信を行うことが可能です．外部サーバにデータを渡して，何らかの処理を行い，外部サーバからデータを受け取るということで面白いアプリケーションを作ることも出来ると思います．</p>
				<p>この類のアプリケーションを実装するときに注意しなければいけないことは，サーバ側のプログラムでは，mixiアプリ（つまりWebブラウザ）から受け取る情報を一切信用してはいけないということです．</p>
				<p>詳しい手法を説明することはしませんが，クエリ文字列を含めて，mixiアプリからサーバに送信される情報は，自由に書きかえることができます．つまり，何らかの悪意のあるデータを含めることも可能であるということです．</p>
				<h2>mixi側に保存された情報は，誰でも簡単に読み取れる</h2>
				<p>mixiアプリでは，Key-Valueペアの文字列情報の永続化をサポートしています．これを利用することで，アプリに関する情報をmixiサーバに保存しておくことができるため，開発者側の歳ービス提供への負担を減らすことができます．</p>
				<p>が，注意しなければいけないことは，この情報にアクセス権は存在しないということです．</p>
				<p>mixiアプリのソースコードは誰でも書き換えが可能であるということを述べましたが，誰でもソースコードの書き換えが可能であるということは，誰でもが，mixi側に保存されている任意の人の情報を読み出すことができるということになります．（書き込みに関しては自分の情報に対してしか許可されていません）</p>
				<p>ですので，マイミクだけへの公開，全体への公開という公開範囲をmixiアプリ側で設定しても，少し知識がある人がソースコードを書き換えれば，情報を読み出すことが可能です．ですので，mixi側に保存する情報に関しては万全の注意が必要です．</p>
				<h2>おわりに</h2>
				<p>以上，Webアプリ開発経験のある方からすれば基本的なことかもしれませんが，これまでWebアプリ開発の経験がないけどmixiアプリに挑戦してみようという方が陥りやすそうなポイントを3つほど書いてみました．実際には，気をつけなければいけないポイントは他にも色々ありあます．</p>
				<p>もし，興味がある方は，それ用の本を購入するなどして，読んで頂ければ良いんじゃないかと思います．そして，多くの方がセキュリティに配慮した上で，面白いアプリを開発してくださることを期待しています．</p>
]]></content:encoded>
			<wfw:commentRss>http://kur.jp/2009/10/20/mixiappsec/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://kur.jp/2009/10/20/mixiappsec/" />
	</item>
	</channel>
</rss>
