UNPKG

@gby/uniqueid

Version:

uniqueid 无任何依赖,提供了获取唯一标识相关的工具,比如:UUID、UCID、Fingerprint、浏览器指纹、唯一标识符 等等

166 lines (160 loc) 5.3 kB
/* @gby/uniqueid v1.2.0 author: { "name": "郭斌勇", "email": "guobinyong@qq.com" } license: MIT homepage: https://github.com/GuoBinyong/uniqueid#readme repository: { "type": "git", "url": "https://github.com/GuoBinyong/uniqueid" } description: uniqueid 无任何依赖,提供了获取唯一标识相关的工具,比如:UUID、UCID、Fingerprint、浏览器指纹、唯一标识符 等等 */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /** * 获取浏览器的Canvas指纹,用来标识设备上的浏览器 * 理论上,对于 不同计算机实体的不同浏览器会生成不同的指纹标识 * @returns * * * 经过测试,ctx.fillRect() 会导致在 Safari、Chrome、Edge 等浏览器刚启动初期渲染的Canvas指纹不一致,Safari经常需要刷新三次才能得到稳定的 Canvas指纹 * 所以,这里不用 ctx.fillRect() 进行绘制; * 另外部分 window.navigator 中的数据也浏览器刚启动前期,也会有变化 * 所以,这里也不使用 window.navigator */ function getCanvasFingerprint() { // 带有各种字符的文本,充分体现渲染差异 var text = "?! 科研者 GuoBinYong abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?!"; var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); if (ctx) { ctx.textBaseline = "alphabetic"; ctx.font = '14px Arial'; ctx.fillStyle = '#ccc'; ctx.fillText(text, 2, 3); } var dataURL = canvas.toDataURL('image/jpeg'); return dataURL.replace("data:image/jpeg;base64,", ""); } // 存储 id 的 key 的前缀 var Key_Prefix = "_?!_"; // 设置 用于存储 id 的 key 的前缀 function setKeyPrefix(keyPrefix) { Key_Prefix = keyPrefix; } //存储 uuid 的key后缀 var uuid_KeySuffix = "_uuid"; /** * 获取 UUID 通用唯一识别码,用于标识浏览器,对于不同电脑实体的不同浏览器 会有不同的值 * @returns */ function getUUID() { var key = Key_Prefix + uuid_KeySuffix; var id = localStorage.getItem(key); if (!id) { var fp = getCanvasFingerprint(); id = String(murmurhash3_32_gc(fp)); localStorage.setItem(key, id); } return id; } /** * 设置 UUID * @param {*} id */ function setUUID(id) { var key = Key_Prefix + uuid_KeySuffix; localStorage.setItem(key, id); } /** * 生成唯一的标识符,每次调用生成的都不一样 * @returns {string} */ function createUniqueIdentifier() { return Date.now().toString() + String(Math.random()).slice(1); } // 存储 uuid 的key的后缀 var ucid_KeySuffix = "_ucid"; /** * 获取 UCID * 如果不重置,则每个浏览器中同一个域名下每次获取的都一样 * @returns */ function getUCID() { var key = Key_Prefix + ucid_KeySuffix; var id = localStorage.getItem(key); if (!id) { id = createUniqueIdentifier(); localStorage.setItem(key, id); } return id; } /** * 设置 UCID * @param {*} id */ function setUCID(id) { var key = Key_Prefix + ucid_KeySuffix; localStorage.setItem(key, id); } /** * MurmurHash3 算法 * @param key * @returns */ function murmurhash3_32_gc(key) { var remainder = key.length & 3; // key.length % 4 var bytes = key.length - remainder; var c1 = 0xcc9e2d51; var c2 = 0x1b873593; var h1, h1b, k1; for (var i_1 = 0; i_1 < bytes; i_1++) { k1 = (key.charCodeAt(i_1) & 0xff) | ((key.charCodeAt(++i_1) & 0xff) << 8) | ((key.charCodeAt(++i_1) & 0xff) << 16) | ((key.charCodeAt(++i_1) & 0xff) << 24); ++i_1; k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; k1 = (k1 << 15) | (k1 >>> 17); k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; h1 ^= k1; h1 = (h1 << 13) | (h1 >>> 19); h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff; h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); } var i = bytes - 1; k1 = 0; switch (remainder) { case 3: { k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; break; } case 2: { k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; break; } case 1: { k1 ^= key.charCodeAt(i) & 0xff; break; } } k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; k1 = (k1 << 15) | (k1 >>> 17); k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; h1 ^= k1; h1 ^= key.length; h1 ^= h1 >>> 16; h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; h1 ^= h1 >>> 13; h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff; h1 ^= h1 >>> 16; return h1 >>> 0; } exports.createUniqueIdentifier = createUniqueIdentifier; exports.getCanvasFingerprint = getCanvasFingerprint; exports.getUCID = getUCID; exports.getUUID = getUUID; exports.murmurhash3_32_gc = murmurhash3_32_gc; exports.setKeyPrefix = setKeyPrefix; exports.setUCID = setUCID; exports.setUUID = setUUID;