もともとはNode.jsでランダムな64bit整数を作りたかったんですが、JavaScriptの数値型では整数は2^53までしかサポートされていないので数値じゃなくて10進文字列で取得しようとしたんです。
別に四則演算を全部やりたいわけではないので、自分で作れるんじゃね?と思いました。
やってみた
ランダムな64bitの16進文字列を作るのは簡単。SIZEを変えれば128bitでも256bitでもいけます。const crypto = require("crypto");
const SIZE = 8; // 8バイト(64ビット)ほしい
crypto.randomBytes(SIZE, (err, buf) => {
if (err !== null) {
// エラー
console.error(err);
return;
}
// Buffer -> 16進文字列
const hexstr = buf.toString("hex");
console.log(hexstr);
});
で、これを10進文字列に変換するわけですが…
あれ?意外と難しいぞ?
JavaScriptのNumber型で扱える範囲を超えるという前提なので、Number.parseIntは使えません。
32bitずつ整数化してあとでつなげようとしても、結局多倍長の加算や乗算が必要になります🤔
結局
NPMのbig-integerパッケージを使いました。
const crypto = require("crypto");
const BigInteger = require("big-integer");
const SIZE = 8; // 8バイト(64ビット)ほしい
crypto.randomBytes(SIZE, (err, buf) => {
if (err !== null) {
// エラー
console.error(err);
return;
}
// Buffer -> 16進文字列
const hexstr = buf.toString("hex");
console.log(hexstr);
// 16進文字列→10進文字列
const bigint = BigInteger(hexstr, 16);
const decstr = bigint.toString();
console.log(decstr);
});
オーバースペックかもしれないけどとりあえず動いた。めでたしめでたし。ひらめいた。
このbig-integerを使って、現在53bitまでしか対応していないmaylilyを64bit対応というか任意精度に対応できるかもしれない。
今度やってみよう。
BigIntは?
ところで、JavaScriptの世界ではBigIntがstage3になっているので無事サポートされたら簡単な操作で64bit(以上の)整数を扱えますが、演算全体の速度に影響するという理由でBabel7には含まれていません。
0 件のコメント:
コメントを投稿