Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
74
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@psn

JavaScript で UUID (Ver4)

なるべく衝突しないIDを用意したい

時刻やMACアドレスなどの固有の値を使わず、なるべく衝突しない一意のIDを生成したい。それでは、UUIDを作りましょう。

バージョン4

乱数によるUUID。16進表記ではRRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRRとなり、バリアント(10)とバージョン(0100)を除くすべてのビットを乱数(R:122ビット)で生成する。
UUID - Wikipedia

RFC4122 でも確認できます。

他ライブラリではどのように生成しているのか

Chrome Platform Analytics の実装 (Apache License v2.0)

identifier.js
/** @private {string} */
analytics.internal.Identifier.UUID_FMT_ =
    'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';


/** @private {RegExp} */
analytics.internal.Identifier.UUID_MATCHER_ =
    /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;


/**
 * @return {string} A randomly generated UUID V4.
 */
analytics.internal.Identifier.generateUuid = function() {
  var chars = analytics.internal.Identifier.UUID_FMT_.split('');
  for (var i = 0, len = chars.length; i < len; i++) {
    switch (chars[i]) {
      case 'x':
        chars[i] = goog.math.randomInt(16).toString(16);
        break;
      case 'y':
        chars[i] = (goog.math.randomInt(4) + 8).toString(16);
        break;
    }
  }

  return chars.join('');
};
  1. analytics.internal.Identifier.UUID_FMT_ を分解
  2. 分解した文字列(chars)を1文字ずつ取得して
  3. パターンに合う文字を生成・書き換え
  4. 結合します
  • パターンに合わない文字(-4)はそのまま出力されます。
  • パターン「x」の場合は0~9またはa~fのいずれか1文字が選択されます。
  • パターン「y」の場合は89aまたはbのいずれか1文字が選択されます。

なお、.UUID_MATCHER_ は、生成済みのUUIDがパターンと合致するかテストするための正規表現となります。

上記の実装では Google Closure Library が使われています。goog.math.randomInt(number)Math.floor(Math.random() * number)に置き換える事ができます。

uuid-v4-switch.js
switch (chars[i]) {
  case "x":
    chars[i] = Math.floor(Math.random() * 16).toString(16);
    break;
  case "y":
    chars[i] = (Math.floor(Math.random() * 4) + 8).toString(16);
    break;
}

google/closure-library math.js

コードを書く

単体で生成できるようにしてみましょう。

uuid-v4.js
function generateUuid() {
    // https://github.com/GoogleChrome/chrome-platform-analytics/blob/master/src/internal/identifier.js
    // const FORMAT: string = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
    let chars = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split("");
    for (let i = 0, len = chars.length; i < len; i++) {
        switch (chars[i]) {
            case "x":
                chars[i] = Math.floor(Math.random() * 16).toString(16);
                break;
            case "y":
                chars[i] = (Math.floor(Math.random() * 4) + 8).toString(16);
                break;
        }
    }
    return chars.join("");
}

確認する

ブラウザにて確認してみましょう。
test.png

JavaScript で UUID (Ver4) を作ることができました。

74
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
74
Help us understand the problem. What is going on with this article?