为什么需要GUID/UUID?这比想象中更简单
\n\n您是否曾想过,网站和应用程序如何区分数据库中的不同记录?或者您的浏览器如何记住是您将商品放入了购物车,而不是其他人?秘密往往隐藏在一个小巧但强大的字符串中——GUID(全局唯一标识符)或其更精确的兄弟UUID(通用唯一标识符)。
\n\n在Stack Overflow上,“How do I create a GUID / UUID?”这个问题获得了数千次浏览。这并非偶然。每个开发者迟早都会遇到这样的任务:“我需要一个唯一ID,但我不想引入整个库。”今天,我们将从头到尾深入探讨JavaScript中的这个主题。您不仅将了解如何生成UUID,还将明白针对您的任务应该选择哪种方法。
\n\n准备好了吗?让我们开始吧!
\n\nUUID到底是什么?(这并非魔法)
\n\n在编写代码之前,让我们先了解一些理论。UUID是一个128位的数字,通常以带连字符的十六进制格式表示。它看起来像这样:
\n\n123e4567-e89b-12d3-a456-426614174000\n\nRFC 4122标准描述了多个版本的UUID。最流行的是:
\n- \n
- 版本4:随机UUID。您在互联网上找到的几乎所有UUID都是这个版本。 \n
- 版本1:基于时间和MAC地址。已过时,但偶尔仍会见到。
- 版本5:通过SHA-1哈希从名称(例如URL)生成。
UUID的主要特性是无需中央服务器即可保证唯一性。发生冲突(两个ID相同)的概率极低,可以忽略不计。据说,如果每秒生成十亿个UUID,那么大约需要100年才会产生一个重复项。这是一个不错的保证,对吧?
\n\n最正确的方法:crypto.randomUUID()
\n\n如果您编写的是现代JavaScript(ES2020+),您可以直接使用内置解决方案——crypto.randomUUID()。此方法在浏览器和Node.js(从版本14.17.0开始)中可用。
\n\n使用方法如下:
\n\n// 浏览器\nconst myUUID = crypto.randomUUID();\nconsole.log(myUUID); // 输出: "f47ac10b-58cc-4372-a567-0e02b2c3d479"\n\n// Node.js (现代版本)\nconst { randomUUID } = require('crypto');\nconst myUUID = randomUUID();\nconsole.log(myUUID);\n\n为什么这是最佳选择?
\n- \n
- 安全性:使用加密安全的随机数生成器。没有可预测的模式。
- 标准:严格符合RFC 4122版本4。
- 性能:底层用C++编写,运行速度极快。
- 零依赖:无需安装第三方库。
重要提示:在旧版浏览器(Internet Explorer、Safari 15.4之前)中,此方法可能不可用。如果您需要支持这些“老古董”,请继续阅读——我们还有备用方案。
\n\n经典技巧:Math.random() + RFC 4122模板
\n\n在crypto.randomUUID()出现之前,开发者们发明了一些变通方法。最流行的方案是使用Math.random()将数字填入UUID模板。这段代码已经在互联网上流传了超过10年:
\n\nfunction generateUUID() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\nconsole.log(generateUUID()); // 输出: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"\n\n它是如何工作的?
\n- \n
- 模板
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx定义了格式。 - 字符 'x'