5

私のアプリは、次のような16進文字列を含むリンクを生成します37c1fbcabbc31f2f8d2ad31ceb91cd8d0d189ca5963dc6d353188d3d5e75b8b3e401d4e74e9b3e02efbff0792cda5c4620cb3b1f84aeb47b8d2225cd40e761a5Ruby / Railsで16進文字列を圧縮する際にRubyで説明したソリューションのように、これらを短くしたいと思います。

JavaScript / NodeJSでこれを行う方法はありますか?

4

3 に答える 3

4

toStringメソッドparseIntメソッドを使用できます。これらは、基本的に、リンクで説明したメソッドと同じことを実行します。

var hexString = "4b3fc1400";
var b36 = parseInt(hexString, 16).toString(36); // "9a29mgw"

そしてそれを元に戻すには、反対のことをする必要があります:

hexString = parseInt(b36, 36).toString(16); // "4b3fc1400"

文字列の唯一の問題は、JavaScriptの数値としては大きすぎて脅威にならないことです。それらをチャンクに分割する必要があります。JavaScriptの数値は2^53(プラス記号)まで正確であるため、処理できる正の最大数値は0x20000000000000(16進数、つまり10進数で9007199254740992)です。精度を使用してチャンクを処理できます。

var hexString = "37c1fbcabbc31f2f8d2ad31ceb91cd8d0d189ca5963dc6d353188d3d5e75b8b3e401d4e74e9b3e02efbff0792cda5c4620cb3b1f84aeb47b8d2225cd40e761a5"

var b36 = "", b16 = "";

var chunk, intChunk;

// 14 is the length of 0x20000000000000 (2^53 in base 16)

for (var i = 0, max = 14; i < hexString.length; i += max) {
    chunk = hexString.substr(i, max);
    intChunk = parseInt(chunk, 16);

    if (intChunk.toString(16) !== chunk) {
        intChunk = parseInt(hexString.substr(i, max - 1), 16);
        i -= 1;
    }

    b36 += intChunk.toString(36)
}

// 11 is the length of 2gosa7pa2gv (2^53 in base 36)

for (var i = 0, max = 11; i < b36.length; i += max ) {
    chunk = b36.substr(i, max);
    intChunk = parseInt(chunk, 36);

    if (intChunk.toString(36) !== chunk) {
        intChunk = parseInt(b36.substr(i, max - 1), 36);
        i -= 1;
    }

    b16 += intChunk.toString(16)
}

console.log(hexString);
console.log(b36);
console.log(b16);

更新: 36の代わりにベース62を使用してさらに圧縮することもできますが、JSはベース36までサポートしているため、その個人表記を手動で実装する必要があります(すでにいくつかの実装があると思います)。

于 2012-08-02T10:15:55.623 に答える
3

node int-encoderは、すでに述べた戦略を使用してこれを行います。

また、多数をサポートします

npm install int-encoder

var en = require('int-encoder');

//simple integer conversion
en.encode(12345678); // "ZXP0"
en.decode('ZXP0'); // 12345678

//convert big hex number using optional base argument
en.encode('e6c6b53d3c8160b22dad35a0f705ec09', 16); // 'hbDcW9aE89tzLYjDgyzajJ'
en.decode('hbDcW9aE89tzLYjDgyzajJ', 16); // 'e6c6b53d3c8160b22dad35a0f705ec09'
于 2012-11-09T01:32:03.263 に答える
2

最も簡単で最速の方法は、URLで使用する64個の安全な文字のセット(AZ、az、0-9、_、$など)を定義することです。次に、3桁ごとの16進数(各4ビット)を2つの安全な文字(各6ビット)にエンコードします。これは乗算と除算を必要とせず、任意の長さの文字列で使用できます。

最後の4ビット部分が使用されているかどうかを示すために、文字列の最後で使用する65番目の文字を選択する必要があります。そうしないと、偶数の文字を含む文字列があいまいになります。それを2nと呼びましょう。次に、3n-1または3nの16進数がエンコードされていますが、どちらかを判断する方法はありません。これらのケースの1つを示すために、特殊文字を使用してシーケンスをたどることができます。例:'。' (限目)。

注:URLには安全な句読文字の独自の定義があるため、ここでセットに選択された最後の数文字はBase64エンコーディングとは異なります。RFC1738を参照してください。

于 2012-08-02T23:25:59.703 に答える