在Go中以短字符串形式输出UUID
是否有内置方式或合理的标准软件包,可让您将标准UUID转换为短字符串,从而启用较短的URL?
即利用了较大范围的字符,例如[A-Za-z0-9]
输出较短的字符串。
我知道我们可以使用base64对字节进行编码,如下所示,但是我正在创建一个看起来像“单词”的字符串,即no +
和/
:
id = base64.StdEncoding.EncodeToString(myUuid.Bytes())
回答:
甲通用唯一标识符(UUID)是一个128位的值,它是16个字节。对于人类可读的显示,许多系统使用规范格式,该规范格式使用带有插入的连字符的十六进制文本,例如:
123e4567-e89b-12d3-a456-426655440000
这有长度16*2 + 4 = 36
。您可以选择省略为您提供的连字符:
fmt.Printf("%x\n", uuid)fmt.Println(hex.EncodeToString(uuid))
// Output: 32 chars
123e4567e89b12d3a456426655440000
123e4567e89b12d3a456426655440000
您可以选择使用base32编码(与使用1个符号编码4位的十六进制编码相反):
fmt.Println(base32.StdEncoding.EncodeToString(uuid))// Output: 26 chars
CI7EKZ7ITMJNHJCWIJTFKRAAAA======
=
传输时修剪尾随标志,因此始终为26个字符。请注意,您必须先附加,"======"
然后才能使用解码字符串base32.StdEncoding.DecodeString()
。
如果这对于您来说仍然太长,则可以使用base64编码(使用1个符号对6位进行编码):
fmt.Println(base64.RawURLEncoding.EncodeToString(uuid))// Output: 22 chars
Ej5FZ-ibEtOkVkJmVUQAAA
请注意,base64.RawURLEncoding
生成的base64字符串(不带填充)可安全地包含在URL中,因为符号表中的2个额外字符(位于之外[0-9a-zA-Z]
)为-
和_
,两个都可以安全地包含在URL中。
对于您来说很不幸,base64字符串除之外可能还包含2个额外的字符[0-9a-zA-Z]
。继续阅读。
解释的转义字符串
如果您对这两个额外的字符不熟悉,则可以选择将base64字符串转换为类似于Go中的解释后字符串文字的 解释后转义字符串
。例如,如果要在解释的字符串文字中插入反斜杠,则必须将其加倍,因为反斜杠是表示序列的特殊字符,例如:
fmt.Println("One backspace: \\") // Output: "One backspace: \"
我们可以选择做类似的事情。我们必须指定一个特殊字符:顺其自然9
。
base64.RawURLEncoding
使用字符集:A..Za..z0..9-_
,因此9
代表带有字母数字字符的最高代码(61个十进制=
111101b)。请参见下面的优势。
因此,只要base64字符串包含a9
,就将其替换为99
。每当base64字符串包含多余的字符时,请使用 序列 代替它们:
9 => 99- => 90
_ => 91
这是一个简单的替换表,可以通过以下值捕获strings.Replacer
:
var escaper = strings.NewReplacer("9", "99", "-", "90", "_", "91")
并使用它:
fmt.Println(escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid)))// Output:
Ej5FZ90ibEtOkVkJmVUQAAA
这会稍微增加长度,因为有时会使用2个字符而不是1个字符,但是这样做的好处是,[0-9a-zA-Z]
您可以根据需要仅使用字符。的 平均
长度将小于1的附加字符:23
字符。 公平交易。
为简单起见,我们假设所有可能的uuid都具有相同的概率(uuid并非完全随机,因此不是这种情况,但我们将其放在一边,因为这只是一种估计)。最后一个base64符号将永远不会是可替换字符(这就是为什么我们选择特殊字符9
代替like的原因A
),21个字符可能会变成可替换序列。一个可替换的机会:3/64
= 0.047,因此平均而言,这意味着21 * 3/64 = 0.98个序列,这些序列将1个字符转换为2个字符,因此,这等于附加字符的数量。
要进行解码,请使用以下捕获的逆解码表strings.Replacer
:
var unescaper = strings.NewReplacer("99", "9", "90", "-", "91", "_")
解码转义的base64字符串的示例代码:
fmt.Println("Verify decoding:")s := escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid))
dec, err := base64.RawURLEncoding.DecodeString(unescaper.Replace(s))
fmt.Printf("%x, %v\n", dec, err)
输出:
123e4567e89b12d3a456426655440000, <nil>
在Go Playground上尝试所有示例。
以上是 在Go中以短字符串形式输出UUID 的全部内容, 来源链接: utcz.com/qa/432714.html