如何用 JavaScript 產生 UUID / GUID?
12 Mar 2017UUID 是「Universally Unique IDentifier」(通用唯一識別碼)的縮寫,目的是唯一的標示資訊。UUID 包含 32 個十六進位數字,並用「-」分隔成五組,每組分別有8、4、4、4、12的數字。例如:「550e8400-e29b-41d4-a716-446655440000」是一組完整的 UUID。
這裡列了幾種使用 JavaScript 產生 UUID / GUID的方法、優缺比較。
方法 1
最簡單的方法就是使用 Math.random()
產出任意16進位數字,但
- 格式不符合 RFC4122 規範
Math.random()
產出的數字可能重覆 (collision),儲存前必須做比對
function _uuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
var uuid = _uuid(); //b3165466-df5b-c3d7-0e94-79d94e8c692f
接下來的方法都是基於 Math.random()
做改善,不管是改進格式或唯一性。
方法 2
先擺好格式,再利用 Math.random()
產出任意數字填入格式中。這個方法解決了方法 1 的格式問題,但仍可能有 collision。
function _uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);});
}
var uuid = _uuid(); //5fc84f46-5743-4ed3-a94d-1ba63b8022a5
方法 3
結合 time stamp 與方法 2,同時解決了格式和 collision 問題。
由於加上 Performance.now()
(亞毫秒級的時間戳記),很難產生 collision。主流瀏覽器皆支援,但 IE 只支援 10 以上或 Edge。
function _uuid() {
var d = Date.now();
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
d += performance.now(); //use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
測試
for(var i = 0; i < 10; i++) {
console.log(_uuid());
}
b382bd5-becd-4d93-8d3f-98aad78a049e
e3dea0f5-37f2-4d79-ae58-490af3228069
3e8d1c2b-f9f9-4a74-a8af-a4e8bebea438
eefbada8-efee-439a-af83-a80dde423dd6
8084d5dd-4f91-4590-927c-4751b49f2de0
06423d2c-1d62-429b-b6f9-de0a8d4ea95f
8b86b39e-5f2e-4abd-a8f0-2108a39a1d8a
62c8628e-e2e2-439d-80cd-b86e31e4bd59
1322e5db-91b0-4f12-94bd-fb4989d3cb95
0db3399e-55c3-44ba-822e-afcabf9b702b
應用
可參考這個小專案-Todo List: Vue.js Example。
每新增一筆 todo,都會為這個 todo 產生一個 ID (UUID),後端儲存進資料庫前,比對 ID 是否已經存在:若是已存在的 ID,即更新這個 todo 的資料;若非已存在的 ID,就新增一筆 todo 資料。