UUID version1

var create_RFC4122_UUID_Generator_version_1 = function (MS_GUID/*Boolean*/) {
  var int = Math.floor;
  var random = Math.random;
  var zero52 = '0000000000000000000000000000000000000000000000000000';
  // zero52 = Array(52).join('0');

  var version = 1;
  var time_base = -Date.UTC (1582, 1, 1, 0, 0, 0); //基準時間
  var buffer = (new Date).getTime (); //比較のため
  var clock_seq;
  var clock_seq_hi;
  var node = randD4Hex () + randD4Hex () + randD4Hex ();

  function randD4Hex () {
    return ('000' + int (random () * (1 << 16)).toString (16)).slice (-4);
  }


  if (MS_GUID) // clock_seq_hi & variant
    clock_seq_hi = (6 << 4) + int (random () * (1 << 4));
  else
    clock_seq_hi = (2 << 5) + int (random () * (1 << 5));

  clock_seq = (clock_seq << 16) + int (random () * (1 << 16)); //シフトして合成

  return function () {
    var now  = (new Date).getTime ();
    var time = time_base;

    if (buffer > now) //時間が遡った場合
      clock_seq += 1;
    
    time   += (buffer = now);

    // 必要な60ビット- 53ビットの整数 = 7ビット(ランダムに生成)
    // 2進法に直して・・・・
    var time60 = (zero52 + time.toString (2)).slice (-53) +
                 ('000000' + int (random () * (1 << 8)).toString (2)).slice (-7);
    var time_hi  = (version << 12) | parseInt (time60.substring (0, 16), 2);
    var time_mid = parseInt (time60.substring (16, 32), 2);
    var time_low = parseInt (time60.substring (32), 2);

    return [
      ('0000000' + time_low.toString (16)).slice (-8),
      ('0000000' + time_mid.toString (16)).slice (-4),
      ('0000000' +  time_hi.toString (16)).slice (-4),
      ('0000000' + clock_seq.toString(16)).slice (-4),
      node
    ].join ('-');
  };
};