LoginSignup
97
79

More than 5 years have passed since last update.

JavaScript で UUID (Ver4)

Last updated at Posted at 2017-02-14

なるべく衝突しない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) を作ることができました。

97
79
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
97
79