仙台の山奥で自転車に乗ったり転んだり

愛車の GIOS でサイクリングしたりポタリングしたり、それをブログに記録してみたり。ロードバイクや自転車や坂のことを書いてみたり。ときたまプログラムのことを忘れないようにメモってみたり。

JavaScriptとNode.jsの勉強、乱数とか

擬似乱数的な乱数ビット列から、ランダムな文字列を生成

var LISTEN      = 8124;
var URANDOM     = '/dev/urandom';
var BUFFER_SIZE = (264 / 8); // 33 Bytes = 264 Bits
var BASE64      = 'base64';

var http = require('http');
var fs   = require('fs');

function getRandomString() {
    var fd     = fs.openSync(URANDOM, 'r');
    var result = fs.readSync(fd, BUFFER_SIZE, 0, BASE64);
    fs.close(fd);

    return result[0];
};

http.createServer(function (request, response) {
    var httpResponseHeader = {
        'Content-Type': 'text/plain'
    };
    var body = getRandomString();

    response.writeHead(200, httpResponseHeader);
    response.end(body + '\n');
}).listen(LISTEN);

console.log('Server running at http://127.0.0.1:%s/', LISTEN);

53ビット乱数を生成
↓まるっと参考にさせていただきました。
http://liosk.blog103.fc2.com/blog-entry-198.html
http://liosk.blog103.fc2.com/blog-entry-197.html

var LISTEN    = 8124;
var PRECISION = 53;

/**
 * Returns an unsigned x-bit random integer.
 * 
 * @param int bit A positive integer ranging from 0 to 53, inclusive.
 * @return int An unsigned x-bit random integer (0 <= getRandomInt(x) < 2^x).
 * @see http://liosk.blog103.fc2.com/blog-entry-198.html
 */
function getRandomInt(bit) {
    if (bit < 0) {
        return NaN;
    };
    if (bit > 53) {
        return NaN;
    };

    var result = NaN;
    if (bit <= 30) {
        result = (0 | Math.random() * (1 << bit));
    } else {
        result = (0 | Math.random() * (1 << 30))
               + (0 | Math.random() * (1 << (bit - 30))) * (1 << 30);
    };

    return result;
}

var http = require('http');
var util = require('util');

http.createServer(function (request, response) {
    var value   = getRandomInt(PRECISION);
    var padding = '';
    for (var i = 0; i < PRECISION; i++) {
        padding += '0';
    };
    var bit = (padding + value.toString(2)).slice(-1 * PRECISION);

    var httpResponseHeader = {
        'Content-Type': 'text/plain'
    };
    var body = util.format('Result: %s', bit);

    response.writeHead(200, httpResponseHeader);
    response.end(body + '\n');
}).listen(LISTEN);

console.log('Server running at http://127.0.0.1:%s/', LISTEN);

XorShift法で乱数を生成

var LISTEN  = 8124;
var URANDOM = '/dev/urandom';
var BASE64  = 'base64';

/**
 * Pseudorandom number generators.
 *
 * @see <a href="http://ja.wikipedia.org/wiki/Xorshift">Xorshift</a>
 */
var XorShift = (function() {
    var x = 123456789;
    var y = 362436069;
    var z = 521288629;
    function XorShift(seed) {
        if (!seed) {
            this.seed(seed);
        };
    };
    XorShift.prototype.seed = function(seed) {
        w = seed;
    };
    XorShift.prototype.rand = function() {
        var t;

        t = x ^ (x << 11);
        x = y;
        y = z;
        z = w;
        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));

        return w;
    };
    return XorShift;
}) ();

var http     = require('http');
var xorshift = new XorShift();

http.createServer(function (request, response) {
    var httpResponseHeader = {
        'Content-Type': 'text/plain'
    };
    var body = xorshift.rand();

    response.writeHead(200, httpResponseHeader);
    response.end(body + '\n');
}).listen(LISTEN);

console.log('Server running at http://127.0.0.1:%s/', LISTEN);