<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>X-LABO</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.dango-itimi.com/blog/atom.xml" />
   <id>tag:www.dango-itimi.com,2012:/blog//1</id>
    <link rel="service.post" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1" title="X-LABO" />
    <updated>2012-01-30T04:11:29Z</updated>
    <subtitle>団子一味によるFlash実験Blog</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type  3.2-ja-2</generator>
 
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の七 ボール増殖と表示倍率設定</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2012/001103.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1103" title="Box2DFlash v2.1a : ピンボール 其の七 ボール増殖と表示倍率設定" />
    <id>tag:www.dango-itimi.com,2012:/blog//1.1103</id>
    
    <published>2012-01-30T03:43:59Z</published>
    <updated>2012-01-30T04:11:29Z</updated>
    
    <summary>ボール増殖処理を組み込み。 [MOVE]と表示されている箇所の穴にボールが入ると...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>ボール増殖処理を組み込み。<br />
[MOVE]と表示されている箇所の穴にボールが入ると画面内にボールが一つ追加されます。</p>

<p>実験として ボール増殖量には制限をかけておらず、一度ボールが増えると とてもにぎやかな画面になります。もはや何のゲームかわからないほどです。</p>

<p>　<img src="http://www.dango-itimi.com/blog/swf/151/1.png" /> <img src="http://www.dango-itimi.com/blog/swf/151/2.png" /></p>

<p>また、今回より swf 表示倍率(100% or 200%)の設定をプレイヤーが任意に行えるようにしました。200% の表示倍率のものを ノート PC で確認してみたところ、表示がたいへんゆっくりしたものになってしまっていたからです。</p>

<p>■ 操作説明</p>

<p>swf 画面クリック後 以下のキーで操作を行います。</p>

<p>フリッパー操作 : 左右キー<br />
画面振動 : 上キー<br />
100%表示(画面動作が遅い方向け) : 1キー<br />
200%表示 : 2キー<br />
</p>]]>
        <![CDATA[<p><script language="javascript">swfobject.embedSWF('http://www.dango-itimi.com/blog/swf/151/preloader.swf', 'swf_view', '488', '608', '10', '', {}, {base:"http://www.dango-itimi.com/blog/swf/151/"});</script></p>

<div>
	<div id="swf_view">[ ここに swf が表示されます ]</div>
</div>]]>
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の六 ゲームテンポ上昇と動作対象オブジェクトのすり抜け対策(CCD)</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2012/001102.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1102" title="Box2DFlash v2.1a : ピンボール 其の六 ゲームテンポ上昇と動作対象オブジェクトのすり抜け対策(CCD)" />
    <id>tag:www.dango-itimi.com,2012:/blog//1.1102</id>
    
    <published>2012-01-16T07:14:32Z</published>
    <updated>2012-01-16T07:34:42Z</updated>
    
    <summary>「ピンボールゲームの楽しさとは何たるか」を調査するために、無料で遊べるピンボール...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>「ピンボールゲームの楽しさとは何たるか」を調査するために、無料で遊べるピンボールゲームを片っ端からプレイしてみました。結果 一番楽しめたのは、長いフリッパーで勢いよく次々とボールを弾きまくるピンボールゲームでした。ふんわり浮くボールが画面内で弾かれる様を長く眺めているよりも、自分で頻繁に弾いて操作するほうが遊んでいる感が強いのかもしれません。</p>

<p>というわけで今回のサンプルでは、ボール落下速度を上げフリッパーの長さを増加し、ゲームテンポの向上を行なってみました。</p>

<h5>動作対象オブジェクトのすり抜け対策</h5>

<p>ボール落下速度を上げてみると、ボールがフリッパーをすり抜けてしまうという問題が発生。<br />
何か設定が足りないところはないか ネット上で「Box2D すり抜け」といった単語で調べてみたところ、以下の情報が見つかりました。</p>

<p>動作対象オブジェクト(b2Body)の b2BodyDef.bullet プロパティを true に設定すれば解決との事です。</p>

<pre>
bodyDef.bullet = true;
</pre>

<p>すり抜け対処のための衝突判定を continuous collision detection(CCD) と呼ぶ模様。Box2DFlash v2.1a 用のマニュアルではありませんが、以下の Box2D manual の Bullets の項目に説明がありました。</p>

<p>　Box2D v2.2.0 User Manual<br />
　<a href="http://www.box2d.org/manual.html" target="_blank">http://www.box2d.org/manual.html</a></p>

<p>ただし、この機能を利用すると負荷が増えるため、フレームレートが下がる原因となります。低スペックなPCほど影響がでてきます。<br />
</p>]]>
        <![CDATA[<h5>サンプル</h5>

<p>swf 画面クリック後 以下のキーで操作を行います。</p>

<p>フリッパー操作 : 左右キー<br />
PAUSE : スペースキー<br />
画面振動 : 上キー</p>

<p><script language="javascript">swfobject.embedSWF('http://www.dango-itimi.com/blog/swf/150/preloader.swf', 'swf_view', '480', '600', '10', '', {}, {base:"http://www.dango-itimi.com/blog/swf/150/"});</script></p>

<div style="border:solid 5px #000000; width: 480px">
	<div id="swf_view">[ ここに swf が表示されます ]</div>
</div>

<p>画面中央のスロット得点文字は ボールを見失う原因となってしまうため、後に修正を行います。<br />
</p>]]>
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の五 演出微強化</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2012/001101.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1101" title="Box2DFlash v2.1a : ピンボール 其の五 演出微強化" />
    <id>tag:www.dango-itimi.com,2012:/blog//1.1101</id>
    
    <published>2012-01-09T10:00:34Z</published>
    <updated>2012-01-09T10:04:46Z</updated>
    
    <summary>かぼちゃ風オブジェクト追加や得点表示拡大等、演出を少しずつ追加中。  ...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>かぼちゃ風オブジェクト追加や得点表示拡大等、演出を少しずつ追加中。</p>

<p><img src="http://www.dango-itimi.com/blog/swf/149/1.png" /> <img src="http://www.dango-itimi.com/blog/swf/149/2.png" /></p>]]>
        <![CDATA[<p>■ 操作説明</p>

<p>swf 画面クリック後 以下のキーで操作を行います。</p>

<p>フリッパー操作 : 左右キー<br />
PAUSE : スペースキー<br />
画面振動 : 上キー</p>

<p><script language="javascript">swfobject.embedSWF('http://www.dango-itimi.com/blog/swf/149/preloader.swf', 'swf_view', '480', '600', '10', '', {}, {base:"http://www.dango-itimi.com/blog/swf/149/"});</script></p>

<div style="border:solid 5px #000000; width: 480px">
	<div id="swf_view">[ ここに swf が表示されます ]</div>
</div>

<p>発射台から弾が発射されない不具合があり原因調査中です。</p>]]>
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の四 カジノ風BGM・他</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001099.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1099" title="Box2DFlash v2.1a : ピンボール 其の四 カジノ風BGM・他" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1099</id>
    
    <published>2011-12-30T09:46:43Z</published>
    <updated>2011-12-30T09:48:44Z</updated>
    
    <summary>団子一味のメインテーマをカジノ風にしてみた BGM に差し替えました。 その他、...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>団子一味のメインテーマをカジノ風にしてみた BGM に差し替えました。<br />
その他、ゲーム画面内上部の扉を開けるとランプに火がつき、３つ全てのランプに火がつくと、得点が倍になるような処理を組み込んでいます。</p>

<p>また、今回より swf 画面を二倍に拡大して表示するようにしています。</p>

<p><br />
</p>]]>
        <![CDATA[<p>■ 操作説明</p>

<p>swf 画面クリック後 以下のキーで操作を行います。</p>

<p>フリッパー操作 : 左右キー<br />
PAUSE : スペースキー<br />
画面振動 : 上キー</p>

<p><script language="javascript">swfobject.embedSWF('http://www.dango-itimi.com/blog/swf/148/preloader.swf', 'swf_view', '480', '600', '10', '', {}, {base:"http://www.dango-itimi.com/blog/swf/148/"});</script></p>

<div id="swf_view">[ ここに swf が表示されます ]</div>]]>
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の三 BGM</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001097.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1097" title="Box2DFlash v2.1a : ピンボール 其の三 BGM" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1097</id>
    
    <published>2011-12-24T08:32:30Z</published>
    <updated>2011-12-24T08:49:16Z</updated>
    
    <summary>少しずつ合間合間に手を加えています。 今回は「クリスマス風」になっているかどうか...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>少しずつ合間合間に手を加えています。<br />
今回は「クリスマス風」になっているかどうかわかりませんが、それっぽい BGM (約 500KB)を作成し組み込んでみました。</p>

<p>　<a href="http://www.dango-itimi.com/blog/swf/147/preloader.swf" target="_blank"><img src="http://www.dango-itimi.com/blog/swf/147/img.png" /></a><br />
　<a href="http://www.dango-itimi.com/blog/swf/147/preloader.swf" target="_blank">http://www.dango-itimi.com/blog/swf/147/preloader.swf</a></p>

<p>■ 操作説明</p>

<p>swf 画面クリック後 以下のキーで操作を行います。</p>

<p>フリッパー操作 : 左右キー<br />
PAUSE : スペースキー<br />
画面振動 : 上キー</p>]]>
        
    </content>
</entry>
<entry>
    <title>GAE 1.6.0 : python 2.7 PyCrypto ImportError</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001096.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1096" title="GAE 1.6.0 : python 2.7 PyCrypto ImportError" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1096</id>
    
    <published>2011-12-08T07:20:03Z</published>
    <updated>2011-12-14T05:15:50Z</updated>
    
    <summary>最近 Google App Engine(GAE) では python 2.7 ...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>最近 Google App Engine(GAE) では python 2.7 が利用可能になったため、新しく python 2.7 用にアプリケーションを作成してみたところ、PyCrypto のモジュールをインポートする箇所でエラーが発生してしまう事がわかりました。</p>

<p>例えば以下の一行を記述するだけで、GAE のサーバ上では ImportError が発生してしまいます。</p>

<pre>
import Crypto.Cipher
</pre>

<p>python 2.5 のアプリケーションでは上記記述を行なっても問題なく動作します。GAE python 2.7 では何か別の記述が必要なのでしょうか？</p>

<p>行なった検証手順は、以下の URL にある「Hello, World!」を表示するだけのアプリケーションの二行目に「import Crypto.Cipher」を追加しただけ、となります。</p>

<p><a href="http://code.google.com/intl/en/appengine/docs/python/gettingstartedpython27/helloworld.html" target="_blank">http://code.google.com/intl/en/appengine/docs/python/gettingstartedpython27/helloworld.html</a></p>

<p>Dashboard から確認可能なログに出力されたエラー内容<br />
<pre>
Traceback (most recent call last):
  File &quot;/base/python27_runtime/python27_lib/versions/1/google/appengine/runtime/wsgi.py&quot;, line 168, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File &quot;/base/python27_runtime/python27_lib/versions/1/google/appengine/runtime/wsgi.py&quot;, line 206, in _LoadHandler
    handler = __import__(path[0])
  File &quot;/base/data/home/apps/s~test-crypto/1.355228157185667132/helloworld.py&quot;, line 2, in &lt;module&gt;
    import Crypto.Cipher
ImportError: No module named Crypto.Cipher
</pre></p>

<p>現状解決策が見つからないため、python 2.5 用のアプリケーションを別途作成しそちらで開発を進めることに。</p>

<p><b>追記)</b><br />
<a href="https://groups.google.com/forum/embed/?place=forum/google-appengine-python&showsearch=true&showpopout=true&parenturl=http://code.google.com/intl/ja/appengine/forum/python-forum.html?place%3Dforum/google-appengine-python#!searchin/google-appengine-python/ImportError/google-appengine-python/jUbJnkQmi2A/A0elOPMncOUJ" target="_blank">GAE フォーラム「1.6.1 Pre-release SDKs are live」のスレッド</a>内記述に以下の項目を発見。</p>

<pre>
- Fixed an issue in the SDK where importing Crypto.Util.Counter caused an
  ImportError.
</pre>

<p>今回の ImportError は次回バージョンで解決されるのかな？</p>

<p><b>追記2 2011/12/14)</b><br />
本日 GAE 1.6.1 がリリースされたとのことで再度検証してみましたが、同じエラーが発生。<br />
ちなみに Windows ローカル開発環境上では import Crypto.Cipher という記述ではエラーは発生しませんが、import Crypto.Cipher.DES という記述を行なうとエラーが発生します。</p>

<p><b>追記3 2011/12/14)</b><br />
問題ほぼ解決。<br />
python2.7 では外部ライブラリを用いる際、app.yaml に追記が必要なことがわかりました。<br />
今回の場合、以下の記述を行えばサーバ上で ImportError は発生しなくなりました。</p>

<pre>
libraries:
- name: pycrypto
  version: latest
</pre>

<p>GAE ドキュメントをしっかり読んでいなかった私のミスでした。<br />
残りの問題は、Windows ローカル開発環境上での ImportError のみ、となります。<br />
Windows Vista 上での ImpoerError は以下のような記述になっています。</p>

<pre>
ImportError: DLL load failed: %1 は有効な Win32 アプリケーションではありません。
</pre>

<p>ファイル権限が関係している感じがします。引き続き調査を行います。<br />
もしかしたら「GAEローカル開発環境では python 2.7 はまだサポートされていない」という事に対するエラーの可能性あり。<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>GAE : Google アカウントによる Flash(swf) 内データ保存から ユーザ独自の URL 発行  </title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001095.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1095" title="GAE : Google アカウントによる Flash(swf) 内データ保存から ユーザ独自の URL 発行  " />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1095</id>
    
    <published>2011-12-02T08:26:33Z</published>
    <updated>2011-12-02T08:44:36Z</updated>
    
    <summary>Google App Engine(GAE)にて、以下の処理動作を行うサンプルア...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>Google App Engine(GAE)にて、以下の処理動作を行うサンプルアプリケーションを作成しました。</p>

<p>・swf 内データを Google アカウントを用いて GAE のデータストアに記録<br />
・記録されたデータを元に Google アカウントユーザ毎の独自 URL の発行</p>

<p>サンプルアプリケーション URL <br />
<a href="http://dango-itimi.appspot.com/crypto_test/" target="_blank">http://dango-itimi.appspot.com/crypto_test/</a></p>

<p>SCORE 欄 に最大 5桁の数値を入力し登録ボタンを押すと処理が開始します。使用しているブラウザで Google アカウントにログイン中の場合、GAE サーバ上に入力した数値が記録され、ログインしていない場合 ログインを促す画面が表示されます。</p>

<p>数値を登録した Google アカウントには アプリケーション上で ユニークID が割り振られ、http://dango-itimi.appspot.com/crypto_test/home/ユニークID/ という URL で、記録された数値を誰からも閲覧することができるようになります。</p>

<p>Google アカウント情報から取得可能な情報(<a href="http://code.google.com/intl/ja/appengine/docs/python/users/userclass.html#User_user_id" target="_blank">ユーザID</a>)はハッシュ化(暗号化)して利用しており、どの Google アカウントがこのサンプルアプリケーションを利用したのか等の情報は 管理人の私でもわからないようにしています。数値を登録するだけの大した内容ではありませんが、お気軽にご利用ください。</p>

<h5>GAE と Google アカウント</h5>

<p>GAE には Google アカウントと紐付けたアプリケーションの作成を比較的簡単に行うことができる仕組みがあります。何かユーザサービスを作成したい場合、GAE と Google アカウントを利用する事で、アプリケーション作成者はユーザのアカウント管理システムを作成する必要はなくなります。私のようなサーバ側の知識はほとんどない Flash 開発者にとっては、この仕組は非常に大きいです。アカウント管理は Google にまかせ、コンテンツ制作に力をそそぐことができます。</p>

<p>現在 Google アカウントを取得するには電話番号確認が必須となっています。(IP によっては電話番号は必須にならないケースもあるとの情報も見かけます)<br />
Web サービスに Google アカウントを利用するメリットとして、ユーザの唯一性が保ちやすいという点が挙げられます。例えば何かの投票サービスを作成する場合、一人が多数のアカウントを利用してたくさんの投票を行う、という事態を避ける事ができます。<br />
デメリットとしては、電話番号が必須のため アカウント作成にやや手間がかかるという点が挙げられます。サービスにログインしようとしたら、Google アカウントが必須な事がわかり、アカウントを取得するには電話番号が必須、となると「これはめんどうだ」という事で、ユーザを逃してしまう可能性がでてきます。簡単なゲーム等では、ログインはしなくても遊ぶことは可能で、スコア登録を行う場合のみログインが必要である、といった工夫が必要となりそうです。</p>

<h5>暗号・難読化</h5>

<p>Flash(swf) とサーバ(GAE)とで通信を行う箇所では、調査した以下の記事の内容を元に暗号化通信を行なっています。</p>

<p>・<a href="http://www.dango-itimi.com/blog/archives/2011/001091.html">暗号化調査</a><br />
・<a href="http://www.dango-itimi.com/blog/archives/2011/001093.html">暗号化調査2 : as3crypto ←→ PyCrypto : DES, AES, RSA</a><br />
・<a href="http://www.dango-itimi.com/blog/archives/2011/001094.html">暗号化調査3 : Crypto.getCipher メソッドの利用 : DES, AES 修正版</a></p>

<p>また、<a href="http://www.kindi.com/" target="_blank">secureSWF</a> を導入し、swf の難読化を行なっています。(現在円高なので secureSWF は割とリーズナブルなお値段になっているかもしれません。)</p>

<p>python 側(PyCrypto)で RSA 暗号化したデータを as3 側(as3Crypto)で復号可能であれば もう少し安全な暗号化通信を行えそうなのですが、ここは残念なところです。</p>

<p>今回行なった通信内容のデータ改ざん対策の他、ゲーム等ではメモリ操作によるチート対策も必須となりそうです。</p>

<p>　参考 : Flashゲームのチート対策 | NJF <br />
　<a href="http://njf.jp/?p=999" target="_blank">http://njf.jp/?p=999</a></p>

<h5>今後</h5>

<p>複数の swf からでもデータ登録を可能にするシステムへ修正予定。汎用性をもたせたライブラリ化を図ります。</p>

<p>サーバ・ユーザアカウント管理問題や swf 解析問題により、今までは諦めてしまっていた事が多々ありました。「それを行うにはサーバ側を専門としている会社が必要」であったり「swf は解析されてしまうから、それを Flash で行うには避けたほうがよい」等々。<br />
GAE の利用や、暗号・難読化により、これら問題は解決してきているのではないかと思います。<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>暗号化調査3 : Crypto.getCipher メソッドの利用 : DES, AES 修正版</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001094.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1094" title="暗号化調査3 : Crypto.getCipher メソッドの利用 : DES, AES 修正版" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1094</id>
    
    <published>2011-12-01T01:53:13Z</published>
    <updated>2011-12-01T07:45:51Z</updated>
    
    <summary>前回の記事「暗号化調査2 : as3crypto ←→ PyCrypto : D...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>前回の記事「<a href="http://www.dango-itimi.com/blog/archives/2011/001093.html">暗号化調査2 : as3crypto ←→ PyCrypto : DES, AES, RSA</a>」を元に、as3 と python とで暗号化通信を行うサンプル制作を進めていた所、PyCrypto 側で DES 暗号化したデータを as3crypto 側で DES 復号できないケースがある事に気づきました。<br />
8 byte 丁度の文字列は DES 復号可能でしたが、16 byte といった 8 byte より大きな文字列の復号が正常に行われませんでした。</p>

<p>調査の結果、AS3 版 SymmetricCrypter クラス内に問題があったため以下のように修正を行いました。</p>

<pre>

package com.dango_itimi.crypto {

	import com.hurlant.crypto.symmetric.IPad;
	import com.hurlant.crypto.symmetric.NullPad;
	import com.hurlant.crypto.symmetric.ICipher;
	import com.hurlant.crypto.Crypto;
	import com.hurlant.util.Base64;
	import com.hurlant.util.Hex;
	import flash.utils.ByteArray;
	
	public class SymmetricCrypter {

		private var crypter:ICipher;

		public static function createDESCrypter(key:String):SymmetricCrypter {
			
			return new SymmetricCrypter(&quot;des-ecb&quot;, key, new NullPad());
		}
		public static function createAESCrypter(key:String):SymmetricCrypter {
			
			return new SymmetricCrypter(&quot;aes-128-ecb&quot;, key, new NullPad());
		}
		public function SymmetricCrypter(cipherName:String, key:String, pad:IPad = null) {
			
			var keyBin:ByteArray = Hex.toArray(Hex.fromString(key));
			crypter = Crypto.getCipher(cipherName, keyBin, pad);
		}
		
		public function encrypt(plainText:String):String {
			
			var textBin:ByteArray = Hex.toArray(Hex.fromString(plainText));
			crypter.encrypt(textBin);
			
			var cipherText:String = Base64.encodeByteArray(textBin);
			return cipherText;
		}
		public function decrypt(cipherText:String):String {
			
			var decodedTextBin:ByteArray = Base64.decodeToByteArray(cipherText);
			crypter.decrypt(decodedTextBin);	
			
			var decryptedText:String = Hex.toString(Hex.fromArray(decodedTextBin));
			return decryptedText;
		}
	}
}

</pre>

<p>DESKey, AESKey クラスインスタンスを直接作成するのではなく、Crypto クラスの getCipher メソッド経由で DES, AES 処理を行うためのクラスインスタンスを取得するように変更を行なっています。</p>

<h5>Crypto.getCipher メソッド第一引数</h5>

<p>Crypto.getCipher メソッド第一引数にどういった文字列を指定すればよいかは Crypto.getCipher メソッドのコメントに記述があります。</p>

<p>引用 : com.hurlant.crypto.Crypto クラス getCipher メソッドコメント<br />
<pre>

/**
 * Things that should work, among others:
 *  &quot;aes&quot;
 *  &quot;aes-128-ecb&quot;
 *  &quot;aes-128-cbc&quot;
 *  &quot;aes-128-cfb&quot;
 *  &quot;aes-128-cfb8&quot;
 *  &quot;aes-128-ofb&quot;
 *  &quot;aes-192-cfb&quot;
 *  &quot;aes-256-ofb&quot;
 *  &quot;blowfish-cbc&quot;
 *  &quot;des-ecb&quot;
 *  &quot;xtea&quot;
 *  &quot;xtea-ecb&quot;
 *  &quot;xtea-cbc&quot;
 *  &quot;xtea-cfb&quot;
 *  &quot;xtea-cfb8&quot;
 *  &quot;xtea-ofb&quot;
 *  &quot;rc4&quot;
 *  &quot;simple-aes-cbc&quot;
 */
public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
	…
}

</pre></p>

<p>python 側では、DES 暗号化モード? に MODE_ECB と設定したので、as3 側でも同じく ECB モードに設定するために "des-ecb" という文字列を指定しました。</p>

<h5>Crypto.getCipher メソッド第三引数の注意点</h5>

<p>Crypto.getCipher メソッド第三引数には Padding 方法を指定します。</p>

<p>「<a href="http://crypto.hurlant.com/demo/" target="_blank">AS3 Crypto Demo page</a>」の Secret Key タブ内 Padding: 選択フォームを見ると「PKCS#5」「NONE」二種類の Padding 方法を選択できる事がわかります。Padding: に「NONE」を選択すると、前回作成した python 側での DES 暗号化した文字列の復号が可能となります。</p>

<p>Padding は「NONE」なのだから、Crypto.getCipher メソッド第三引数にデフォルトで設定されている null を指定すればよいのではないか、と考えてしまいそうですが、null を指定すると「PKCS#5」方式が選択されてしまう点にご注意ください。Padding に「NONE」を指定するには、NullPad クラスインスタンスを設定すればよいようです。</p>

<p><br />
引用 : com.hurlant.crypto.symmetric.ECBMode クラスコンストラクタ 注意点<br />
<pre>

public function ECBMode(key:ISymmetricKey, padding:IPad = null) {
	this.key = key;
	if (padding == null) {
		padding = new PKCS5(key.getBlockSize());
	} else {
		padding.setBlockSize(key.getBlockSize());
	}
	this.padding = padding;
}

</pre><br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>暗号化調査2 : as3crypto ←→ PyCrypto : DES, AES, RSA</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001093.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1093" title="暗号化調査2 : as3crypto ←→ PyCrypto : DES, AES, RSA" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1093</id>
    
    <published>2011-11-10T04:39:31Z</published>
    <updated>2011-11-30T12:18:08Z</updated>
    
    <summary>前回の「暗号化調査」記事の続きです。 Action Script 3(AS3),...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>前回の<a href="http://www.dango-itimi.com/blog/archives/2011/001091.html">「暗号化調査」</a>記事の続きです。<br />
Action Script 3(AS3), python 双方向に暗号化通信を目的とした、共通鍵暗号方式(DES, AES)と公開鍵暗号方式(RSA)のプログラミングに関する調査が完了しました。</p>

<h5>環境</h5>

<p>AS3 側は as3crypto という暗号化用ライブラリを用いています。as3crypto.swc バージョン 1.3 と、svnリポジトリにある最新バージョンのソースファイル一式 両方で検証しました。</p>

<p>python 側は Google App Engine がデフォルトでサポートしている PyCrypto という暗号化ライブラリを用いました。python のバージョンは 2.5.2, PyCrypto のバージョンは 2.0.1 となります。最近 GAE でサポートされた python 2.7, PyCrypto 2.3 でも動作検証を行っています。</p>

<p>　as3crypto<br />
　<a href="http://code.google.com/p/as3crypto/" target="_blank">http://code.google.com/p/as3crypto/</a></p>

<p>　PyCrypto<br />
　<a href="https://www.dlitz.net/software/pycrypto/" target="_blank">https://www.dlitz.net/software/pycrypto/</a></p>

<p>　windows 用 PyCrypto 2.0.1 ダウンロード URL<br />
　<a href="http://www.voidspace.org.uk/python/modules.shtml#pycrypto" target="_blank">http://www.voidspace.org.uk/python/modules.shtml#pycrypto</a></p>

<h5>調査結果</h5>

<p>AS3, python 共にネット上にサンプルソースが載っていた、共通鍵暗号方式(DES, AES)と公開鍵暗号方式(RSA)についてプログラミング調査を行ないました。共通鍵暗号方式の AS3, python 双方向暗号化に対しては、特に問題は発生せず、意図通りの動作となりました。</p>

<p>しかし公開鍵暗号方式(RSA)で問題が発生。AS3 側で暗号化したデータを python 側で復号する事は成功しましたが、python 側で暗号化したデータを AS3 側で復号する事ができませんでした。as3crypto の復号処理でエラーが発生してしまいます。</p>

<p>何が問題か as3crypto, PyCrypto 両方共に調査を行なってみましたが、ネット上の資料はあまり多くは見つからず、はっきりとした原因はわかりませんでした。どうも、RSA 暗号化方式にはパディング処理という物がいくつかあり、PyCrypto の採用しているパディング処理に対し as3crypto の復号処理が対応していないっぽい、という感じがします。それらしきキーワードが書かれていた英語の質問フォーラムの記述を断片的につなげてみただけなので、めちゃくちゃ言ってしまっているかもしれません。PyCrypto の RSA 暗号処理は PKCS#1 v1.5？方式で、as3crypto ではそれは解析できないとかどうとか、まだよく分かっていません。</p>

<p>「環境」の項目に記述した as3crypto, PyCrypto 二種類のバージョンで検証を行いましたが、動作の違いはなく問題は解決しませんでした。</p>

<p>as3crypto の復号処理で、「どういう復号処理を行うか」を指定できる箇所(RSAKey.decrypto メソッドの第四引数)があり、そこに pycrypto で暗号化したデータを復号するための独自のメソッドを指定すれば問題は解決しそうではあります。しかし別途、復号アルゴリズムの勉強を行わなくてはならなそうなので、python → AS3 への RSA 暗号化通信に関しては保留としたいと思います。</p>

<h5>参考サイト</h5>

<p>　■ AS3<br />
　<a href="http://blog.suz-lab.com/2009/01/as3.html" target="_blank">AS3で暗号/復号化 : suz-lab</a><br />
　<a href="http://blog.suz-lab.com/2009/01/as3rsa.html" target="_blank">AS3で暗号/復号化(RSA版) : suz-lab</a><br />
　<a href="http://kyucon.com/blog/2009/06/as30-rsa.html" target="_blank">RSA暗号化して通信経路途中での改ざんを防止 : KYUCON*BLOG</a><br />
　<br />
　■ python<br />
　<a href="http://d.hatena.ne.jp/yutakikuchi/20110207/1297070966" target="_blank">Pythonでの暗号化/復号化(AEC-DES,RSA) : YutaKikuchiのTechBlog</a><br />
　<a href="http://yoshi-python.blogspot.com/2009/10/pycrypto.html" target="_blank">PyCryptoで暗号化する : Pythonメモ</a></p>

<p>　■ ツール<br />
　<a href="http://crypto.hurlant.com/demo/" target="_blank">AS3 Crypto Demo page</a></p>

<h4>サンプルソースコード</h4>

<p>暗号化・復号用クラスと検証用クラスのソース一式は以下となります。AS3, python 共にロジックはほぼ同じです。</p>

<p>暗号化対象の文字列を暗号化し Base64エンコードするまでを encryptメソッドで行い、Base64エンコードされた暗号化文字列を 暗号化されていない文字列にまで復号するまでの処理を decrypt メソッドで行なっています。</p>]]>
        <![CDATA[<h5>AS3 : DES, AES</h5>

<p>AS3 で共通鍵暗号方式(DES, AES)を行うためのクラス SymmetricCrypter<br />
<pre>
package crypto_test {

	import com.hurlant.crypto.symmetric.AESKey;
	import com.hurlant.crypto.symmetric.DESKey;
	import com.hurlant.util.Base64;
	import com.hurlant.crypto.symmetric.ISymmetricKey;
	import com.hurlant.util.Hex;
	import flash.utils.ByteArray;
	
	public class SymmetricCrypter {

		private var crypter:ISymmetricKey;

		public static function createDESCrypter(key:String):SymmetricCrypter {
			
			return new SymmetricCrypter(DESKey, key);
		}
		public static function createAESCrypter(key:String):SymmetricCrypter {
			
			return new SymmetricCrypter(AESKey, key);
		}
		public function SymmetricCrypter(crypterClass:Class, key:String) {
			
			var keyBin:ByteArray = Hex.toArray(Hex.fromString(key));
			crypter = new crypterClass(keyBin);
		}
		
		public function encrypt(plainText:String):String {
			
			var textBin:ByteArray = Hex.toArray(Hex.fromString(plainText));
			crypter.encrypt(textBin);
			
			var cipherText:String = Base64.encodeByteArray(textBin);
			return cipherText;
		}
		public function decrypt(cipherText:String):String {
			
			var decodedTextBin:ByteArray = Base64.decodeToByteArray(cipherText);
			crypter.decrypt(decodedTextBin);	
			
			var decryptedText:String = Hex.toString(Hex.fromArray(decodedTextBin));
			return decryptedText;
		}
	}
}
</pre></p>

<p>SymmetricCrypter クラスの検証用クラス<br />
<pre>
package crypto_test {
	
	public class SymmetricCryptoTester {

		public function test():void {
			
			testDES();
			testAES();
		}
		private function testDES():void {
			
			trace(&quot;--- testDES ---&quot;);
			
			testCmn(SymmetricCrypter.createDESCrypter(&quot;abcdefgh&quot;), &quot;ohayou12&quot;);
		}
		private function testAES():void {
			
			trace(&quot;--- testAES ---&quot;);
			
			testCmn(SymmetricCrypter.createAESCrypter(&quot;aaaaaaaabbbbbbbb&quot;), &quot;ohayou12konbanwa&quot;);
		}

		private function testCmn(crypter:SymmetricCrypter, plainText:String):void {
			
			var cipherText:String = crypter.encrypt(plainText);
			trace('cipherText: ' + (cipherText));
			
			var decryptedText:String = crypter.decrypt(cipherText);
			trace('decryptedText: ' + (decryptedText));
		}
	}
}
</pre></p>

<p>SymmetricCryptoTester の実行結果<br />
<pre>
--- testDES ---
cipherText: jKbIR+rbJ8w=
decryptedText: ohayou12
--- testAES ---
cipherText: 96JhvLji/Bi7as61vYAO2g==
decryptedText: ohayou12konbanwa
</pre></p>

<h5>python : DES, AES</h5>

<p>python で共通鍵暗号方式(DES, AES)を行うためのクラス SymmetricCrypter<br />
<pre>
import Crypto.Cipher.DES as DES
import Crypto.Cipher.AES as AES
import base64

def createDESCrypter(key):
	
	return SymmetricCrypter(DES, key)

def createAESCrypter(key):
	
	return SymmetricCrypter(AES, key)

class SymmetricCrypter:
	
	def __init__(self, crypterClass, key):
		
		self.__crypter = crypterClass.new(key, crypterClass.MODE_ECB)

	def encrypt(self, plainText):
		
		encryptedTextBin = self.__crypter.encrypt(plainText)
		encodedText = base64.b64encode(encryptedTextBin)
		return encodedText

	def decrypt(self, cipherText):

		decodedTextBin = base64.b64decode(cipherText)
		decryptedText = self.__crypter.decrypt(decodedTextBin)
		return decryptedText
</pre></p>

<p>SymmetricCrypter クラスの検証用クラス<br />
<pre>
import SymmetricCrypter

class SymmetricCryptoTester:
	
	def test(self):
		
		self.__testDES()
		self.__testAES()

	def __testDES(self):
		
		print &quot;--- testDES ---&quot;
		
		self.__testCmn(
			SymmetricCrypter.createDESCrypter(&quot;abcdefgh&quot;), &quot;ohayou12&quot;)

	def __testAES(self):

		print &quot;--- testAES ---&quot;
		
		self.__testCmn(
			SymmetricCrypter.createAESCrypter(&quot;aaaaaaaabbbbbbbb&quot;), &quot;ohayou12konbanwa&quot;)
	
	def __testCmn(self, crypter, plainText):
		
		cipherText = crypter.encrypt(plainText)
		print &quot;cipherText: &quot; + cipherText
		
		decryptedText = crypter.decrypt(cipherText)
		print &quot;decryptedText: &quot; + decryptedText

if __name__ == '__main__':
	tester = SymmetricCryptoTester()
	tester.test()
</pre></p>

<p>SymmetricCryptoTester の実行結果<br />
<pre>
--- testDES ---
cipherText: jKbIR+rbJ8w=
decryptedText: ohayou12
--- testAES ---
cipherText: 96JhvLji/Bi7as61vYAO2g==
decryptedText: ohayou12konbanwa
</pre></p>

<p>AS3, python ともに実行結果は同じとなります。よって双方向暗号化処理に問題はありません。</p>

<h5>AS3 : RSA</h5>

<p>AS3 で公開鍵暗号方式(RSA)を行うためのクラス RSACrypter<br />
<pre>
package crypto_test {

	import com.hurlant.util.Base64;
	import com.hurlant.crypto.rsa.RSAKey;
	import com.hurlant.util.Hex;
	import flash.utils.ByteArray;
	
	public class RSACrypter {

		private var PUBLIC_MODULUS:String;
		private var PUBLIC_EXPONENT:String;
		private var PRIVATE_EXPONENT:String;
		private var P:String;
		private var Q:String;
		private var DMP1:String;
		private var DMQ1:String;
		private var IQMP:String;
		private var encrypter:RSAKey;
		private var decrypter:RSAKey;

		public function RSACrypter(
			PUBLIC_MODULUS:String, 
			PUBLIC_EXPONENT:String, 
			PRIVATE_EXPONENT:String = null, 
			P:String = null, 
			Q:String = null, 
			DMP1:String = null, DMQ1:String = null, IQMP:String = null
		) {
			this.IQMP = IQMP;
			this.DMQ1 = DMQ1;
			this.DMP1 = DMP1;
			this.Q = Q;
			this.P = P;
			this.PRIVATE_EXPONENT = PRIVATE_EXPONENT;
			this.PUBLIC_EXPONENT = PUBLIC_EXPONENT;
			this.PUBLIC_MODULUS = PUBLIC_MODULUS;
		}
		public function createEncrypter():void {
			
			encrypter = RSAKey.parsePublicKey(PUBLIC_MODULUS, PUBLIC_EXPONENT);
		}
		public function createDecrypter():void {
			
			decrypter = RSAKey.parsePrivateKey(PUBLIC_MODULUS, PUBLIC_EXPONENT, PRIVATE_EXPONENT, P, Q, DMP1, DMQ1, IQMP);
		}

		public function encrypt(plainText:String):String {
			
			var textBin:ByteArray = Hex.toArray(Hex.fromString(plainText));
			var encryptTextBin:ByteArray = new ByteArray();	
			
			encrypter.encrypt(textBin, encryptTextBin, textBin.length);	
			
			var cipherText:String = Base64.encodeByteArray(encryptTextBin);
			return cipherText;
		}
		public function decrypt(cipherText:String):String {
			
			var decodedTextBin:ByteArray = Base64.decodeToByteArray(cipherText);
			var decryptedTextBin:ByteArray = new ByteArray();
			
			decrypter.decrypt(decodedTextBin, decryptedTextBin, decodedTextBin.length);
			
			var decryptedText:String = Hex.toString(Hex.fromArray(decryptedTextBin));
			return decryptedText;
		}
	}
}
</pre></p>

<p>RSACrypter クラスの検証用クラス<br />
<pre>
package crypto_test {

	public class RSACryptoTester {

		private var crypter:RSACrypter;
		
		public function RSACryptoTester() {
			
			crypter = new RSACrypter(
				&quot;a1b7ee12d7f83208b7a3ad028b95b679a94a4fee56324e0232919680c7ca8d2d411c61246a86c3eea635043c80248ccee58cd1f1fd57f5a09ac03b8a6e0b8ac7&quot;,
				&quot;10001&quot;,
				&quot;952a74bc88dcf439ba398d01c602c8179c21616cf3b0dee784016a134b35f7d500d48037ef9132734bbb337fb1917de8a7a280d81f5b72c30ba4805f28d56a61&quot;,
				&quot;fa1519c5586d0ced156aaef81d8f694cbcb8fd4b61fed35cbefdbd83c9e7d5a9&quot;,
				&quot;a58b8e4bb37f10857d9652bf703d466dc876270d0a33ef16a0c0a328b5c9c2ef&quot;,
				&quot;bdd35a7673c282f74b34698fa8507d6b642d3f0703617c6a8006f6dd9c5abfd1&quot;,
				&quot;24fed92005cf21ac1372e2af31b01feb2cdf6abeb946fde97aa7524f28c11c35&quot;,
				&quot;b9912750e685af9bca5bed7effb1f8ea459d87dd458a3e2046e691dcf9a898ed&quot;
			);
			crypter.createEncrypter();
			crypter.createDecrypter();
		}

		public function test():void {
			
			test1();
			test2();
			test3();
		}
		private function test1():void {
			
			trace('--- test1 ---');
			
			var cipherText:String = crypter.encrypt(&quot;konbanwa&quot;);
			trace('cipherText: ' + (cipherText));
			
			var decryptedText:String = crypter.decrypt(cipherText);
			trace('decryptedText: ' + (decryptedText));
		}
		private function test2():void {
			
			trace('--- test2 ---');
			
			var cipherText:String = &quot;l9T8qv5+ab+G7RdjwUZNctAtTG7SqZYEQyfUkvGU97mMUfWMC+pfIILm6LT86vwUAH0GsrKBg/6k7dy5WF9rsg==&quot;;
			var decryptedText:String = crypter.decrypt(cipherText);
			trace('decryptedText: ' + (decryptedText));
		}
		//error : pycrypto → ascrypto
		private function test3():void {
			
			trace('--- test3 ---');
			
			var cipherText:String = &quot;nUB1y5xmDjTq2AsHI+EnetCNJuODedQWZ2Ojv41qPMEoI3/CaE/2KXSdoJvoourTmotCE9Xp07KnqU3VcedkhQ==&quot;;
			crypter.decrypt(cipherText);
		}

	}
}
</pre></p>

<p>RSACryptoTester クラスの説明です。</p>

<p>まず、<a href="http://crypto.hurlant.com/demo/" target="_blank">AS3 Crypto Demo page</a>の Public Key タブにある Generate ボタンを押して、暗号化・復号に必要なキーを作成します。作成したキーを RSACrypter クラスのコンストラクタに設定します。コンストラクタの引数に全てのデータを設定していますが、実際は第三引数までで動作します。RSAKey.parsePrivateKey メソッドに第三引数まで指定した場合と、第三引数より後の引数全てを指定した場合とで動作がどう異なるのかは理解していません。「あらかじめ必要な計算を行なっておき、処理を高速化するため」と予想しておきます。</p>

<p>RSACryptoTester.test1 メソッドでは、文字列 konbanwa を暗号化・復号する検証を行なっています。</p>

<p>RSACryptoTester.test2 メソッドでは、AS3 Crypto Demo page の Public Key タブ Plain Text(Text) に「konbanwa」と入力し、Cipher Text(Base64)欄に出力された内容「l9T8qv5+ab+G7RdjwUZNctAtTG7SqZYEQyfUkvGU97mMUfWMC+pfIILm6LT86vwUAH0GsrKBg/6k7dy5WF9rsg==」を、復号する検証を行なっています。</p>

<p>RSACryptoTester.test3 メソッドでは、後述の python(PyCrypto) 側で「konbanwa」という文字列を暗号化した「nUB1y5xmDjTq2AsHI+EnetCNJuODedQWZ2Ojv41qPMEoI3/CaE/2KXSdoJvoourTmotCE9Xp07KnqU3VcedkhQ==」という文字列を復号する検証を行なっています。</p>

<p>RSACryptoTester クラスの実行結果は以下となります。<br />
<pre>
--- test1 ---
cipherText: oBFNV/IXcrGUhoCFg80MAF+zCDyUZeG6UAgnJwUT1t8cYMZoCouLdXC+Ea8qL1GmBZ8J22Rvp9YWuV3DRCyW5w==
decryptedText: konbanwa
--- test2 ---
decryptedText: konbanwa
--- test3 ---
PKCS#1 unpad: i=0, expected b[i]==2, got b[i]=6b
Error: Decrypt error - padding function returned null!
	at com.hurlant.crypto.rsa::RSAKey/_decrypt()
	at com.hurlant.crypto.rsa::RSAKey/decrypt()
	at crypto_test::RSACrypter/decrypt()
	at crypto_test::RSACryptoTester/test3()
	at crypto_test::RSACryptoTester/test()
	at crypto_test::CryptoTester()
</pre></p>

<p>RSACryptoTester.test3 メソッドの実行結果はエラーとなってしまいます。</p>

<h5>python : RSA</h5>

<p>python で公開鍵暗号方式(RSA)を行うためのクラス RSACrypter<br />
<pre>
import Crypto.PublicKey.RSA as RSA
import base64

class RSACrypter:
	
	def __init__(
		self, 
		PUBLIC_MODULUS, 
		PUBLIC_EXPONENT, 
		PRIVATE_EXPONENT = None, P = None, Q = None, IQMP = None
	):
		self.__n = long(PUBLIC_MODULUS, 16)
		self.__e = long(PUBLIC_EXPONENT, 16)
		
		if PRIVATE_EXPONENT: self.__d = long(PRIVATE_EXPONENT, 16)
		if P: self.__p = long(P, 16)
		if Q: self.__q = long(Q, 16)
		if IQMP: self.__u = long(IQMP, 16)
	
	def createEncrypter(self):
		
		self.__encrypter = RSA.construct((self.__n, self.__e))
	
	def createDecrypter(self):
		
		#self.__decrypter = RSA.construct((self.__n, self.__e, self.__d))
		self.__decrypter = RSA.construct((self.__n, self.__e, self.__d, self.__p, self.__q))
		#self.__decrypter = RSA.construct((self.__n, self.__e, self.__d, self.__p, self.__q, self.__u))
	
	def encrypt(self, plainText):
		
		encryptedTuple = self.__encrypter.encrypt(plainText, &quot;&quot;)
		encodedText = base64.b64encode(encryptedTuple[0])
		return encodedText
	
	def decrypt(self, cipherText):
		
		decodedText = base64.b64decode(cipherText)
		decryptedText = self.__decrypter.decrypt(decodedText)
		return decryptedText
</pre></p>

<p>RSA.construct のタプル6番目の要素には <a href="http://crypto.hurlant.com/demo/" target="_blank">AS3 Crypto Demo page</a> Public Key タブの Generate ボタンで生成される 1/Q mod P の値を設定すればよいかと思いますが、自信がないのでひとまず5番目の要素までを設定できるようにしています。</p>

<p><br />
RSACrypter クラスの検証用クラス<br />
<pre>
import RSACrypter

PUBLIC_MODULUS = &quot;a1b7ee12d7f83208b7a3ad028b95b679a94a4fee56324e0232919680c7ca8d2d411c61246a86c3eea635043c80248ccee58cd1f1fd57f5a09ac03b8a6e0b8ac7&quot;
PUBLIC_EXPONENT = &quot;10001&quot;
PRIVATE_EXPONENT = &quot;952a74bc88dcf439ba398d01c602c8179c21616cf3b0dee784016a134b35f7d500d48037ef9132734bbb337fb1917de8a7a280d81f5b72c30ba4805f28d56a61&quot;

P = &quot;fa1519c5586d0ced156aaef81d8f694cbcb8fd4b61fed35cbefdbd83c9e7d5a9&quot;
Q = &quot;a58b8e4bb37f10857d9652bf703d466dc876270d0a33ef16a0c0a328b5c9c2ef&quot;
DMP1 = &quot;bdd35a7673c282f74b34698fa8507d6b642d3f0703617c6a8006f6dd9c5abfd1&quot;
DMQ1 = &quot;24fed92005cf21ac1372e2af31b01feb2cdf6abeb946fde97aa7524f28c11c35&quot;
IQMP = &quot;b9912750e685af9bca5bed7effb1f8ea459d87dd458a3e2046e691dcf9a898ed&quot;
		
class RSACryptoTester:
	
	def __init__(self):
		
		self.__crypter = RSACrypter.RSACrypter(
			PUBLIC_MODULUS, PUBLIC_EXPONENT, PRIVATE_EXPONENT, P, Q, IQMP)
		
		self.__crypter.createEncrypter()
		self.__crypter.createDecrypter()
	
	def test(self):
		
		self.__test1()
		self.__test2()
		
	def __test1(self):
		
		print &quot;--- test1 ---&quot;
		
		cipherText = self.__crypter.encrypt(&quot;konbanwa&quot;)
		print cipherText
		
		decryptedText = self.__crypter.decrypt(cipherText)
		print decryptedText
	
	def __test2(self):
		
		print &quot;--- test2 ---&quot;
		
		cipherText = &quot;l9T8qv5+ab+G7RdjwUZNctAtTG7SqZYEQyfUkvGU97mMUfWMC+pfIILm6LT86vwUAH0GsrKBg/6k7dy5WF9rsg==&quot;
		decryptedText = self.__crypter.decrypt(cipherText)
		print decryptedText
		
		text = self.pkcs1_unpad(decryptedText)
		print text
	
	def pkcs1_unpad(self, text):
		
		import re
		m = re.match('\x02[^\x00]{8,}\x00(.*)', text)
		return m.group(1) if m else None

if __name__ == '__main__':
	tester = RSACryptoTester()
	tester.test()
</pre></p>

<p>RSACryptoTester クラスの説明です。AS3 版 RSACrypter と同じくコンストラクタには第三引数まで指定でも動作します。</p>

<p>RSACryptoTester.test1 メソッドでは、文字列 konbanwa を暗号化・復号する検証を行なっています。</p>

<p>RSACryptoTester.test2 メソッドでは、AS3 版 RSACryptoTester.test2 と同じ 暗号化文字列を復号する検証を行なっています。しかし意図通り復号されないため、補足処理(後述)を加えています。</p>

<p><br />
RSACryptoTester クラスの実行結果は以下となります。<br />
<pre>
--- test1 ---
nUB1y5xmDjTq2AsHI+EnetCNJuODedQWZ2Ojv41qPMEoI3/CaE/2KXSdoJvoourTmotCE9Xp07KnqU3VcedkhQ==
konbanwa
--- test2 ---
バイナリ文字列konbanwa
konbanwa
</pre></p>

<p>RSACryptoTester.test1 メソッドで暗号化された文字列「nUB1y5xmDjTq2AsHI+EnetCNJuODedQWZ2Ojv41qPMEoI3/CaE/2KXSdoJvoourTmotCE9Xp07KnqU3VcedkhQ==」を、AS3版 RSACryptoTester.test3 メソッドで利用しています。python 側では復号可能ですが AS3 側では復号できないことがわかります。</p>

<p>RSACryptoTester.test2 メソッドの実行結果一行目はランダムなバイナリ文字列に加えて「konbanwa」という文字列が表示されます。as3crypto で暗号化した文字列を PyCrypto で復号しても、完全に復号できないことがわかります。対策として、RSACryptoTester.pkcs1_unpad メソッドでランダムなバイナリ文字列の削除を行なっています。</p>

<p>　pkcs1_unpad メソッド参考 URL<br />
　<a href="http://kfalck.net/2011/03/07/decoding-pkcs1-padding-in-python" target="_blank">http://kfalck.net/2011/03/07/decoding-pkcs1-padding-in-python</a></p>

<p>追記 2011/11/30)</p>

<p>上記サンプルソースコードですと、Pycrypto 側で DES 暗号化する文字列長は 8バイトの倍数ではなく 8バイト丁度でないと、as3crypto 側で復号が正常に行なえない事実が発覚しました。AES も同様に何か制限がかかってしまっているかもしれません。解決方法を調査中。</p>

<p>追記2 2011/11/30)<br />
解決しました。次回記事にて詳細を記述します。<br />
</p>]]>
    </content>
</entry>
<entry>
    <title>Adobe 製品インストール・アンインストールエラーでの対処 : Error 1325. ******* is not a valid short file name</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001092.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1092" title="Adobe 製品インストール・アンインストールエラーでの対処 : Error 1325. ******* is not a valid short file name" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1092</id>
    
    <published>2011-11-04T06:38:51Z</published>
    <updated>2011-11-04T06:42:52Z</updated>
    
    <summary>ものすごく状況が限定される情報です。世の中同じような状況で Adobe 製品がイ...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="info" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>ものすごく状況が限定される情報です。世の中同じような状況で Adobe 製品がインストール出来ない…！なんて人の方のための解決へのヒントになれば幸いです。</p>

<p>Windows にて、近年の Adobe 製品のインストーラで発生します。インストール(アンインストール)時のエラーメッセージとして「Error 1325. ******* is not a valid short file name」といった「ショートファイル名が有効でない」といった意味の文言が表示された時の対処となります。</p>

<h5>原因の可能性</h5>

<p>上記エラーメッセージが表示される原因として、以下の Windows 上での以下の(a)～(b)の操作が問題である可能性があります。</p>

<p>(a)ドキュメント(マイドキュメント)ディレクトリの場所を任意に設定</p>

<p>私は外部ハードディスクにドキュメントディレクトリを設定するよう変更していました。私の場合、外部ハードディスクは Gドライブだったので「G:\MyDocument」というパスを設定していました。</p>

<p>(b)ドキュメントディレクトリのドライブを変更</p>

<p>関東大震災時いろいろ作業環境を変更していた際、外部ハードディスク名が変わってしまった事があります。Gドライブから Hドライブに変更がかかりました。「H:\MyDocument」へと変わりました。</p>

<h5>いきさつ</h5>

<p>本日、購入した Adobe Flash Professional CS5.5 アップグレード版が家に届いたのですが、インストールエラーが発生。たくさん表示されるエラーと警告文の中に気になるエラー文言が見つかります。</p>

<p>　Error 1325. MyDocument is not a valid short file name</p>

<p>このエラーメッセージは半年前くらいに DreamWeaver 体験版のインストールや Adobe Reader のアンインストールを行おうとした際にも表示されました。近年の Adobe 製品のインストーラで発生するかと思われます。</p>

<p>購入した Adobe Flash Professional CS5.5 でも同じエラーメッセージが表示されインストールできないのはまずい、という事で再度調査を開始しました。</p>

<h5>解決手順</h5>

<p>エラーメッセージの内容は「『MyDocument』という文字列を含むディレクトリパスが見つからない」という事かと予測し、任意に変更していたドキュメントディレクトリの場所をまずはデフォルトに戻してみようと思いました。しかし戻し方が思い出せない。<br />
おかしいなとネット上で調べてみると「ドキュメントディレクトリのプロパティに[場所]タブで設定が可能」との事ですが、プロパティウインドウ内に[場所]タブが見つからない。更に検索してみると以下の情報がありました。</p>

<p>　Vistaのドキュメントプロパティから[場所]タブが消えた<br />
　<a href="http://lufia.org/notes/2008/0808.html" target="_blank">http://lufia.org/notes/2008/0808.html</a></p>

<p>上記記事を参考に、レジストリのドキュメントディレクトリの位置を調べてみると「G:\MyDocument」となっていました。「H:\MyDocument」になっていなくてはならないのに、ドライブ名は G のままでした。よって、「G:\MyDocument」を「H:\MyDocument」に編集し PC を再起動。(レジストリの書き換えには十分にご注意ください。)</p>

<p>これにより万事解決。エラーメッセージは表示されることなく無事 Flash CS 5.5 へのアップグレードを行うことができました。ドライブが変わったがレジストリは書き換えられていなかった、というのが主原因だったようです。<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>暗号化調査</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001091.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1091" title="暗号化調査" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1091</id>
    
    <published>2011-10-31T07:23:26Z</published>
    <updated>2011-10-31T09:42:25Z</updated>
    
    <summary>暗号化通信 並びに swf の暗号化についての調査を少しずつ開始。 暗号化通信 ...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>暗号化通信 並びに swf の暗号化についての調査を少しずつ開始。</p>

<h5>暗号化通信</h5>

<p>いくら暗号化通信を行おうとも swf 自体を解析されてしまえば意味が無い、といった認識がありました。ざっと調査した結果 その認識は変わらず。とはいえ暗号化しないと、誰でも簡単に不正なリクエストを行うことが可能となってしまうため、重要なデータを扱う swf では暗号化は必須となります。</p>

<p>swf は Google App Engine 上で動作させることを予定しており、AS3 ←→ Python 双方向に暗号化通信を可能にすることを第一の目標とします。</p>

<p>暗号化の方法を調べてみると、共通鍵暗号方式と公開鍵暗号方式、そして両者を組み合わせたハイブリッド暗号方式等が見つかります。以下はハイブリッド暗号方式に関しての参考 URL です。</p>

<p>　<a href="http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1065429575" target="_blank">http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1065429575</a><br />
　<a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20060620/241303/" target="_blank">http://itpro.nikkeibp.co.jp/article/COLUMN/20060620/241303/</a></p>

<p>共通鍵暗号化通信、公開鍵暗号化通信それぞれサンプルを制作した後、ハイブリッド暗号方式に挑戦してみようと思います。ハイブリッド式にするのは、上記 URL 内にあるような両者の利点をとるため、というのではなく、スクリプト難読化のため(不正なリクエストを送り難くするため)の対処といえます。</p>

<p>AS3, python 共に暗号化に関する情報は検索すると結構見つかります。MD5, RSA あたりがキーワードになるでしょうか。</p>

<p>Adobe のサイトでも少々解説がありました。</p>

<p>　より安全なSWF Webアプリケーションの作成<br />
　<a href="http://www.adobe.com/jp/devnet/flashplayer/articles/secure_swf_apps_12.html" target="_blank">http://www.adobe.com/jp/devnet/flashplayer/articles/secure_swf_apps_12.html</a></p>

<p>ただし、上記 URL の以下の文章は誤りではないでしょうか。<br />
<pre>
非対称暗号化方式を使用する場合は、SWFファイル内に公開鍵を格納しても、
脅威にさらされることはありません。
</pre></p>

<pre>
第三者がSWFファイルを逆コンパイルして鍵を盗んだとしても問題はありません。
攻撃者が不正な暗号化済みデータをサーバに送りつける可能性もありますが、
サーバ側で、暗号化が行われているかどうかにかかわらずデータの検証を行うよう対策を施していれば、
問題はありません。
</pre>

<p>サーバ側でデータの検証を行えばよい、とありますが、データを作る側のロジックは swf 内に存在するため、ロジックが解析されてしまえば不正なデータは作れてしまうような気がします。</p>

<h5>swf 暗号化</h5>

<p>まず、どれくらいの精度で解析可能なんだろうかと、世にある swf の解析ソフトを試用してみました。<br />
swf バイナリ解析を勉強していた時、相当これはややこしいな、と感じていたため、解析ソフトも大した解析はできないのではないか？などと思っていましたが、いやはや実際に試用してみてびっくり。クラスパッケージ構造そのまま、ソースファイルの内容ほぼそのままに解析されました。あまりのそのままさに、ブーッと吹いてしまいました。暗号化通信対処を行なっても、その処理箇所がどうなっているのか知識のある人ならばすぐに見ることができてしまいます。</p>

<p>これは手詰まりか、と思いましたが、次に「swf 難読化ソフト」の試用を行って見ました。ソフト名は <a href="http://www.kindi.com/" target="_blank">secureSWF</a> です。試用してみた結果、解析ソフトで解析したとしてもソースファイルの内容は何が書かれているのか分からないような難読化が行われました。ディレクトリ構造やらクラス名やら何から何まで解析結果はめちゃめちゃな状態になり、これを解読するのは無理と言ってもいいような状況ではないでしょうか。</p>

<p>ただし、secureSWF によってクラス名等変更されているのが原因かどうか、外部 swf を読み込む箇所で動作が停止してしまう現象が発生しました。secureSWF の Identifiers Renaming タブに、クラス名や変数名等 rename 設定を任意に行うことができるような箇所があるので、その設定によってこの問題は解決するかもしれません。</p>

<p>secureSWF のデモダウンロードページを見てみると、FDT Plugin バージョンというものも用意されている模様。これはなんとか上記問題を解決し、導入を検討してみたいところです。</p>

<h5>まとめ</h5>

<p>暗号化通信並びに swf 暗号化、双方が問題なく可能になれば、サーバと swf とのデータのやりとりを行う処理にて、最低限の対策はとった と言うことができそうです。<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a : ピンボール 其の二</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001090.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1090" title="Box2DFlash v2.1a : ピンボール 其の二" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1090</id>
    
    <published>2011-10-29T04:36:00Z</published>
    <updated>2011-10-29T07:16:16Z</updated>
    
    <summary>過去制作していた素材データの組み込みが完了。 自力での物理演算処理組み込みにおい...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>過去制作していた素材データの組み込みが完了。<br />
自力での物理演算処理組み込みにおいて難題だった「フリッパーがボールを跳ね返す動作」は、Box2DFlash によって見事なまでの跳ね返り具合を見せてくれるようになりました。</p>

<p>　<a href="http://www.dango-itimi.com/blog/swf/146/preloader.swf" target="_blank">http://www.dango-itimi.com/blog/swf/146/preloader.swf</a></p>

<p>画面クリック後、左右キーでフリッパーを操作することが可能です。スペースキーを押すと PAUSE となります。<br />
また、ボールがどこか平坦な地で停止してしまった場合の対処として、上下キーで画面全体を揺らす事ができます。ボールがどこかに接地している場合のみ機能し、一度揺らしたら一定時間立たないと再度揺らすことはできません。</p>

<p>効果音はテストとしてフリッパーを操作した時のみ鳴るようにしています。また、現段階で得点はスロットがそろった時のみ入ります。</p>

<p>どのようにすれば Box2DFlash でピンボールゲームを作ることが可能かの調査は、今回のサンプル製作でほぼ完了しました。今後は、スロットのようなゲーム内イベントを少しずつ増やしていき、充実化を図りたいと思います。<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>FDT5 リリース</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001089.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1089" title="FDT5 リリース" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1089</id>
    
    <published>2011-10-27T02:09:20Z</published>
    <updated>2011-10-27T03:33:59Z</updated>
    
    <summary>AS3 用エディタとして利用している FDT の新しいバージョン FDT5 が昨...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="info" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>AS3 用エディタとして利用している <a href="http://fdt.powerflasher.com/" target="_blank">FDT</a> の新しいバージョン FDT5 が昨日登場しました。</p>

<p>　<a href="http://fdt.powerflasher.com/" target="_blank">http://fdt.powerflasher.com/</a></p>

<p>早速導入してみようと eclipse プラグイン設定から http://fdt.powerflasher.com/update/ へアクセスしてみるも、FDT4 までしか見つからない状況。twitter の情報を追ってみると、プラグイン版はまだとの書き込みを発見。プラグイン版が出るまで、うずうずしながら使用はしばらく待ちたいと思います。</p>

<h5>コード補完機能の向上</h5>

<p>ざっとどのような機能があるのか見てみたところ、一番に目についたのはエディタのコード補完機能が向上したという点。</p>

<p>　<a href="http://fdt.powerflasher.com/docs/Advanced_Refactoring_%26_FDT_5" target="_blank">Advanced Refactoring & FDT 5</a></p>

<p>値から変数と型宣言を自動で補完してくれたり、ローカル変数定義を直でフィールド変数定義に変換してくれたり、値をフィールド定数値に変換してくれたりと、かゆい所にまで手を届けてくれた感じの機能向上です。コーディング時で薄々不便に感じていた点を補完してくれるようになり、開発効率も微量ながらアップすることでしょう。</p>

<p>メソッドの戻り値に対する変数と型宣言も補完してくれそうな気もしますが、上記サイト内にはその説明がなかったので試してみないとわからないところです。例えば「test.run();」という記述を「var *:int = test.run();」と補完してくれるのならば、とても効率がアップします。</p>

<h5>haXe サポート</h5>

<p>以前 FDT の blog で文字を目にしたことはありましたが <a href="http://haxe.org/?lang=jp" target="_blank">haXe</a> とはなんぞや状態でノーチェックでした。<a href="http://haxe.org/?lang=jp" target="_blank">haXe</a> のサイト内説明を見てみたところ、なんとも面白そうなプログラミング言語であることがわかりました。</p>

<p>　<a href="http://haxe.org/doc/intro?lang=jp" target="_blank">haXe の紹介</a></p>

<p>javascript でのゲーム開発、といったソースコード量が大変多くなりそうな時に、代行手段として haXe を用いることができるのではないかな？と感じました。現行の javascript を記述していて一番問題に感じるのは、eclipse の Refactor 機能(Rename, Moveコマンド)を用いる事が可能なエディタが存在しない、という点です(存在していたらごめんなさい)。大規模開発にて javascript の利用が厳しいと感じるのは、これが理由です。<br />
しかし FDT の Refactor 機能を haXe に用いることが可能ならばこの問題は解決します。AS1 の利用をやめ AS2 を利用するイメージと同等となります。とはいえまだ試してもいないので、FDT の Refactor 機能が haXe に利用できなかったらごめんなさい。</p>

<p>haXe にて jQuery といった外部ライブラリを利用したい場合、どのように記述するのだろうか、それとも同等の API が用意されているのだろうか、等 疑問は多々ありますが、時間があるときに簡単に調査したい所です。</p>

<h5>フリー版</h5>

<p>FDT5 には機能を制限したフリー版があります。フリー版では肝と言える Refactor 機能の利用はできませんが、基本となるコード補完機能の利用は可能のようなので、eclipse + FDT によるコーディングがどのようなものか、これを機に試してみてはいかがでしょうか。</p>

<p>　ダウンロードページ<br />
　<a href="http://fdt.powerflasher.com/buy-download/" target="_blank">http://fdt.powerflasher.com/buy-download/</a></p>

<p>vi 使いの方には合わせて <a href="http://www.viplugin.com/" target="_blank">viPlugin for Eclipse</a> (有料)の導入もお勧めします。</p>]]>
        
    </content>
</entry>
<entry>
    <title>TortoiseSVN 1.7 の WC-NG で eclipse Refactor (Rename, Move)機能が問題なく利用可能に</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001088.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1088" title="TortoiseSVN 1.7 の WC-NG で eclipse Refactor (Rename, Move)機能が問題なく利用可能に" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1088</id>
    
    <published>2011-10-20T06:32:08Z</published>
    <updated>2011-10-20T06:47:07Z</updated>
    
    <summary>先日 TortoiseSVN 1.7 がリリースされ、それに伴い WC-NG(W...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>先日 TortoiseSVN 1.7 がリリースされ、それに伴い WC-NG(Working Copy Next Generation) というファイル管理方法に変更がかかりました。</p>

<p>　参考)Subversion 1.7が出たので、TortoiseSVN 1.7でWC-NGやってみた<br />
　<a href="http://d.hatena.ne.jp/lino/20111014/1318597181" target="_blank">http://d.hatena.ne.jp/lino/20111014/1318597181</a><br />
　<br />
引用<br />
<pre>
Subversion 1.7の新機能の中でも個人的に嬉しいのが、WC-NG(Working Copy Next Generation)です。WC-NGは作業コピーのメタデータ変更で、フォルダの中にたくさんあった.svnフォルダがルートフォルダだけに集約されます。
</pre></p>

<p>今までは各ソースディレクトリ内毎に .svn ができてしまっていたため、eclipse(<a href="http://www.fdt.powerflasher.com/" target="_blank">FDT</a>) の Refactor コマンド(Rename, Move)を用いて「ディレクトリ名の変更」や「ディレクトリを他ディレクトリへ移動」を行うと、作業コピー内ディレクトリの構造が壊れてしまうという問題がありました。しかしこれからはその問題は発生しなくなります。</p>

<p><br />
<h5>TortoiseSVN 1.6 以前の問題点</h5></p>

<p>例えば以下のような Subversion 管理のディレクトリ構造があったとします。testA ディレクトリ内には AS3 ソースファイルの SampleA.as と SampleB.as が存在します。</p>

<pre>
root/
├ testA/
│　├ SampleA.as
│　└ SampleB.as
├ testB/
└ testC/
</pre>

<p>実際には以下のように、各ディレクトリ内には隠しディレクトリ .svn/ が存在します。</p>

<pre>
root/
├ .svn/
├ testA/
│　├ SampleA.as
│　├ SampleB.as
│　└ .svn/
├ testB/
│　└ .svn/
└ testC/
　　└ .svn/
</pre>

<p>Refactor Move コマンドを用いて testA ディレクトリを testB ディレクトリの下に移動させると以下のようになります。</p>

<pre>
root/
├ .svn/
├ testB/
│　├ .svn/
│　└ testA/
│　　　├ SampleA.as
│　　　├ SampleB.as
│　　　└ .svn/
└ testC/
　　└ .svn/
</pre>

<p>FDT の Refactor Move コマンドでは testA/SampleA.as と testB/SampleB.as の内容は自動で書き換えてくれますが、testA/.svn/ ディレクトリ内の内容を書き換える機能はありません。上記のように Move コマンドで root/testB/testA/.svn/ に移動しても Subversion 上では root/testA/.svn/ 上に存在している事となり、不整合が発生してしまいます。よって今までは、任意に root/testB/testA/ 内の .svn/ ディレクトリを削除したりしなくてはなりませんでした。</p>

<h5>TortoiseSVN 1.7 以降</h5>

<p>上記ディレクトリ構造例を TortoiseSVN 1.7 に適用すると以下のようになります。</p>

<pre>
root/
├ .svn/
├ testA/
│　├ SampleA.as
│　└ SampleB.as
├ testB/
└ testC/
</pre>

<p>Refactor Move コマンドを用いて testA ディレクトリを testB ディレクトリの下に移動させると以下のようになり、ディレクトリ構造の不整合は発生しません。</p>

<pre>
root/
├ .svn/
├ testB/
│　└ testA/
│　　　├ SampleA.as
│　　　└ SampleB.as
└ testC/
</pre>]]>
        
    </content>
</entry>
<entry>
    <title>Box2DFlash v2.1a ピンボール1</title>
    <link rel="alternate" type="text/html" href="http://www.dango-itimi.com/blog/archives/2011/001087.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.dango-itimi.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=1087" title="Box2DFlash v2.1a ピンボール1" />
    <id>tag:www.dango-itimi.com,2011:/blog//1.1087</id>
    
    <published>2011-10-13T07:56:52Z</published>
    <updated>2011-10-13T08:03:03Z</updated>
    
    <summary>過去 AS2 で製作し中途で止まっていたピンボールゲームを、Box2DFlash...</summary>
    <author>
        <name>siratama</name>
        
    </author>
            <category term="FLASH" />
            <category term="tips" />
            <category term="update" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.dango-itimi.com/blog/">
        <![CDATA[<p>過去 AS2 で製作し中途で止まっていたピンボールゲームを、Box2DFlash v2.1a にて動作させてみることに。</p>

<p>「Flash オーサリング環境上で製作したシェイプデータを Box2DFlash の物体として再現するライブラリ」の精錬化と、Box2D を用いてのゲームプログラミングの練習の意味も兼ねての制作となります。</p>

<p>過去製作したピンボールゲームの背景データと、Flash オーサリング上で背景用グラフィックスシンボルを配置したイメージは以下となります。</p>

<p><img src="http://www.dango-itimi.com/blog/swf/145/0.png" /> <img src="http://www.dango-itimi.com/blog/swf/145/1.png" /></p>

<p>まだまだお粗末ですが Box2D debug モードでの動作は以下となります。</p>

<p>　<a href="http://www.dango-itimi.com/blog/swf/145/0/preloader.swf" target="_blank">http://www.dango-itimi.com/blog/swf/145/0/preloader.swf</a></p>

<p>画面クリック後、左右キーでフリッパーを操作することが可能です。ゲーム中スペースキーを押すと PAUSE となります。どこかくぼみにボールがはまるとゲームは停止してしまいます。</p>

<p>PAUSE 機能を実装してみて、Box2DFlash v2.1a では内部で何か独自のスレッドを持ってはいないことが確認できました。b2World.Step メソッドを実行することで 1フレーム分の処理が実行されるような内容になっているようです。</p>

<p><br />
背景グラフィックスや、ボールとフリッパーのグラフィックスを合わせたものが以下となります。</p>

<p>　<a href="http://www.dango-itimi.com/blog/swf/145/1/preloader.swf" target="_blank">http://www.dango-itimi.com/blog/swf/145/1/preloader.swf</a></p>

<p><br />
<h5>b2RevoluteJointDef 制限角度注意点</h5></p>

<p>フリッパーの動作は b2RevoluteJointDef クラスのモーター機能を利用しています。</p>

<p>　参考サイト)<br />
　<a href="http://flashjp.com/apiindex.php" target="_blank">http://flashjp.com/apiindex.php</a><br />
　<a href="http://d.hatena.ne.jp/matsu4512/20090110/1231585208" target="_blank">http://d.hatena.ne.jp/matsu4512/20090110/1231585208</a></p>

<p>b2RevoluteJointDef を利用してみた所、b2RevoluteJointDef.lowerAngle, b2RevoluteJointDef.upperAngle の値を設定したとしても、その値 丁度には停止してくれない、という点に気づきました。制限値に近い角度になっている状態で更に大きなチカラを加えたり モーターを回したりすると、一瞬大きく角度がはみ出てしまいます。よって、制限角度を超えたらそれ以上にチカラを加えたりモーターを回したりはしないようにするための制御を別途行うようにしています。</p>]]>
        
    </content>
</entry>

</feed> 


