0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】ULID風の一意なIDを生成する方法

Posted at

ULIDとは?

ULIDは、UUID(Universally Unique Identifier)の代替として設計された識別子で、次の特徴を持ちます。

  • ソート可能:タイムスタンプが含まれており、時間順に並べることが可能
  • 一意性:十分にランダムな識別子を生成
  • URLセーフ:Base32 でエンコードされ、URL などで扱いやすい

ULIDのフォーマットは以下のようになっています。

01H0ZK1WBP8TY5G5VME3TGZ7EX
  • 最初の10文字:タイムスタンプ部分(ミリ秒単位のUNIX時間)
  • 残りの16文字:ランダム部分(エンコードされたランダム値)

GASには crypto ライブラリがないため、Utilities.getUuid() などを使わずに、手動でULIDのようなIDを生成します。

処理の流れ

  • enerateULID()

    スプレッドシートで選択されたセル範囲を取得
    選択範囲の各セルにULIDを挿入

    function generateULID() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      var range = sheet.getActiveRange();
      
      if (!range) {
        SpreadsheetApp.getUi().alert("セール未選択");
        return;
      }
      
      for (var i = 0; i < range.getNumRows(); i++) {
        for (var j = 0; j < range.getNumColumns(); j++) {
          console.log((i + 1 )+" : "+ (j + 1))
          range.getCell(i + 1, j + 1).setValue(createULID());
        }
      }
    }
    
  • createULID()

    現在のタイムスタンプを取得
    ランダムな80ビットの値を生成
    エンコード処理を行い、26文字のULIDを作成

    function createULID() {
      var timestamp = Date.now();  // Get current timestamp in milliseconds
      
      //  80-bit 作成
      var randomPart = [];
      for (var i = 0; i < 10; i++) {
        randomPart.push(Math.floor(Math.random() * 256));
      }
      return encodeULID(timestamp, randomPart);   
    }
    
    
  • encodeULID(timestamp, randomPart)

    • Base32エンコード文字セットを定義
    • 48ビットのタイムスタンプをBase32に変換(10文字)
    • 80ビットのランダム値をBase32に変換(16文字)
    • 最終的なULID(26文字)を返す
    function encodeULID(timestamp, randomPart) {
      var encoding = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; 
    
      // Encode timestamp (48-bit = 10 characters in Base32)
      var timeChars = [];
      for (var i = 9; i >= 0; i--) {
        timeChars[i] = encoding.charAt(timestamp % 32);
        timestamp = Math.floor(timestamp / 32);
      }
    
      var randChars = [];
      var value = 0;
      var bitLength = 0;
    
      for (var i = 0; i < randomPart.length; i++) {
        value = (value << 8) | randomPart[i];
        bitLength += 8;
    
        while (bitLength >= 5) {
          bitLength -= 5;
          randChars.push(encoding.charAt((value >> bitLength) & 31));
        }
      }
      
      while (randChars.length < 16) {
        randChars.push(encoding.charAt(0)); // Pad with '0' if needed
      }
    
      // 26-character ULID
      return timeChars.join("") + randChars.join("");
    }  
    
    

サンプルコード

function generateULID() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var range = sheet.getActiveRange();
  
  if (!range) {
    SpreadsheetApp.getUi().alert("セール未選択");
    return;
  }
  
  for (var i = 0; i < range.getNumRows(); i++) {
    for (var j = 0; j < range.getNumColumns(); j++) {
      console.log((i + 1 )+" : "+ (j + 1))
      range.getCell(i + 1, j + 1).setValue(createULID());
    }
  }
}


function createULID() {
  var timestamp = Date.now();  // Get current timestamp in milliseconds
  
  //  80-bit 作成
  var randomPart = [];
  for (var i = 0; i < 10; i++) {
    randomPart.push(Math.floor(Math.random() * 256));
  }
  return encodeULID(timestamp, randomPart);   
}

function encodeULID(timestamp, randomPart) {
  var encoding = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; 

  // Encode timestamp (48-bit = 10 characters in Base32)
  var timeChars = [];
  for (var i = 9; i >= 0; i--) {
    timeChars[i] = encoding.charAt(timestamp % 32);
    timestamp = Math.floor(timestamp / 32);
  }

  var randChars = [];
  var value = 0;
  var bitLength = 0;

  for (var i = 0; i < randomPart.length; i++) {
    value = (value << 8) | randomPart[i];
    bitLength += 8;

    while (bitLength >= 5) {
      bitLength -= 5;
      randChars.push(encoding.charAt((value >> bitLength) & 31));
    }
  }
  
  while (randChars.length < 16) {
    randChars.push(encoding.charAt(0)); // Pad with '0' if needed
  }

  // 26-character ULID
  return timeChars.join("") + randChars.join("");
}

生成データ

image.png

まとめ

  • GASでULIDを生成し、スプレッドシートに挿入可能
  • 時間順にソート可能なID を作成
  • Base32エンコードを利用してUUIDより短く使いやすい
  • スプレッドシートの選択範囲に一括挿入 できる
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?