UUID生成的字符类型是什么?

38
  1. java.util.UUID 生成的是特殊字符吗?
  2. UUID 生成的每个字符都是什么类型(例如:大写字母、小写字母、数字)?
4个回答

76

简述

您问:

java.util.UUID 会生成特殊字符吗?

不会。UUID 实际上是一个 128 位的值,而不是文本。

UUID 的文本表示法通常是由十六进制数字(0-9,a-f,A-F)和连字符组成的字符串。


你的问题是:

UUID生成的每个字符的类型是什么(例如大写字母、小写字母、数字)。

根据UUID规范的要求,表示UUID值的十六进制字符串中的任何a到f字符必须全部为小写字母。但是违规情况很多。

UUID ≠ 文本

需要澄清的是,UUID实际上是128位值,不是文本,也不是数字。

你可以将它们视为128位无符号整数。但它们实际上不是数字,因为某些位位置具有语义和特定含义。哪些位具有哪些含义因variant和UUID的version而异。

十六进制字符串

人类不善于将128位表示为128个1和0字符进行阅读和编写。当需要将UUID写成人可读的形式时,我们使用基于16进制十六进制 (数字0-9和字母a-f)字符串。我们使用32个十六进制字符,用4个连字符分组,共36个字符来表示这128位。例如:

550e8400-e29b-41d4-a716-446655440000

没有 "特殊" 字符

至于问题中提到的 "特殊字符",您只会在UUID的十六进制字符串表示中看到以下23个可能的字符:

abcdefABCDEF1234567890-

规范要求小写字母

最新的国际规范(日期为2008-08)指出(重点标出):

6.5.4 生成UUID十六进制表示的软件不应使用大写字母。注意-建议在所有可读格式中使用的十六进制表示仅限于小写字母。但是,处理此表示的软件需要按照6.5.2规定接受大小写字母。

普遍违规

然而,微软、苹果和其他公司通常违反小写规则。曾经有一段时间,微软发布了一个生成混合大小写(同时使用大写和小写)的软件,显然是一个意外的功能。

所以要按照规范进行操作:

  • 输出使用小写字母。
  • 输入时可以容忍大小写字母。
Java文档中UUID类的toString方法的BNF文档表明,在生成字符串时允许使用大写字母,与UUID标准规范相矛盾。然而,在Java 8的Oracle实现中,该类和其toString方法的实际行为是正确的,输出使用小写字母,但容忍输入的大小写字母。

大小写字母均可输入:

UUID uuidFromLowercase = UUID.fromString ( "897b7f44-1f31-4c95-80cb-bbb43e4dcf05" ); 
UUID uuidFromUppercase = UUID.fromString ( "897B7F44-1F31-4C95-80CB-BBB43E4DCF05" );

仅输出小写:

System.out.println ( "uuidFromLowercase.toString(): " + uuidFromLowercase );
System.out.println ( "uuidFromUppercase.toString(): " + uuidFromUppercase );

uuidFromLowercase.toString(): 897b7f44-1f31-4c95-80cb-bbb43e4dcf05

uuidFromUppercase.toString(): 897b7f44-1f31-4c95-80cb-bbb43e4dcf05

在 IdeOne.com 上查看此 code run live

空值

当 UUID 尚未知道时,可以使用由所有零组成的特殊 UUID。

00000000-0000-0000-0000-000000000000

示例数值

您可以通过使用许多生成值的网站之一来查看一些 UUID 值的示例。例如:

或者使用命令行工具。几乎每个操作系统都附带了这样的工具。在macOS上,启动Terminal.app并输入uuidgen


9

java.util.UUID 的 javadoc 链接到 RFC 4122,其中指出:

  Each field is treated as an integer and has its value printed as a
  zero-filled hexadecimal digit string with the most significant
  digit first.  The hexadecimal values "a" through "f" are output as
  lower case characters and are case insensitive on input.
因此,它不会产生特殊字符。

6

UUID并不是由字符组成的,除非你要求将其转换为字符串。此时,它将被转换为一个由十六进制字符和连字符组成的字符串,UUID.toString()文档中所述

(文档没有说明十六进制数字是大写还是小写。)


生成小写字符 - kommradHomer
@kommradHomer:对于特定的实现可能是正确的,但是不同的实现可以产生大写字符,这仍然是有效的。 - Jon Skeet
非常正确,我只是想提供一个侧面说明,因为问题是关于JAVA的,而你已经链接了JAVA文档,所以我想指出JAVA一直在做什么。 - kommradHomer
@kommradHomer:关键是你说的只是Java的一个实现(顺便提一下,不是JAVA)。 你有检查过所有的实现是否都做了同样的事情吗? - Jon Skeet
1
但你在链接Oracle Java,这就是我注意到的。 - kommradHomer

1
根据 互联网RFC 4122
每个字段都被视为整数,并将其值打印为填充了零的十六进制数字字符串,最高有效位在前。十六进制值“a”到“f”以小写字符输出,并且输入时不区分大小写。
如果您尊重互联网标准,请始终使用小写字母。
虽然BNF定义了大写字母,但仅适用于输入,而非输出。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接