IE6.0SP1以上で利用できるシステム制限

– Internet Explorer 6.0 SP1 で使用できる制限値(Microsoft)
http://support.microsoft.com/kb/823057/ja
 
Spybot の IE Tweaks 機能について気になって調べていて見付けました。
レジストリで設定すると、IE の機能の一部(例: メニューの項目等)を制限することが可能です。
例えば Spybot では

HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Restrictions

キーで、NoBrowserOptions = 1 (REG_DWORD)とすることで
ブラウザからインターネットオプションを開こうとした時に

このコンピュータの制限により、処理は取り消されました。システム管理者に問い合わせてください。

と出し実行できなくする、という機能を実現しています。
 
その他

NoSelectDownloadDir : [ファイルのダウンロード] ダイアログ ボックスの [保存] ボタンを無効にします。
NoViewSource : [表示] メニューの [ソース] を無効にします。ただし、ユーザーがソースを完全に表示できなくなるようにするには、NoBrowserContextMenu 値を追加する必要があります。
AlwaysPromptWhenDownload : [ファイルのダウンロード] ダイアログ ボックスの [この種類のファイルであれば常に警告する] チェック ボックスを淡色表示にし、常にオンに設定されるようにします。
NoTheaterMode : F11 キー (全画面表示モード) を無効にします。
NoBrowserContextMenu : Web ページを右クリックしたときに表示されるショートカット メニューを無効にします。
NoOpeninNewWnd : Ctrl + N キーおよび [開く] を無効にします。
NoBrowserSaveAs : [ファイル] メニューの [名前を付けて保存] を非表示にします。

などなど。
作品展示用のコンピュータなどで機能制限したい場合に有用かもしれません。
 
なお、セキュリティのため Policies 以下については、(HKEY_CURRENT_USER においても)管理者権限がないと追加、削除、変更ができないようになっています。

国際化(i18n:他言語対応)の基本

まず文字列の外部化をし、言語ごとにプロパティファイルを作成し、Java のクラスパス直下に置きます。たとえば Eclipse の場合 src ディレクトリ、それ以外の場合 class ディレクトリなど。
 
filename.properties: (対応していない場合のデフォルト. 英語が望ましい)

message.greet = Hello!!
message.bye = Good bye.

 
filename_ja.properties:
  日本語ロケール ja_JP の時に利用されるプロパティ.
  マルチバイト文字を扱う場合 native2ascii でエンコードする必要があるため、参考欄で後述する Eclipse の PropertiesEditor プラグインを使うとよい.

message.greet = こんにちは!!
message.bye = さようなら。

 
filename_fr.properties:
  フランス語ロケール fr_FR の時に利用されるプロパティ.
  このように対応したい言語用のファイルを追加するだけで言語対応ができます.

message.greet = Salut!!
message.bye = Au revoir.

 
以下が国際化対応した外部文字列呼び出しと時刻整形の Java サンプルコードです。

import java.util.ResourceBundle; // 外部文字列取得用
import java.text.DateFormat; // 日付表示用
// その他 import 文省略
 
// 略
 
public void main(String[] args){
   // 実行環境のデフォルトのロケールのプロパティファイルを読み込む
   ResourceBundle bundle =
       ResourceBundle.getBundle(“filename”); // <filename>_<言語コード>.properties の <filename> を指定。
    
   // 現在のロケールの言語で挨拶
   System.out.println(bundle.getString(“message.greet”));
 
   // 現在のロケールで有効な書式で日付表示
   String sToday = DateFormat.getDateInstance().format(new Date());
   System.out.println(sToday);
    
   // 現在のロケールの言語で別れの挨拶
   System.out.println(bundle.getString(“message.bye”));
  
}

結果:

– ロケールが英語(en_USなど)の場合:
Hello!!
May 31, 2007
Good bye.
 
– 日本語(ja_JP)の場合:
こんにちは!!
2007/05/31
さようなら。
 
– フランス語(fr_FR)の場合:
Salut!!
31 mai 2007
Au revoir.

 

java.util.Locale.setDefault(Locale.ENGLISH);

のようにすることで、以降のコードのデフォルトロケールを任意の言語,国に変更することができます。
 
参考:
国際化プログラミングの常識(@IT)
– Locale クラス(Javadoc)
– DateFormat クラス
PropertiesEditor
  .properties ファイルで日本語を含むマルチバイト文字を扱う時に便利な Eclipse プラグイン.
これを使うことでいちいち native2ascii を実行する必要がなくなります.
なお、スタンドアロン版(PropertiesEdotor.jar)もあります.
詳しい導入方法はこちらの記事(@IT)が参考になります。

PHP 用デバッガ

PHP: Advanced PHP Debugger(PHP) (php.net)

(PHP 公式ドキュメントより引用)
APD は進化した PHP デバッガです。PHP コードのプロファイリングや デバッグの機能を提供すること、また完全なスタックトレースを出力する 機能を提供することを目的として作成されています。

 
インストール手順:

$ pecl install apd
 
$ cat >> /path/to/php.ini ← エディタ等で以下の内容を php.ini に追加
 
zend_extension = /path/to/apd.so ← APD モジュールのフルパス(zend_extention 指定の場合は相対パスは不可)
apd.dumpdir = /tmp/apd_log ← APD での解析結果の出力先フォルダ
apd.statement_tracing = 0 ← 行単位トレースをする場合 1 にする。これを有効にすると出力が冗長になります。

Windows 用のコンパイル済み PECL モジュールは http://snaps.php.net/win32/ からダウンロードできます(ファイル名 pecl からはじまるもの)。
 
 
利用方法:
デバッグをしたいスクリプトの一番始めに

apd_set_pprof_trace();

を呼ぶと PHP デバッガが利用できます。
 
PHP デバッガによる結果は php.ini の apd.dumpdir で指定したディレクトリに

pprof.<プロセスID>.<通し番号>

のような形式で保存されます。
 
そのまま読めなくはないですが、読みやすい形に整形するために pprofp コマンドを利用することができます(APD に付属しています)。
 
— かかった処理時間の多い関数順に並びかえて出力する

pprofp -R [ファイル名]

— コールツリー(関数の実行順序)を調べる

pprofp -t [ファイル名]

— (上の二つ)+(ビルトイン関数は含めない)+(コールツリーの横に経過時間を表示)

pprofp -Rtci [ファイル名]

 
その他のオプションについては「APD の pprofp 引数一覧(pprofp -h)」を参照してください。
  
Windows 用の pprofp についてはAPD のソースに含まれるものが使えるのですが、そのままの形では使いにくいため、実行用のバッチファイルを作成したものを置いておきます。
 
Windows 対応 pprofp をダウンロード
(APD 1.0.1 ソース付属のものから作成)
 
– pprofp
– pprofp.bat
– pprof2calltree
– pprof2calltree.bat
の 4 ファイルが入っています。
この4ファイルをそのまま php.exe と同じ場所など適当にパスが通る場所に置いてご利用ください。
 
参考:
– APD(公式 PHP マニュアル)
cles::blog

PHP で OpenSSL

PHP で OpenSSL 関数を使ってみたので、定番のハローワールドを置いておきます。


OpenSSL 関数で暗号化、復号化を行うには、
暗号化、復号化に必要な鍵のペアを PEM 形式で生成する必要があります。
1. パスワード付き秘密鍵 private_password.pem を生成

$ openssl genrsa private_password.pem -des3 1024

2. (1)からパスワードのない秘密鍵 private.pem を生成

$ openssl rsa -in private_password.pem -out private.pem

3. (1)を削除

$ rm private_password.pem

4. (2)から公開鍵 public.pem を生成

$ openssl rsa -in private.pem -pubout -out public.pem

 


openssl_public_encrypt(), openssl_private
…公開鍵で暗号化し、秘密鍵で復号化します。
つまり、誰からでも暗号化して送れるが、内容を読めるのは秘密鍵を持っている人だけになるため、通信経路での傍受が不可能になり、内容が外部に洩れる心配がないので機密性が高くなります。
ただし誰でも暗号化できるので全く別の内容へのかいざんは可能であり、必ずしも信頼性はありません。
 

// 暗号化に使う公開鍵
$public_key = file_get_contents(“public.pem”);
 
// 暗号化する文字列
$message = “Hello, world!!”;
 
// 暗号化データの結果格納先
$encrypted = “”;
 
// 暗号化実行
if(!openssl_public_encrypt($message, $encrypted, $public_key)){
    echo “暗号化に失敗\n”;
    die;
}
 
// 暗号化結果を表示(そのままでは表示できないのでBASE64エンコードする)
echo “暗号化データ: \n “.base64_encode($encrypted) . “\n”;
 
$message = null;
// ———————
// 復号化
// ———————
// 暗号化に使った公開鍵に対応する秘密鍵
$private_key = file_get_contents(“private.pem”);
 
// 復号化結果格納先
$result = “”;
 
// 復号化実行
if(!openssl_private_decrypt($encrypted, $result, $private_key)){
    echo “復号化に失敗\n”;
    die;
}
 
// 結果出力
echo “復号化結果: \n ” . $result . “\n”
     “BASE64:\n” . base64_encode($result).”\n”; // 比較用

結果:

暗号化データ:
FmPaJ9jOmjl/mK249NqUPzYjPUHsmFkSuNyp0SMlgW1c9RRzmKXBjcRhXH/5fwTxItAcE8/
AlZkjYo27XvGR7a3hdXxgaXbk4VORdRRk8LJXKB+xlVzF48OlHJ5lKUrXUdfr2BFtx53/IH
431mBlYWDhf+KyW608eKAA0T34qRY=
復号化結果:
Hello, world!!
BASE64:
SGVsbG8sIHdvcmxkZmc=

 


openssl_private_encrypt(), openssl_public_decrypt() の例:
…秘密鍵で暗号化し、公開鍵で復号化します。
つまり、鍵の所有者しか暗号化できないので中身のかいざんも、経路での差し替えも不可能になり、内容についての信頼性が高くなります。
ただし誰でも読めるため、内容の機密性はありません。
 
秘密鍵、公開鍵の使い方を逆にする以外は上の例と全く同じです。

// 暗号化に使う秘密鍵
$private_key = file_get_contents(“private.pem”);
 
// 暗号化する文字列
$message = “Hello, world!!”;
 
// 暗号化データの結果格納先
$encrypted = “”;
 
// 暗号化実行
if(!openssl_private_encrypt($message, $encrypted, $private_key)){
    echo “暗号化に失敗\n”;
    die;
}
 
// 暗号化結果を表示(そのままでは表示できないのでBASE64エンコードする)
echo “暗号化データ: \n “.base64_encode($encrypted) . “\n”;
 
$message = null;
// ———————
// 復号化
// ———————
// 暗号化に使った秘密鍵から作られた公開鍵
$public_key = file_get_contents(“public.pem”);
 
// 復号化結果格納先
$result = “”;
 
// 復号化実行
if(!openssl_public_decrypt($encrypted, $result, $public_key)){
    echo “復号化に失敗\n”;
    die;
}
 
// 結果出力
echo “復号化結果: \n ” . $result . “\n”
     “BASE64:\n” . base64_encode($result).”\n”; // 比較用

結果:

暗号化データ:
CII4EW6LQBq0faVJxshUfk9VCdFsE66DnQPVdsLbvfq7tNCMzAIZbZA3GBxHu4cG2TqvOnn
xN9C9S9IgBIbulfj4c90IkrYtHQGt3RHAJBYiAgfmzCKbMr2cPJhZwkMUkjczXeaOD1htFJ
TL9e2RKsrWBVFIaiG1JgFk2Jyd928=
復号化結果:
Hello, world!!
BASE64:
SGVsbG8sIHdvcmxkZmc=


openssl_open(), openssl_seal() の例:
…同報メールのように、別々の公開鍵を持つ複数の相手に対して同じデータを暗号化して送る場合に使います
 
– 送信側(送信先1の公開鍵 user1_public.pem と送信先2の公開鍵 user2_public.pem を持っているとする. 自分の鍵は必要としない)

// 送り先の公開鍵一覧。
$pubkeys = array(
        file_get_contents(“user1_public.pem”),
        file_get_contents(“user2_public.pem”),
   );
 
// 送る内容
$real_message = “Hello, world!!”;
 
// 暗号化データの結果格納先
$encrypted = “”;
// 復号化に必要なエンベロープキーの格納先。$pubkeys の数だけ格納される。
$ekeys = array();
 
if(!openssl_seal($real_message, $encrypted, $ekeys, $pubkeys)){
    echo “暗号化に失敗しました\n”;
    die;
}
 
// 出力. エンベロープキーと暗号化データについてはバイトコードなので、表示のために BASE64 エンコードしています。
for($i = 0; $i < count($pubkeys); $i++){
    echo “送り先番号: $i\n” .
         “使った公開鍵: \n” .
         $pubkeys[$i] .”\n” .
         “対応するエンベロープキー: \n” .
         base64_encode($ekeys[$i]) .”\n” .
         “暗号化されたデータ: \n” .
         base64_decode($encrypted);
}

 
受信側(送信側からエンベロープキー $ekey と暗号化データ $encrypted を受け取っているとする):

// 送信側が暗号化に使った公開鍵(user1_public.pem)に対応する秘密鍵
$private_key = file_get_contents(“user1_private.pem”);
 
// 結果格納先。復号化した文字列が入る
$message = “”;
 
if(!openssl_open($encrypted, $message, $ekey, $private_key)){
    echo “復号化に失敗しました\n”;
    die;
}
 
// 結果表示
echo $message . “\n”;

 
送信側結果は次のようになります。


送り先番号: 0
使った公開鍵:


-BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzZFcKoXbuWzGvlv++7Y05/jBh
nYC+PM67v3H2I5pYV8tUz/6GqsG5afFgLJYoWPEd3KYXHb46B0GxEOydOTuTLEcv
+gVr6v4khgOgjxOcM1hlv+EvAThm1lIY1Y5lbTv+MEUyrGm7SDk8iUaHF6OBcQp3
NzkO6j3+YrsC8znXPwIDAQAB


-END PUBLIC KEY—–
対応するエンベロープキー:
lu4ON1xW2hrrS1jXfav6mjWD32+Iuz1Jk20vhDRmSsfEp3vXuij7Z0R/ClhpgE9MxDJADiU
LS/CCUPuiZ3wUDErccfUFGGgcBKFsoXOgcX/vSfhi8yCYu3BOD+h5fOMmg/ZVe6NMjCVq50
D8yce5gPoypg2LHijse+0R1bPil8o=
暗号化されたデータ:
0qf1eWjjaHkiqRFKijam


送り先番号: 1
使った公開鍵:


-BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzZFcKoXbuWzGvlv++7Y05/jBh
nYC+PM67v3H2I5pYV8tUz/6GqsG5afFgLJYoWPEd3KYXHb46B0GxEOydOTuTLEcv
+gVr6v4khgOgjxOcM1hlv+EvAThm1lIY1Y5lbTv+MEUyrGm7SDk8iUaHF6OBcQp3
NzkO6j3+YrsC8znXPwIDAQAB


-END PUBLIC KEY—–
対応するエンベロープキー:
Hpv4sE4M4RGnbEAPMqFKxOOPDJG0hpWBoIXCe8xUaIzx/dskUQ/a+T4jYyw+RRGh11wlzZt
CJOjzkP3pbafc0ymElAzS8RFAne7bVuCJh44UF55thAUo0nZVo1/2Wz9HuTDL23AYwc+jyh
U/k24bpGh81VJl5I7IkItoDeiS70Y=
暗号化されたデータ:
0qf1eWjjaHkiqRFKijam

受信側結果:

Hello, world!!

 
参考:
OpenSSL 関数(php.net)
 PHP マニュアルの OpenSSL 関数についての項目。
– OpenSSL 公式サイトの日本語訳サイト
更新は不定期のようですが、openssl のマニュアルが参考になります。
公式はこちらです。

PHP の OpenSSL 関数で DSA(DSS) を使うとエラー

PHP で OpenSSL 関数を使って DSA 公開鍵での暗号化を行おうとしたところ

Warning: openssl_public_encrypt(): key type not supported in this PHP build!

のようにエラーがでてしまった。
 
PHP のソースを追ってみたところ、どうやら PHP では現在のところ DSA の秘密鍵/公開鍵についてはサポートされていないようです。
 
php-5.2.1/ext/openssl/openssl.c:

PHP_FUNCTION(openssl_public_encrypt)
{
// ** 省略 **
        switch (pkey->type) {
                case EVP_PKEY_RSA:
                case EVP_PKEY_RSA2:
                        successful = (RSA_public_encrypt(data_len,
                                                (unsigned char *)data,
                                                cryptedbuf,
                                                pkey->pkey.rsa,
                                                padding) == cryptedlen);
                        break;
                default:
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, “key type no
t supported in this PHP build!”);

        }
// ** 以下略 **

のように、
openssl_open(), openssl_seal(), openssl_private_decrypt(), openssl_private_encrypt(), openssl_public_encrypt(), openssl_public_decrypt()
など、暗号化/復号化を行う関数では RSA か RSA2 の時の処理しか実装されていないようです。
 
参考:
OpenSSL 関数(php.net)

他のアプリケーションのキーイベント等メッセージ監視

SetWindowsHookEx() という API を使うと、他のウィンドウに対するさまざまなイベントを監視することができます。
 
デフォルトの動作であるローカルフックだとそのアプリケーションに対するイベントしかとれません。他のウィンドウのイベントをとるキーロガー的な動作を実現するにはグローバルフックにする必要があります。
グローバルフックを行うには、DLL のハンドルを引数として渡さなければならないため、DLL で実装しなければなりません。
 
参考:
SetWindowsHookEx()(MSDN)
– 他のアプリケーションのメッセージを監視(doumo.jp)

3Dでのカメラ設定

デバイスのプロパティ Device.Transform.View に、Matrix インスタンスを指定することで設定可能。

// 左手座標の視点マトリクスを構築する
public static Matrix Matrix.LookAtLH(
    Vector3 cameraPosition, // カメラの位置。
    Vector3 cameraTarget, // カメラの見ている位置。
    Vector3 cameraUpVector // カメラの頭の方向(例: 正立は new Vector3(0f,1f,0f), 倒立は new Vector3(0f,-1f,0f)). 方向を指定する目的なので、ベクトルの大きさは問わない
)

例:

Device device;
 
// ..中略..
 
// 座標 (0,0,-10) から正立状態で 座標 (0,0,0) を見る
device.Transform.View = Matrix.LookAtLH(
    new Vector3(0f, 0f, -10.0f),
    new Vector3(0f,0f,0f),
    new Vector3(0f,1f,0f) );
    
);

実際に表示するには、さらに 3D から 2D への投影の設定を行う必要があります。
この設定を行うには Device.Transform.Projection プロパティに Matrix インスタンスを指定します。

// 左手座標のパースペクティブマトリクスを構築する
public Matrix Matrix.PerspectiveFovLH(
    float fieldOfViewY, // (カメラから見て) Y軸方向の視野。ラジアンで指定する。(1/4 π == 45度 くらいが適切)
    float aspectRatio, // 2Dに変換後の画面のアスペクト比(横幅 ÷ 縦幅) (例: 高さも幅も同じなら 1.0f, 汎用:(float)device.Viewport.Width / (float)device.Viewport.Height )
    float znearPlane, // (カメラから見た)可視範囲のうち、最も近い距離(1.0f)
    float zfarPlane // (カメラから見た)可視範囲のうち、最も遠い距離 (100.0f)
);

例:

Device device;
// …中略…
 
device.Transform.View = … // 略
 
// 上下角度45度で奥行き 1.0f 前方から 100.0f 前方までの範囲を表示する
device.Transform.Projection = Matrix.PerspectiveFovLH(
    (float) Math.PI / 4,
    (float) device.Viewport.Width / device.Viewport.Height,
    1.0f, 100.0f );

ちなみに、Matrix.PerspectiveForLH ではなくて Matrix.PerspectiveFovLH なので注意してください。for でなく fov です。
 
参考:
チュートリアル3 行列の使い方(MSDN Direct3D)
Matrix.LookAtLH メソッド(MSDN)
ビュー行列を設定する(MSDN)
Matrix.PerspectiveFovLH メソッド

C#.NET で UDP 通信を簡単に行うには

この記事はC#での実装例です。
もしPCからの接続、コマンドラインからの接続方法を知りたい方は、こちらの記事をどうぞ。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SendTo(…);
socket.ReceiveFrom(…);

のように System.Net.Sockets.Socket を使う方法もありますが、System.Net.Sockets.UdpClient を使うと簡単に UDP 通信を行うことができます。

// 必要な宣言
using System.Net;
using System.Net.Sockets;

private void DoSend(){
// 送信元とするポート
int localPort = 1234;
 
UdpClient client = new UdpClient(localPort);
 
// UDP パケットの送信先
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(“192.168.2.1”), 5678);
// 送信する内容(バイト配列で指定)
byte[] msg = Encoding.ASCII.GetBytes(“Hello, world\n”);
 
// 送信する
client.Send(msg, msg.Length, remoteEP);
// // 同じ場所に送信し続ける場合は次のように接続と送信をわけてもよい
// client.Connect(remoteEP);
// client.Send(msg, msg.Length);
}

以下のようにすれば、受信ができます。

private void DoReceive(){
int localPort = 5678;
UdpClient client = new UdpClient(localPort);
 
// 送信元。任意のIPアドレス、任意のポートから許可
IPEndPoint remoteEP = IPEndPoint(IPAddress.Any, 0);
 
// 受信するまで待ち続ける
byte[] res = client.Receive(ref remoteEP);
 
// バイト配列から ASCII 文字列に変換して表示
System.Console.Write(
   “送信元:” + remoteEP + “\n” + // 実際に送信が行われた IPアドレス, ポートが格納されているので一緒に表示
   “受信内容:”+Encoding.ASCII.GetString(res)
  );
}

TCP 版の TcpClient もあります。
 
参考:
UdpClient クラス (System.Net.Sockets)
TcpClient クラス
Socket クラス(System.Net.Sockets)

enum 型の一覧を得る

列挙型のすべての要素を得るには、Enum.GetValues() や Enum.GetNames() を使います。

private enum UserType {
    Guest = 1,
    Member,
    VIP,
    Refused = 99
}
 
private void SomeMethod(){
    foreach(UserType type in Enum.GetValues(typeof(UserType))){
        System.Console.Write(type + ” = ” + ((int) type)+ “\n”);
    }
}

結果:

Guest = 1
Member = 2
VIP = 3
Refused = 99