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