1. ホーム
  2. javascript

[解決済み] aX4j9Z "のような短いuidを生成する方法 (JSの場合)

2023-01-23 08:46:46

質問

私のウェブアプリケーション(JavaScript)で、(実際には異なるタイプの文字列や文字列の配列である)異なるオブジェクトのための短いガイドを生成したいのですが、それは可能ですか?

私は、uids(guids)のために"aX4j9Z"のようなものが欲しいです。

これらの uid は、Web 転送と js 文字列処理のために十分に軽量で、巨大な構造ではない(10k 要素以下)ために非常にユニークであるべきです。uid の生成後に、この uid が構造体にすでに存在するかどうかを確認し、存在する場合は再生成できることを意味します。

どのように解決するのですか。

参照 Mohamedの回答 をご覧ください。 shortid パッケージ ). 特別な要件がない場合は、このページの他のソリューションの代わりにこれを使用することをお勧めします。


6 文字の英数字からなるシーケンスは、10k のコレクションをランダムにインデックス化するのに十分な大きさです (36 6 = 22 億、そして 36 3 = 46656).

function generateUID() {
    // I generate the UID from two parts here 
    // to ensure the random number provide enough bits.
    var firstPart = (Math.random() * 46656) | 0;
    var secondPart = (Math.random() * 46656) | 0;
    firstPart = ("000" + firstPart.toString(36)).slice(-3);
    secondPart = ("000" + secondPart.toString(36)).slice(-3);
    return firstPart + secondPart;
}

ランダムに生成されたUIDは、~√N個の数を生成した後に衝突が発生する(誕生日のパラドックス)ため、チェックなしで安全に生成するには6桁が必要です(旧バージョンでは4桁しか生成しないため、チェックしないと1300個のIDの後に衝突が発生します)。

衝突チェックを行えば、桁数は3~4桁減らすことができますが、生成するUIDが多くなると性能がリニアに低下することに注意してください。

var _generatedUIDs = {};
function generateUIDWithCollisionChecking() {
    while (true) {
        var uid = ("0000" + ((Math.random() * Math.pow(36, 4)) | 0).toString(36)).slice(-4);
        if (!_generatedUIDs.hasOwnProperty(uid)) {
            _generatedUIDs[uid] = true;
            return uid;
        }
    }
}

シーケンシャルジェネレータの利用を検討する(例えば user134_item1 , user134_item2 もし、一意性を必要とし、予測不可能性を必要としないのであれば、...)。予測不可能性を回復するために、順次生成される文字列を "Hash"することができます。

を使って生成されたUIDは Math.random を使って生成されたUIDは安全ではありません(そして、どのみちクライアントを信用してはいけません)。行う ではなく ミッションクリティカルなタスクでは、その一意性や予測不可能性に依存しないでください。