> 文章列表 > UUID无处不在,你就是唯一(2023.4.16)

UUID无处不在,你就是唯一(2023.4.16)

UUID无处不在,你就是唯一(2023.4.16)

六种语言生成UUID 2023.4.16

  • 引言
  • 1、UUID简介
  • 2、UUID格式和编码
  • 3、UUID各历史版本
  • 4、UUID代码具体调用实现
    • 4.1 C# 生成UUID
    • 4.2 Java 生成UUID
    • 4.3 Python 生成UUID
    • 4.4 C++ 生成UUID
    • 4.5 C 生成UUID
    • 4.6 JavaScript 生成UUID(较为实用)
      • 4.6.1 控制台运行(浏览器)
      • 4.6.2 控制台运行(Node TestUUID.js)
  • 5、总结

引言

        全球数字化浪潮滚滚而来,各行各业无时无刻不在与数字打交道,万事万物或被牵扯和囊括其中。数字(Digit or number)作为一种简单快速的识别代码,深受开发者和广大用户的喜爱,在以下诸如此类的众多场景中被广泛使用:
(1)各个国家居民身份的唯一标识ID Card
(2)全世界生产的所有电脑,每台电脑都有着唯一的序列号硬件MAC地址
(3)各大手机厂商为用户分配的识别号,如(苹果手机AppID、华为手机HUAWEI_id
(4)全球通信运营商为用户分配的移动号码8614879421684
(5)互联网为政府机构、大学校园教育、企业单位、个人用户都分配了唯一的IP地址,从广域网(WAN)到局域网(LAN),从IPv4IPv6,公网环境下寄托在域名服务器DNS中的域名地址
(6)银行等业务部门为客户办理的业务单号、账单流水、卡号
(7) 世界上所有英文期刊发表的论文的唯一标识,如(DOI)。

        假如存在这样一个问题→从全球数十亿人口中寻找满足特定条件的某一个人,那么我们该如何去做这件事情呢

        思路一:世界本无序,但人们可以定义规则生成秩序,对几十亿人口按照阿拉伯数字编号并排序,寻找某个人就相当于获取该人物的编号,但是数字的存储位数显著增加会给计算机存储带来巨大挑战,因为人处于社会当中,伴随复杂多样的关系,导致属性关联、各异,海量信息无法仅仅依赖于数字;

        思路二:为所有人口分配互不重复且唯一的识别码,这个识别码可以是数字、字母、符号以及它们的组合体,但需要统一管理。

        思路三:结合思路一和思路二,考虑归纳分组、分门别类的思想,采取分而治之,从国家到地区、城市、县、乡、村,正如域名分配一样,从顶级、中级到低级一样,采用分层分级的思路实现,便于提高处理效率,缩短计算时间

        前两种思路无形中都与数据库密切相关,数据库的规模可大可小,查询检索速度可快可慢,主要取决于查询条件和数据量的大小第三种思路正如金字塔、树等结构,自上而下,分门别类,扩展延伸,分层分级,较为灵活,当然比较符合现代科学技术的发展、计算机的存储方式、数据库设计模式等理念。当然大家如果有好的想法,欢迎在评论区各抒己见,畅所欲言呀!✨✨✨

1、UUID简介

        UUID的全称为(Universally Unique Identifier通用唯一标识符,它出现的目的是让分布式系统中出现的一切元素都具有唯一的辨识,而不需要根据中央控制端来指定辨识资格,即出生便具有独特性、唯一性和有效性。下图为Github上的uuid,已然收获了13k+的star数量,足见其深受广大开发者和工程师的喜爱。

UUID无处不在,你就是唯一(2023.4.16)

2、UUID格式和编码

UUID无处不在,你就是唯一(2023.4.16)

3、UUID各历史版本

        如果想要进一步了解UUID是如何生成的,可以参考UUID标准和维基百科上的UUID介绍。UUID具有多个版本且各个版本具有不同的算法和应用范围,分别为基于时间的UUID、DCE安全的UUID、基于名字的UUID(MD5)、随机UUID和基于名字的UUID(SHA1)。总的来说,各个版本的发展都是为了保证唯一性、尽可能避免冲突同时提高生成效率,基本是与时间、MAC地址、域名、URL相关或随机生成。

Version 1 UUIDs are generated from a time and a node id (usually the MAC address);version 2 UUIDs are generated from an identifier (usually a group or user id), time, and a node id;versions 3 and 5 produce deterministic UUIDs generated by hashing a namespace identifier and name;and version 4 UUIDs are generated using a random or pseudo-random number.

UUID无处不在,你就是唯一(2023.4.16)

4、UUID代码具体调用实现

        下面就到了激动人心的环节,读完卷书,不如行万里路,让我们来亲自动手实践一下,以C#、Java、Python、C++、C和JavaScript这六种语言代码体验一下通用唯一标识符的生成和调用方法吧。

4.1 C# 生成UUID

        具体需要参考Microsoft-C#官方API文档中的Guid,使用Guid来生成UUID也是一种不错的方法哦。

UUID无处不在,你就是唯一(2023.4.16)
        TestUUID.cs文件代码内容如下:

using System;namespace UUIDCSharp
{class TestUUID{static void Main(string[] args){for(int i=0;i<10;i++){string uuid = Convert.ToString(Guid.NewGuid());Console.WriteLine("第"+i.ToString()+"个 UUID is: " + uuid);}}}
}

        运行结果截图如下:
UUID无处不在,你就是唯一(2023.4.16)

4.2 Java 生成UUID

        具体参考Oracle-Java官方API文档中的UUID,介绍了四种版本的UUID;再者还可参考h2数据库网站上的UUID描述,利用其提供的样例源码来估计和理解两个UUID重复的概率。

UUID无处不在,你就是唯一(2023.4.16)

UUID无处不在,你就是唯一(2023.4.16)

        TestUUID.java文件内容代码如下:

package com;
import java.util.UUID;public class TestUUID {public static String getTwoUUIDRepeatProbability(int i){String res = null;double x = Math.pow(2, 122);double n = Math.pow(2, i);double p = 1 - Math.exp(-(n * n) / 2 / x);res = ("2^" + i + "=" + (1L << i) + " probability: 0" + String.valueOf(1 + p).substring(1));return res;}public static void main(String[] args){/** 直接利用java.util.UUID类直接获取UUID字符串 */for(int i=0;i<10;i++)System.out.println("第"+i+"个 UUID:"+UUID.randomUUID().toString());
//		for(int i=35;i<62;i++)
//			System.out.println(getTwoUUIDRepeatProbability(i));}
}

        运行结果截图如下:

UUID无处不在,你就是唯一(2023.4.16)

4.3 Python 生成UUID

UUID无处不在,你就是唯一(2023.4.16)

        具体参考Python-uuid官网API文档,通过导入uuid模块就可以使用它的四个方法了。注意这四个方法依次是uuid1(),uuid3(),uuid4(),uuid5(),然而并没有uuid2()。在某个文件目录下用Notepad新建test-uuid.py文件,并输入如下代码后打开控制台执行命令:python test-uuid.py

        test-uuid.py文件内容代码如下:

# -*- coding:utf-8 -*-
import uuid
print(uuid.uuid1())
print(uuid.uuid3(uuid.NAMESPACE_DNS, 'jing_zhong'))
print(uuid.uuid4())
print(uuid.uuid5(uuid.NAMESPACE_DNS, 'jing_zhong'))

        命令行和Python自带的IDLE运行结果如下所示:
UUID无处不在,你就是唯一(2023.4.16)
在这里插入图片描述
        下面利用PyCharm新建项目和TestUUID.py文件,编译运行测试,TestUUID.py文件内容代码如下:

# -*- coding:utf-8 -*-
import uuiddef getUUID1():return str(uuid.uuid1())def getUUID3(name):return str(uuid.uuid3(uuid.NAMESPACE_DNS, name))def getUUID4():return str(uuid.uuid4())def getUUID5(name):return str(uuid.uuid5(uuid.NAMESPACE_DNS, name))if __name__ == '__main__':n = 10for i in range(0,n):print("第" + str(i+1) + "个uuid1:" + getUUID1())print("第" + str(i+1) + "个uuid3:" + getUUID3("jing_zhong"))print("第" + str(i+1) + "个uuid4:" + getUUID4())print("第" + str(i+1) + "个uuid5:" + getUUID5("jing_zhong"))

        运行结果截图如下:
UUID无处不在,你就是唯一(2023.4.16)

4.4 C++ 生成UUID

UUID无处不在,你就是唯一(2023.4.16)

        这里依赖C++的Boost库来生成UUID,到官网下载编译后的Boost库或根据官方文档自己编译源码均可,之后用VS 2015新建C++项目头文件和库文件目录引入即可,然后新建TestUUID.cpp文件,输入如下代码后编译生成即可。

        TestUUID.cpp文件内容代码如下:

#include <iostream>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>using namespace std;
using namespace boost;string getUUID()
{boost::uuids::uuid a_uuid = boost::uuids::random_generator()();string uuid_string = boost::uuids::to_string(a_uuid);return uuid_string;
}int main()
{std::cout << "-----------------------C++ 使用boost库生成UUID------------------------" << std::endl;for (int i = 0; i < 10; i++)std::cout << "第"<< (i+1) <<"个UUID:" << getUUID() << std::endl;return 0;
}

        运行结果截图如下:
UUID无处不在,你就是唯一(2023.4.16)

4.5 C 生成UUID

        至于用C语言代码生成UUID,大家可能使用更多的是在linux系统上的libuuid库,当然也推荐大家学习Github-stduuid库,尝试在Windows系统下用VS编译即可使用。有兴趣的伙伴可以多阅读StackOverflow上的generating-a-random-uuid-in-c话题讨论,或许会有启发。

        TestUUID-linux-libuuid.c文件内容代码如下(linux下安装libuuid库后调用):

#include <stdlib.h>
#include <stdio.h>
#include <uuid.h>int main(void) {uuid_t binuuid;uuid_generate_random(binuuid);char *uuid = malloc(37);#ifdef capitaluuiduuid_unparse_upper(binuuid, uuid);#elif lowercaseuuiduuid_unparse_lower(binuuid, uuid);#elseuuid_unparse(binuuid, uuid);#endifputs(uuid); // Equivalent of printf("%s\\n", uuid); - just my personal preferencereturn 0;
}//#include <stdio.h>
//#include <uuid/uuid.h>
//
 gcc uuid.c -luuid -o uuid
//
//int main()
//{
//	int i, n;
//	uuid_t uu[4];
//	char buf[1024];
//	struct timeval tv;
//	//1、
//	uuid_generate(uu[0]);
//	//2、
//	uuid_generate_random(uu[1]);
//	//3、
//	uuid_generate_time(uu[2]);
//	//4、
//	n = uuid_generate_time_safe(uu[3]);
//	printf("n = %d\\n", n);
//	for (i = 0; i<4; ++i) {
//		uuid_unparse(uu[i], buf);
//		printf("uu[%d]\\t\\t%s\\n", i, buf);
//	}
//
//	uuid_time(uu[2], &tv);
//	printf("tv s:%lx  u:%lx\\n", tv.tv_sec, tv.tv_usec);
//
//
//	return 0;
//}

        此外,自己动手编写一个利用随机数生成UUID的函数代码,放到TestUUID.c中,利用VS 2015新建项目后编译运行。

        TestUUID.c文件内容代码如下:

#include <stdio.h>
#include <stdlib.h>char* gen_uuid() //3fb17ebc-bc38-4939-bc8b-74f2443281d4
{char v[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };static char buf[37] = { 0 };for (int i = 0; i < 37; ++i){if (i == 8 || i == 13 || i == 18 || i == 23)buf[i] = '-'; //put dashes in place 8 dash 4 dash 4 dash 4 dash 12else if(i != 36)buf[i] = v[rand() % 16]; //gen random for all spaces because lazyelsebuf[36] = '\\0'; //needs end byte}return buf;
}void printChars(char *s)
{for (int i = 0; i <= 36; ++i){if(i !=36)printf("%c", *(s++));elseprintf("\\n");}
}int main()
{puts("----------------C语言代码生成UUID-----------------");for (int i = 0; i < 10; i++){char *s = gen_uuid();printf("第%d个UUID:", i + 1);printChars(s);}system("pause");return 0;
}

        运行结果截图如下:
UUID无处不在,你就是唯一(2023.4.16)

4.6 JavaScript 生成UUID(较为实用)

        在前端JavaScript代码面前,生成UUID早已成为老生常谈的话题,有兴趣的朋友可以参考StackOverflow上的两个讨论话题:how-to-create-a-guid-uuid-in-javascript和collisions-when-generating-uuids-in-javascript,个人觉得该话题早已引起了广泛而又激烈的讨论,大家的思路和想法都十分活跃和积极,下面的代码是自己认为较为精华的部分:

4.6.1 控制台运行(浏览器)

{function createGuid1() {return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {var r = (Math.random() * 16) | 0;var v = c === "x" ? r : (r & 0x3) | 0x8;return v.toString(16);});}function createuuid2() {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);});}console.log('-------------------使用第一种方法生成UUID---------------------');for(let i=0;i<10;i++)console.log('第'+(i+1)+'个UUID:',createGuid1())console.log('-------------------使用第二种方法生成UUID---------------------');for(let i=0;i<10;i++)console.log('第'+(i+1)+'个UUID:',createuuid2())
}

        浏览器中按F12进入开发者控制台Console窗口中,将以上代码粘贴其中后按回车键,即可看到运行结果:
UUID无处不在,你就是唯一(2023.4.16)

4.6.2 控制台运行(Node TestUUID.js)

UUID无处不在,你就是唯一(2023.4.16)

        除了在浏览器内运行js外,可能大多数开发者更喜欢在命令行终端窗口中测试运行。这里假设大家在电脑上已经安装好了Node.js环境,且已经配置好了npm包管理器,那么可以全局或者在某文件目录下局部安装uuid依赖库进行测试学习,下面我以本地E:\\jing_zhong\\TestNodeUUID文件目录下测试运行js代码进行说明。

        第一步,Win+R打开cmd命令行窗口,依次输入如下两行命令在查看安装的node版本号npm版本号,确保前提环境安装成功。

node -v
npm -v

UUID无处不在,你就是唯一(2023.4.16)

        第二步,用Notepad或其他IDE新建package.json文件和TestUUID.js文件,并将下述内容粘贴到其中;

        package.json文件(utf-8编码)内容如下:

{"name": "test-node-uuid","version": "1.0.0","description": "test javascript uuid","main": "TestUUID.js","scripts": {"testuuid": "node TestUUID"},"type": "cjs","keywords": ["uuid","js"],"author": "jing_zhong","license": "MIT","dependencies": {"uuid": "^9.0.0"}
}

在这里插入图片描述

        TestUUID.js文件内容代码如下:

function createGuid1() {return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {var r = (Math.random() * 16) | 0;var v = c === "x" ? r : (r & 0x3) | 0x8;return v.toString(16);});
}function createuuid2() {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);});
}console.log('-------------------使用第一种方法生成UUID---------------------');
for(let i=0;i<10;i++)console.log('第'+(i+1)+'个UUID:',createGuid1())
console.log('-------------------使用第二种方法生成UUID---------------------');
for(let i=0;i<10;i++)console.log('第'+(i+1)+'个UUID:',createuuid2())console.log('-------------------使用第三种方法生成UUID(uuid库)---------------------');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var uuidv1 = (0, _interopRequireDefault(require("./node_modules/uuid/dist/v1.js")).default);
var uuidv3 = (0, _interopRequireDefault(require("./node_modules/uuid/dist/v3.js")).default);
var uuidv4 = (0, _interopRequireDefault(require("./node_modules/uuid/dist/v4.js")).default);
var uuidv5 = (0, _interopRequireDefault(require("./node_modules/uuid/dist/v5.js")).default);
for(let i=0;i<10;i++)console.log('第'+(i+1)+'个UUID:',uuidv1(),'  ', uuidv4())//console.log(uuidv3('6ba7b810-9dad-11d1-80b4-00c04fd430c8','6ba7b810-9dad-11d1-80b4-00c04fd430c8'));
//console.log(uuidv4());
//console.log(uuidv5('6ba7b810-9dad-11d1-80b4-00c04fd430c8','6ba7b810-9dad-11d1-80b4-00c04fd430c8'));

UUID无处不在,你就是唯一(2023.4.16)

        第三步,在命令行窗口中输入命令进入TestNodeUUID目录,安装uuid库后执行TestUUID.js代码,得到运行结果。

cd E:\\jing_zhong\\TestNodeUUID
E:
npm install
node TestUUID.js

在这里插入图片描述

5、总结

        世界上没有两片完全相同的叶子。作为身份的唯一标识码UUID在许多行业和实际的应用场景中都有独特的唯一性要求,众多软件应用和硬件厂商早已考虑到这一点。人间各地烟火不同,繁花各异(樱花、梅花、海棠花、菊花、茉莉花、桃花),此时此刻,不由得回忆起《爱莲说》中的予独爱莲之出淤泥而不染,濯清涟而不妖,中通外直,不蔓不枝,香远益清,亭亭净植,可远观而不可亵玩焉!!!

        愿自己始终能够保持一颗纯净而沉着的心灵,不被外事外物束缚、干扰,脚踏实地,诚心诚意,实事求是,追求真理,不遗余力,在自己热爱的技术领域深耕探索,以绵薄之力分享些许技术心得,体会学海遨游的乐趣,感叹知识海洋的无线广阔,慢慢成长,积极学习

人生充满未知和挑战,勇敢者从未停止脚步。寒门学子,漂泊在外,漆黑的夜晚时常独自思考自己的人生应该如何度过,回想自己还有哪些不足和遗憾 ?尽管久久无法找到答案,但灵机一动发现,除了从书中寻找答案,还可以用心感受社会的变迁、气候的变化、工作的不易和生活的艰辛,可怜天下父母心,母亲身上那种时不我待、只争朝夕的坚强品格,乐观向上的豁达心态令我敬佩不已;父亲身上那种刚强勇毅、不屈不挠、坚韧执著的恒心和毅力更能成为我前进道路上的明灯。愿自己活到老,学到老,还有三分没学到,回首往事之时尽是历历在目的美好回忆。

        ❤️❤️❤️亲爱的孟营,世界之大,有幸相识,时光匆匆,感恩曾经,纵有不舍,心有所往,愿你早遇佳人,幸福一生

        最后,谨以此文与诸君共勉之,孤独寂寞的日子里还是会偷偷地思念家人、默默期待着未来的那个她

人的一生应当这样度过,当他回首往事的时候,不因虚度年华而悔恨,更不因碌碌无为而羞愧。多少人曾爱慕你年轻时的容颜,可知谁愿承受岁月无情的变迁。