にわとりプログラマーの備忘録

覚えたことをすぐ忘れてしまう、自分のための備忘録ブログです。

Flashのクロスドメインセキュリティへの対処方法

FlashからherokuにデプロイしたサーバとHTTP通信をした際に、以下のエラーが発生したので、自分用に調べたことをまとめておきます。

SecurityError: Error #2060: セキュリティサンドボックス侵害

Flashの上記のエラーを解消する為には、参照先サーバのルートディレクトリにcrossdomain.xmlを配置する必要があります。

crossdomain.xmlについて

Flash では Web ブラウザで再生される SWF は、SWF の生成元となる Web ドメイン外にあるデータにはアクセスできません。セキュリティにおけるこのような制約に対する例外を作成するには、ポリシー ファイルを作成します。ポリシー ファイルは、crossdomain.xml という名前の XML ファイルでなくてはなりません。

crossdomain.xmlの読み込み例

Flashから外部サーバにある画像を読み込む為に"http://image-server?id=1"のURLにアクセスしたとします。

この際、Flashは最初に"http://image-server/crossdomain.xml"にアクセスをして、ホストサーバ上のcrossdomain.xmlを確認します。
この時crossdomain.xmlが存在しなかったり、アクセス可能ドメインとして設定されていない場合は、上記のSecurityErrorが発生します。

crossdomain.xmlの書き方

・全てのドメインを許可する

<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
  <allow-access-from domain="*"/>
</cross-domain-policy> 


・許可するドメインを指定する

<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
  <allow-access-from domain="*.example.com"/>
</cross-domain-policy> 


詳しくはこちらを参照すると分かりやすいです。

Node.jsでHello World

node.jsでHello World をするまでの自分用のまとめです。

実行環境

OS : OS X El Capitan

node.jsのインストール

1. node.jsの公式ページからインストーラーをダウンロード
f:id:t-yng:20151106122029p:plain

2. インストーラーを実行して、node.jsをインストールします

動作確認

ターミナルで以下のコマンドを入力して、バージョンが表示されれば無事インストールは完了しています。

$ node -v
v4.2.2

実際にHello Worldを表示してみる

では実際にコードを書いて、"Hello World"を表示してみましょう

1. 最初にプロジェクト用のディレクトリ生成をします

$ mkdir helloworld


2. ディレクトリに移動して、helloworld.jsというファイルを作成してください。

$ cd helloworld
$ touch helloworld.js


3. helloworld.jsに以下のコードを記述

var http = require('http');
 
var server = http.createServer();
server.on('request', doRequest);
server.listen(3000);
console.log('Server running!');
 
// リクエストの処理
function doRequest(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write('Hello World\n');
    res.end();
}


4. 以下のコマンドを入力して、スクリプトを実行します

$ node helloworld.js


5. ブラウザから "http://localhost:3000""にアクセスして、 "Hello World" と表示されれば成功です。
f:id:t-yng:20151106124511p:plain

node.jsのフレームワーク"express"を利用してみる

1. プロジェクトを作成して、カレントディレクトリに移動する

$ mkdir hello-express
$ cd hello-express


2. 以下のコマンドを入力して、"express"をインストールします
カレントディレクトリにnode_modules/expressディレクトリが新たに生成されます。

$ npm install express
express@4.13.3 node_modules/express
├── escape-html@1.0.2
├── merge-descriptors@1.0.0
├── array-flatten@1.1.1
├── cookie@0.1.3
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── content-type@1.0.1
├── methods@1.1.1
├── vary@1.0.1
├── range-parser@1.0.3
├── serve-static@1.10.0
├── fresh@0.3.0
├── path-to-regexp@0.1.7
├── content-disposition@0.5.0
├── etag@1.7.0
├── parseurl@1.3.0
├── depd@1.0.1
├── qs@4.0.0
├── debug@2.2.0 (ms@0.7.1)
├── finalhandler@0.4.0 (unpipe@1.0.0)
├── on-finished@2.3.0 (ee-first@1.1.1)
├── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)
├── accepts@1.2.13 (negotiator@0.5.3, mime-types@2.1.7)
├── type-is@1.6.9 (media-typer@0.3.0, mime-types@2.1.7)
└── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)


3. moduleのローカルインストールとグローバルインストールについて

  • ローカルインストール

カレントディレクトリのnode_modules/ にモジュールがインストールされます。
ローカルインストールされたモジュールはそのプロジェクトからのみ参照ができます。

  • グローバルインストール

-g オプションを付けた場合は、グローバルインストールになります。
/usr/local/lib/node_modules/ にインストールされました。グローバルインストールされたモジュールは全てのプロジェクトから参照できます。

$ sudo npm install -g express
Password:
express@4.13.3 /usr/local/lib/node_modules/express
├── escape-html@1.0.2
├── array-flatten@1.1.1
├── merge-descriptors@1.0.0
├── cookie@0.1.3
├── cookie-signature@1.0.6
├── utils-merge@1.0.0
├── etag@1.7.0
├── vary@1.0.1
├── content-disposition@0.5.0
├── methods@1.1.1
├── content-type@1.0.1
├── range-parser@1.0.3
├── fresh@0.3.0
├── path-to-regexp@0.1.7
├── serve-static@1.10.0
├── parseurl@1.3.0
├── depd@1.0.1
├── qs@4.0.0
├── on-finished@2.3.0 (ee-first@1.1.1)
├── finalhandler@0.4.0 (unpipe@1.0.0)
├── debug@2.2.0 (ms@0.7.1)
├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
├── type-is@1.6.9 (media-typer@0.3.0, mime-types@2.1.7)
├── accepts@1.2.13 (negotiator@0.5.3, mime-types@2.1.7)
└── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)


4. "hello-express.js"というファイルを作成して、以下のコードを記述します

var express = require('express');
var app = express();

app.get('/', function(req, res){
	res.send('Hello Express');
})

var server = app.listen(3000, function(){
	console.log('Server is running!');
})


5. ブラウザから"http://localhost:300"にアクセスして確認してみる
f:id:t-yng:20151106130846p:plain

PHPで素数を求めるプログラムを実装

前回、Java素数を求めるプログラムを実装しました。

Javaで素数を求めるプログラムを実装 - にわとり学生のプログラミング備忘録

今回はPHPで実装を行い、前回と同様100万までの素数を求めた際の
実行速度を計測しました。

実行環境

OS:Windows 7 Professional
CPU:Intel Core i7-3770 3.40GHz
PHP:5.6.2

改善前の実装コード

<?php

ini_set('memory_limit', '512M');

$N = 1000000;

$start_time = microtime(true);

// 探索リスト
$search = [];
for($i=2; $i<=$N; $i++){
    $search[] = $i;
}
// 素数リスト
$primes = [];

do{
    $prime = array_shift($search);
    $primes[] = $prime;

    // 素数の倍数をふるい落とす
    foreach ($search as $key => $value) {
        if($value % $prime === 0){
            unset($search[$key]);
        }
    }

}while($prime < sqrt($N));

foreach ($search as $prime) {
    $primes[] = $prime;
}

foreach ($primes as $prime) {
    print "$prime\n";
}

$end_time = microtime(true);
$time = $end_time - $start_time;
$time = (int)($time*1000);

print "実行時間 : ${time}ms\n";

実行結果(結果の表示有り)

(省略)
999961
999979
999983
実行時間 : 11779ms

実行結果(結果の表示無し)

実行時間 : 7482ms


booleanの配列を利用して改善してみます。

booleanの配列を利用して改善した実装コード

<?php

$N = 1000000;

$start_time = microtime(true);

// 探索リスト
$search = array_fill(0, $N, true);

// 素数でない場合はfalseにする
for($i=2; $i<sqrt($N); $i++){
    // 素数の倍数では何もしない
    if(!$search[$i]){
        continue;
    }

    // 素数の倍数をふるい落とす
    for($j=2; $i*$j<=$N; $j++){
        $search[$i*$j] = false;
    }
}

foreach($search as $key => $value){
    if($value){
        print "$key\n";
    }
}

$end_time = microtime(true);
$time = $end_time - $start_time;
$time = (int)($time*1000);

print "実行時間 : ${time}ms\n";

実行結果(結果の表示有り)

(省略)
999961
999979
999983
実行時間 : 4913ms

実行結果(結果の表示無し)

実行時間 : 499ms

やはりPHPは、Javaと比べると遅くなってしまいますね。

それでもbooleanによる改善後のコードはJavaの改善前のコードよりも速いのを
見ると、アルゴリズムって大事だなと思います!

Javaで素数を求めるプログラムを実装

エラトステネスの篩を利用した、1からNまでの素数を求めるプログラムをJavaで実装しました。

100万までの素数を求めたときの実行速度を計測してみたので、少しメモしておきます。

実行環境

OS:Windows 7 Professional
CPU:Intel Core i7-3770 3.40GHz
Java:1.8.0_40

最初に、そのまま実装したコードです。

実装コード

import java.util.Iterator;
import java.util.LinkedList;

/**
 * エラトステネスの篩を利用して、素数を調べる
 */
public class PrimeChecker1 {

    /**
     * 1からnまでの素数をリストで返す
     * @param n
     * @return
     */
    private void check(int n) {
        

        Timer timer = new Timer();
        timer.start();
        
        LinkedList<Integer> searchNumberList = new LinkedList<>();
        LinkedList<Integer> primeList = new LinkedList<>();

        // 探索リスト生成
        for(int i=2; i<=n; i++){
            searchNumberList.add(i);
        }
        
        do{
            // 探索リストの先頭を素数として取り出す
            int prime = searchNumberList.poll();
            primeList.add(prime);

            // 取り出した素数の倍数を探索リストから削除
            Iterator<Integer> ite = searchNumberList.iterator();
            while(ite.hasNext()){
                if(ite.next() % prime == 0){
                    ite.remove();
                }
            }
        }while(primeList.getLast() < Math.sqrt(n));

        // 残った探索リストの数字を素数としてリストに追加
        primeList.addAll(searchNumberList);
        
        for(int prime : primeList){
            System.out.println(prime);
        }
        
        timer.stop();
    }   
    
    public static void main(String[] args){
        new PrimeChecker1().check(1000000);
    }   
}

/**
 * 時間の計測クラス
 */
class Timer{
    private long startTime;
    
    public void start(){
        startTime = System.currentTimeMillis();
    }
    
    public void stop(){
        long time = System.currentTimeMillis() - startTime;
        System.out.println("実行時間 : "+time+"ms");
    }
}

実行結果(結果の表示有り)

(省略)
999961
999979
999983
実行時間 : 1343ms

実行結果(結果の表示無し)

実行時間 : 766ms


結果を表示して、1.3秒ほど掛かっています…

友達に「booleanの配列使えば、速くできるよ」と教えてもらったので、コードを改善してみました。

booleanの配列を利用して改善した実装コード

import java.util.Arrays;

/**
 * エラトステネスの篩を利用して、素数を調べる
 * @author tomohiro
 *
 */
public class PrimeChecker2 {

    /**
     * 1からnまでの素数をリストで返す
     * @param n
     * @return
     */
    private void check(int n) {
        
        Timer timer = new Timer();
        timer.start();
        
        // 探索リスト生成
        boolean[] search = new boolean[n+1];
        Arrays.fill(search, true);

        // 素数でないものはfalseにする
        for(int i=2; i<Math.sqrt(n); i++){
            // 素数の倍数なら何もしない
            if(!search[i]){
                continue;
            }
            
            // 素数の倍数をふるい落とし
            for(int j=2; i*j <= n; j++){
                search[i*j] = false;
            }
        }
        
        for(int i=2; i<search.length; i++){
            if(search[i]){
                System.out.println(i);
            }
        }
        
        timer.stop();
    }   
    
    public static void main(String[] args){
        new PrimeChecker2().check(1000000);
    }   
}

/**
 * 時間の計測クラス
 */
class Timer{
    private long startTime;
    
    public void start(){
        startTime = System.currentTimeMillis();
    }
    
    public void stop(){
        long time = System.currentTimeMillis() - startTime;
        System.out.println("実行時間 : "+time+"ms");
    }
}

実行結果(結果の表示有り)

(省略)
999961
999979
999983
実行時間 : 551ms

実行結果(結果の表示無し)

実行時間 : 16ms

大分速くなりました!

アルゴリズムはやっぱり難しいです。
速く動くアルゴリズム思い付ける人って素直に尊敬します。

頑張ろう!

Ubuntu14.04でCaplLockにCtrlを割り当てる

CapsLockキーにCtrlキーを割り当てる方法です。

参考
まさおのブログ (表): Ubuntu 14.04 LTS で、caps lock キーを ctrl キーに変更する

/etc/default/keyboardを修正

$ sudo vi /etc/default/keyboard

XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS="ctrl:nocaps"

Ubuntuを再起動して、設定を反映させる。

GitHubにpushしたファイルを削除する方法

.gitignoreにファイルを追加
.gitignoreに削除するファイルを書き込んで、githubにプッシュしないように設定

対象ファイルをgitの管理化から削除
ディレクトリの場合は、--cached の前に -r を付ける

$ git rm [-r] --cached [ファイル名]

変更をコミット

$ git commit -m "remove file under git management"

githubにプッシュ

$ git push -u origin <branch>

以上でgithubリポジトリからファイルが削除されます.

AndroidStudioでGoogle Play Service APIs を利用できるように設定する

Google Places API for Androidを利用したかったので、AndroidアプリでGoogle Play Service APIs を利用する方法について調べたのでメモしておきます。

Eclipseについては下記のgoogle公式ページ内の"ECLIPSE WITH ADT"を参考にしてください。

参考ページ Setting Up Google Play Services

AndroidStudioのプロジェクト内にあるbuild.gradleに以下の記述を追加

dependencies {
   compile 'com.google.android.gms:play-services:7.5.0'
}

以上で、Google Play Services APIsを利用できるようになります。


エラーについて
実行時に以下のようなエラーが出ることがあります。

Google Play services out of date. Requires xxxxxxx but found xxxxxxxx

これは端末にインストールされている、「Google Play開発者サービス」アプリケーションの
バージョンが古いことが原因です。

google Play store からアプリをアップデートすれば、解決されます。

google store で検索しても出てこない? ので、URLを記載しておきます。
Google Play開発者サービス - Google Play の Android アプリ

gradleはライブラリの依存関係が大分簡単になるので、とても便利だなと思います。