難読化されたJavaScriptコードを展開するスクリプトを書いた

難読化されたJavaScriptコードをコマンドラインで展開してくれるツールを
探したけどパッと見つからなかったのでOnline JavaScript beautifierで使われている
js_beautify.jsというのをPerlに翻訳してみた。

https://github.com/hironorism/p5-js-beautify


使い方は至って簡単に以下のようにすると展開したJavaScriptコードが出力されまする。

$ perl js_beautify.pl jquery-1.5.min.js


今は単純にJavaScriptコードをPerlに直訳しただけなので(コメントとかもほぼそのまま・・・)
今後パッケージ化と、後入力にURLを指定出来るようにしたいと思っています。

1台サーバでFastCGIアプリをダウンタイム無く更新する方法について

なんか難しく考えていたけど実に単純な方法で出来るような気がしたのでメモ。


アプリ(fcgi_app.psgi)

#!/usr/bin/env plackup -s FCGI
use Plack::Handler::FCGI;

my $app = sub {
     return [
        200,
        [ 'Content-Type' => 'text/html' ],
        [ 'BEFORE' ]
    ];
};

my $server = Plack::Handler::FCGI->new(
    nporc  => 3,
    listen  => [ '/tmp/fcgi.sock' ],
    pidfile => '/tmp/fcgi.pid',
    detach => 1,
);

$server->run( $app );

nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        location / {
               set $script "";
               set $path_info $uri;
               fastcgi_pass   unix:/tmp/fcgi.sock;
        }
    }
}


1 アプリ起動

$ ./fcgi_app.psgi

2 nginx起動

$ sudo nginx

3 アプリを更新、ソケット名、PIDファイル名を変更

#!/usr/bin/env plackup -s FCGI
use Plack::Handler::FCGI;

my $app = sub {
     return [
        200,
        [ 'Content-Type' => 'text/html' ],
        [ 'AFTER' ] # BEFORE => AFTER
    ];
};

my $server = Plack::Handler::FCGI->new(
    nporc  => 3,
    listen  => [ '/tmp/fcgi2.sock' ], # fcgi.sock => fcgi2.sock
    pidfile => '/tmp/fcgi2.pid', # fcgi.pid => fcgi2.pid
    detach => 1,
);

$server->run( $app );

4 更新後のアプリを起動

$ ./fcgi_app.psgi

$ ls /tmp | grep fcgi
fcgi.pid
fcgi.sock
fcgi2.pid
fcgi2.sock

5 nginx.confのfasctcgi_passをfcgi2.sockを見るように更新

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        location / {
               set $script "";
               set $path_info $uri;
               fastcgi_pass   unix:/tmp/fcgi2.sock;
        }
    }
}

6 nginx再起動

$ sudo nginx -s reload

7 更新前のプロセスを終了

$ kill `cat fcgi.pid`

多分これでいけるのでは。

何度目かのmergesortのお勉強

今度は同マージソート

Perl

my @b;
sub merge_sort {
    my ($a, $low, $high) = @_;
    $low  //= 0;
    $high //= @$a -1;

    my ($i, $j, $k);
    return if $low >= $high;
    
    my $mid = int( ($low + $high) / 2 );

    merge_sort($a, $low, $mid);
    merge_sort($a, $mid+1, $high);
 
    for ($i = $low; $i <= $mid; $i++) {
        $b[$i] = $a->[$i]; 
    }
 
    for ($i = $mid+1, $j = $high; $i <= $high; $i++, $j--) {
        $b[$i] = $a->[$j];
    }

    $i = $low; $j = $high;
    for ($k = $low; $k <= $high; $k++) {
        if ($b[$i] <= $b[$j]) {
            $a->[$k] = $b[$i++];
        }
        else {
            $a->[$k] = $b[$j--];
        }
    }
}

sub main {
    my @a = (10, 2, 34, 11, 13, 5, 55);
    merge_sort(\@a);
    print join(',', @a), $/;
}

main() unless caller;

Python

b = []
def p(a):
    print ",".join([ str(x) for x in a])

def merge_sort(a, low, high):
    global b
    if len(b) == 0:
        b = [ 0 for i in range(0,len(a)) ]

    if low >= high:
        return

    mid = int( (low+high) / 2 )

    merge_sort(a, low,  mid)
    merge_sort(a, mid+1, high)

    i = low
    while i <= mid:
        b[i] = a[i]
        i += 1

    i = mid + 1
    j = high
    while i <= high:
        b[i] = a[j]
        i += 1
        j -= 1

    i = k = low 
    j = high

    while k <= high:
        if b[i] <= b[j]:
            a[k] = b[i]
            i = i + 1
        else:
            a[k] = b[j]
            j = j - 1
        k = k + 1

def main():
    a = [10, 2, 34, 11, 13, 5, 55, 5];
    merge_sort( a, 0, 7 )
    p(a)

if __name__ == '__main__':
    main()

JavaScript

var b = [];

function merge_sort(a, low, high) {
    if (low >= high) { return }
    
    var mid = Math.floor( (low + high) / 2 );

    merge_sort(a, low, mid);
    merge_sort(a, mid+1, high);

    var i; 
    for (i = low; i <= mid; i++) {
        b[i] = a[i]; 
    }
 
    for (i = mid+1, j = high; i <= high; i++, j--) {
        b[i] = a[j];
    }

    i = low; 
    j = high;
    for (k = low; k <= high; k++) {
        if (b[i] <= b[j]) {
            a[k] = b[i++];
        }
        else {
            a[k] = b[j--];
        }
    }
}

function main() {
    var a = [10, 2, 34, 11, 13, 5, 55];
    merge_sort(a, 0, 6);
    console.log("%s",  a.join(',') );
}

main();

元のコードはCなのだけどPerl,JavaScriptはほぼそのままって感じで書き換えられたけどPythonはちょっと違ったので慣れないのもあって危うくPythonが嫌いになりそうなくらい苦労した。

SRM 148 DIV2 250

与えられた数字の各桁の数字の中で与えられたその数字自体を割り切れるものをカウントして返す

#include <string>
#include <vector>
#include <sstream>
using namespace std;

class DivisorDigits {
    public:
    int howMany(int number) {
        int count = 0;
        string s;
        stringstream ss;

        ss << number;
        s = ss.str();

        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '0') {
                continue;
            }
            int n = s[i] - '0';
            if (number % n == 0) {
                count++;
            }
        }	
        return count;
    }
};

何度目かのquicksortのお勉強

定本 Cプログラマのためのアルゴリズムとデータ構造 (SOFTBANK BOOKS)

定本 Cプログラマのためのアルゴリズムとデータ構造 (SOFTBANK BOOKS)

topcoderの問題を解く時に「とりあえずソートして〜」とか思ったことがあったのだけどバブルソートしか書けない自分に絶望したので勉強がてら『定本 Cプログラマのためのアルゴリズムとデータ構造』に載っていたクイックソートのコードを自分がかじった事がある言語で書直してみた。


Perl

#!perl
use strict;
use warnings;

sub qsort {
    my ($a, $l, $r) = @_;
    $l = 0                unless defined $l; 
    $r = scalar @{$a} - 1 unless defined $r;

    return if $l >= $r; 

    my $i = $l - 1;
    my $j = $r;
    my $pivot = $a->[$r];

    my $t;
    while (1) {
        while ($a->[++$i] < $pivot) {}
        while ($i < --$j && $a->[$j] > $pivot) {}
        last if $i >= $j;

        $t = $a->[$i];
        $a->[$i] = $a->[$j];
        $a->[$j] = $t;
    }
    $t = $a->[$i];
    $a->[$i] = $a->[$r];
    $a->[$r] = $t;
 
    qsort( $a, $l, $i-1 );
    qsort( $a, $i+1, $r ); 
}

sub main {
    my @a = (10, 2, 34, 11, 13, 5, 55, 11);
    qsort( \@a );
    print "@a", $/;
}

main() unless caller;

Python

def qsort(a, l, r):
    if l >= r:
        return

    i = l
    j = r - 1
    pivot = a[r]
    while 1:
        while a[i] < pivot:
            i += 1 
        while i < j and a[j] > pivot:
            j -= 1
        if i >= j:
            break

        t = a[i]
        a[i] = a[j]
        a[j] = t

    t = a[i];
    a[i] = a[r];
    a[r] = t;
 
    qsort( a, l, i-1 );
    qsort( a, i+1, r ); 


def main():
    a = [10, 2, 34, 11, 13, 5, 55, 11];
    qsort( a, 0, len(a) - 1 )
    for x in a:
        print x

if __name__ == '__main__':
    main()

JavaScript

function qsort(a, l, r) {
    if (l >= r) {
        return; 
    }

    var i = l - 1;
    var j = r;
    var pivot = a[r];

    var $t;
    while (1) {
        while (a[++i] < pivot) {}
        while (i < --j && a[j] > pivot) {}
        if (i >= j) {
            break;
        }

        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    t = a[i];
    a[i] = a[r];
    a[r] = t;
 
    qsort( a, l, i-1 );
    qsort( a, i+1, r ); 
}

function main() {
    var a = [10, 2, 34, 11, 13, 5, 55, 11];
    qsort(a, 0, a.length - 1);

    for (var i = 0; i < a.length; i++) {
        console.log("%d", a[i]);
    } 
}

main();

SRM 147 DIV2 250

A-Zで構成され、アルファベット順でN文字横にずらした文字列(ex.N=2:A=>C,B=>D)が与えられるので元の文字列を求めよという問題

#include <string>
#include <vector>
#include <sstream>

using namespace std;

class CCipher {
    public:
    string decode(string cipherText, int shift) {
        stringstream decoded;
        int n = 'Z' - 'A' + 1;
        int m = shift % n;

	for (int i=0; i<cipherText.length(); i++) {
            char c =  cipherText[i] - m;
            if (c < 'A') {
                c = c + n;
            }
            decoded << c;
        }	
        return decoded.str();
    }
};