本文介绍如何在没有后端支持的前端环境中,使用原生JavaScript生成全局唯一标识符(GUID)。通过结合系统时间与十六进制随机数模拟生成算法,提供完整的代码实现及使用示例,适用于需要在前端生成唯一ID的场景。
GUID概述与前端生成需求
GUID(全局统一标识符)是一串用于标识设备的数字,旨在确保在同一时空范围内的所有机器中其唯一性。大多数平台都提供了生成GUID的API接口。其生成算法涉及以太网卡地址、纳秒级时间戳、芯片ID码以及大量可能的数字组合。GUID的主要缺点是生成的字符串长度较大。
GUID的标准格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx。
虽然在前端开发中,GUID的应用场景相对有限,但在某些需要插入特定ID并与后台系统对应,或执行其他依赖GUID的操作时,为了方便起见,前端生成GUID仍具有实用价值。
前端GUID生成原理与代码实现
在SQL、Java、C#等后端语言或数据库中,生成GUID通常非常简单。然而,前端环境没有直接生成GUID的方法,因此需要手动编写代码实现。由于标准的GUID生成需要获取以太网卡地址和纳秒级时间等高精度信息,而前端获取这些信息较为困难(如有了解者请分享),我们可以通过模拟方式实现GUID的生成,具体代码如下:
/* * 功能:生成一个GUID码,其中GUID以14个以下的日期时间及18个以上的16进制随机数组成,GUID存在一定的重复概率,但重复概率极低,理论上重复概率为每10ms有1/(16^18),即16的18次方分之1,重复概率低至可忽略不计*/
核心代码解析
function GUID() {
this.date = new Date();
/* 判断是否初始化过,如果初始化过以下代码,则以下代码将不再执行,实际中只执行一次 */
if (typeof this.newGUID != 'function') {
/* 生成GUID码 */
GUID.prototype.newGUID = function() {
this.date = new Date();
var guidStr = '';
sexadecimalDate = this.hexadecimal(this.getGUIDDate(), 16);
sexadecimalTime = this.hexadecimal(this.getGUIDTime(), 16);
for (var i = 0; i < 9; i++) {
guidStr += Math.floor(Math.random()*16).toString(16);
}
guidStr += sexadecimalDate;
guidStr += sexadecimalTime;
while(guidStr.length < 32) {
guidStr += Math.floor(Math.random()*16).toString(16);
}
return this.formatGUID(guidStr);
}
/*
* 功能:获取当前日期的GUID格式,即8位数的日期:19700101
* 返回值:返回GUID日期格式的字条串
*/
GUID.prototype.getGUIDDate = function() {
return this.date.getFullYear() + this.addZero(this.date.getMonth() + 1) + this.addZero(this.date.getDay());
}
/*
* 功能:获取当前时间的GUID格式,即8位数的时间,包括毫秒,毫秒为2位数:12300933
* 返回值:返回GUID日期格式的字条串
*/
GUID.prototype.getGUIDTime = function() {
return this.addZero(this.date.getHours()) + this.addZero(this.date.getMinutes()) + this.addZero(this.date.getSeconds()) + this.addZero( parseInt(this.date.getMilliseconds() / 10 ));
}
/*
* 功能: 为一位数的正整数前面添加0,如果是可以转成非NaN数字的字符串也可以实现
* 参数: 参数表示准备再前面添加0的数字或可以转换成数字的字符串
* 返回值: 如果符合条件,返回添加0后的字条串类型,否则返回自身的字符串
*/
GUID.prototype.addZero = function(num) {
if (Number(num).toString() != 'NaN' && num >= 0 && num < 10) {
return '0' + Math.floor(num);
} else {
return num.toString();
}
}
/*
* 功能:将y进制的数值,转换为x进制的数值
* 参数:第1个参数表示欲转换的数值;第2个参数表示欲转换的进制;第3个参数可选,表示当前的进制数,如不写则为10
* 返回值:返回转换后的字符串
*/
GUID.prototype.hexadecimal = function(num, x, y) {
if (y != undefined) {
return parseInt(num.toString(), y).toString(x);
} else {
return parseInt(num.toString()).toString(x);
}
}
/*
* 功能:格式化32位的字符串为GUID模式的字符串
* 参数:第1个参数表示32位的字符串
* 返回值:标准GUID格式的字符串
*/
GUID.prototype.formatGUID = function(guidStr) {
var str1 = guidStr.slice(0, 8) + '-',
str2 = guidStr.slice(8, 12) + '-',
str3 = guidStr.slice(12, 16) + '-',
str4 = guidStr.slice(16, 20) + '-',
str5 = guidStr.slice(20);
return str1 + str2 + str3 + str4 + str5;
}
}
}
使用方法与示例
GUID 对象
只需将上述代码保存为一个JS文件并在项目中引用即可使用。
接下来,我们只需要
var guid = new GUID();
alert(guid.newGUID());
即可获取生成的GUID码。
该实现原理较为简单,主要采用系统时间与18个以上的十六进制随机数组合,并将系统时间转换为十六进制格式。尽管理论上仍存在重复的可能性,但重复概率极低,在实际应用中可忽略不计。