盖德
抗碰撞的ids优化了水平缩放和二进制搜索取景性能.
目前可供节点,浏览器,Ruby,.Net,Go,PHP和Elixir使用(见下文的端口 -- -- 欢迎更多的端口).
cuid() 返回带有一些碰撞破坏措施的短随机字符串。 安全用作 HTML 元素 ID 的, 以及独特的服务器侧记录查看 .
示例
节点风格. 对于浏览器, 要么捆绑类似的东西 浏览器 或者说 网络软件包,或使用独立的版本,并离开所需行.
var cuid = require('cuid');
console.log( cuid() );
// ch72gsb320000udocl363eofy
安装
$ npm install --save cuid
或从 ./dist。 。 。 .
断了
** c - h72gsb32 - 0000 - udoc - 133eofy **
这些团体按顺序排列如下:
- 'c' - 将此识别为 cuid, 并允许您在 html 实体 ids 中使用 .
- 时间戳
- 计数器 - 一个单一的过程可能生成相同的随机字符串. 伪随机源越弱,概率越高. 随着处理器的速度加快,这个问题变得更加严重. 柜台会翻转 如果值太大.
- 客户指纹
- 修道会随机( S)
Math.random()在 Java 脚本中)
指纹
在浏览器中,第一个字符来自用户代理字符串(相当独特),支持的mimeTypes(同样相当独特,除了IE,总是返回0). 这个字符串与全球范围的变量数相接(这也相当独特),结果被裁剪为4个字符.
在节点,前两个字符是从该过程提取的.pid. 以下两个字符取自主机名.
动机
现代的网络应用与几年前的应用有不同的要求. 我们的现代独特标识器有一份更严格的要求清单,这些要求不能全部被任何现有的GUID/UID规格满足:
水平可伸缩性
今天的应用程序不会在任何一个单机上运行.
应用程序可能需要支持在线/离线能力,这意味着我们需要一种方法让不同主机上的客户端生成不会与其他主机生成的ID相撞的ID——即使它们没有连接到网络上.
大多数伪随机算法将时间用ms作为随机种子. 随机ID在单独运行过程中(如被克隆的虚拟机或客户端浏览器)缺乏足够的 en来保证不相撞. 应用程序开发者报告 v4 UUID 相撞,当ID 生成在众多机器之间分配时,导致其应用程序出现问题,以至于大量ID在同一毫秒内生成.
每个新客户端都指数地增加相撞的机会,与随机串中每个新字符指数地减少相撞的机会一样. 成功的应用在每天以上百或上千个新客户端的规模进行,因此通过添加随机字符来对抗缺乏 en是失败策略.
由于这个问题的性质,可以从地上建立一个应用软件,在这个问题重新出现其头部之前将其规模扩大到一百万用户. 当你注意到这个问题的时候(当你的高峰时钟使用需要每毫秒创建几十个ID),如果你的db由于你认为你的guids是安全的,对ID没有独特的约束,你就处于一个受伤害的世界. 您的用户开始看到不属于他们的数据,因为db只返回它发现的第一个ID匹配.
或者,你玩它安全, 你只让你的数据库创建ID。 写作只发生在主数据库上,而负载被分散在读取的复制品上. 但是,由于这种压力,你也必须开始横向地缩放你的数据库,然后突然你的应用程序开始爬行(如果db足够聪明,可以保证写主机之间独特的ID),或者你开始得到不同db主机之间的ID相撞,所以写主机不同意哪个ID代表哪个数据.
业绩
由于实体可能需要在高性能循环中生成,id生成速度应该快. 这意味着不能等待同步的 en池请求,或者跨进程/跨网络通信. 性能在浏览器中缓慢到不切实际. 所有 en源需要足够快来同步取用.
更糟糕的是,当数据库是唯一保证ID是独一无二的时,这意味着客户端被迫向数据库发送不完整的记录,并等待网络回转,然后才能在任何算法中使用ID. 别管客户的快速表现了 这根本是不可能的.
这种状况已使一些客户创建只能用于单一客户会话的ID(如内存计数器). 当数据库返回真实的ID时,客户端必须做一些杂乱逻辑来交换正在使用的ID.
如果客户端的ID生成更强,相撞的几率会更小,客户端可以将完整的记录发送给db进行插入,而无需等待完整的来回请求在使用ID前完成.
临时增加身份证
由同一种过程所生成的管子在同毫秒内产生出不到一万个管子时会单调地增加. 由不同过程所产生出,如果过程时钟同步的话,cuids在时间上仍然会有越来越大的价值.
自动增加的身份证适于用作 高性能数据库主密钥,因为它们可以被二进制搜索。 纯伪随机变体不符合这一要求.
小声
某种程度上与性能有关,生成ID的算法需要微小的执行. 这对厚客户端JavaScript应用程序尤其重要.
警卫
客户端可见的ID往往需要有足够的随机数据,从而实际上无法尝试根据已经存在,已知的ID来猜测有效的ID. 这使得简单的相继ID在客户端生成的数据库密钥上无法使用.
可移动性
UUID / GUID 算法中大多数更强大的形式需要访问浏览器中没有的OS服务,这意味着它们无法按规定执行.
幼虫的特征
可缩放
由于时间戳和计数器,cuid在一台机器上非常擅长生成独特的ID.
由于有指纹,cuid也擅长防止多个客户相撞.
快点
因为盖子可以安全地同步生成,所以可以快速地生成出很多. 由于你不太可能遇到相撞,所以你不必等待到数据库的来回旅行,只是为了在数据库中插入完整的记录.
由于Cuids单调增长,数据库主键性能得到显著提升.
以不足 1k 的精度和压缩值来配音, cuid 源应该适合甚至最轻量级的移动客户端, 并且不会对您的应用程序的下载时间产生显著影响, 尤其是如果您遵循最佳做法并将其与您的其他代码相配合, 以避免额外文件请求的暂时性命中 .
安全
Cuids包含足够的随机数据和移动部件,使得基于已存在的id的猜想另一个id几乎不可能. 这也打开了一种侦测滥用尝试的方法——如果客户端请求大量不存在的ID块,那么客户端很有可能是恶意的,或者试图获取不属于它的数据.
可移植
盖德中唯一可能难以在不同客户之间复制的部分是指纹. 为了移植到不同的客户端,很容易超越指纹方法. Cuid在浏览器中已经独立工作,或者作为一个节点模块,所以可以在需要使用的地方使用cuid.
该算法也容易被其他语言所复制. 鼓励您将其移植到您认为合适的语言中 .
端口 :
- JavaScript (浏览器和节点)
- 鲁比的接地 - 说吧 伊恩·香农
- 为. 净额 - 说吧 克莱门特·布尔吉斯
- 库德为去 - 说吧 吕克·海因里希
- pHP 的密钥 - 说吧 安德·贾斯米
- 埃利克西尔的库德 - 说吧 卢卡斯·杜艾利贝
- 哈斯凯尔的图案 - 说吧 丹尼尔·巴克马斯特
- 用于 Python 的 Cuid - 说吧 拉米·乔杜里
- 给克洛朱尔 - 说吧 郝康 邓
- 用于 Java 的 Cuid - 说吧 尼兰·马克坦纳
简短的 URL
需要更小的身份证吗? cuid.slug() 这是给你的。 7到10个角色, .slug() 对简短的urls来说是一个伟大的解决方案. 随着内部计数器的增加,斯拉格可能长出多达10个字符. 它们有利于URL弹壳分解(即:, example.com/some-post-title-<slug>不过 绝对不推荐数据库中唯一的ID。坚持数据库密钥的完整密钥.
注意点 弹子
-
单调增长的可能性较小。 如果可能的话,请坚持数据库搜索的完整取料.
-
拥有较少的随机数据,更少的计数器空间,更少的指纹空间,这意味着它们都更容易相撞或被猜测,特别是随着CPU速度的提高.
如果猜测现有身份会向恶意用户透露机密信息,请不要使用. 例如,如果你在提供谷歌驱动器或DropBox这样的服务,而DropBox是用户的私人文件的主机,那么请 cuid() 结束 .slug()。 。 。 .
问 题
这是 GUID / UUID 的替换吗 ?
没有 Cuid对于它设计的使用案例来说是巨大的 -- -- 用来为多个id生成主机的应用程序生成ID,这些应用程序需要经过几十个或数百个新实体每秒可扩展. 换句话说,如果你正在建立一个网络或移动应用程序,并且想要保证你选择id标准不会拖慢你,cuid是为你准备的.
然而,如果你需要模糊ID生成的顺序,或者如果知道一个ID生成的确切时间可能会有问题,那么你会想用不同的东西.
Cuids不应被视为加密安全(但大多数guid算法也不应如此)。 在你依赖它之前,先确定你的图书馆是加密的.
你为什么不使用sha1,md5等?
在JavaScript中一个sha1的实现本身大约300行,没有压缩,它的使用不会带来什么好处. 相形之下,cuid源代码的重量低于100行代码,没有被压缩. 它也付出了相当大的业绩成本。 Md5也有类似的问题.
为什么没有破折叠?
几乎所有的网络技术识别符都允许数字和字母(虽然有些需要您从一个字母开始——因此在cuid开头的"c"). 然而,在一些标识名称中不允许有破折号. 删除各组之间的破折号可以使ID更便携. 另外,在申请中不应依赖身份识别分类。 删除它们会阻止应用程序开发人员试图从cuid中提取数据.
水泥规格不应视为API合同。 以此处所述的分类为依据的守则应被视为简洁而不适用于生产.
提交问题或评论
信贷
由作者埃里克·艾略特创作, "编程JavaScript应用(O'Reilly)"
感谢 调图 用于支持和生产测试.