模拟将编码 UUID 转换为 Base64

3

我正在尝试模拟C#应用程序将UUID转换为Base64值的方式。出于某种原因,我可以让字符串的一部分与预期值匹配,但不是整个字符串。

我收到的C#代码:

public static string ToShortGuid(this Guid newGuid) {
string modifiedBase64 = Convert.ToBase64String(newGuid.ToByteArray())
.Replace('+', '-').Replace('/', '_') // avoid invalid URL characters
.Substring(0, 22);
return modifiedBase64;
}

我在Python 3.6中尝试过:

import uuid
import base64

encode_str = = base64.urlsafe_b64encode(uuid.UUID("fa190535-6b00-4452-8ab1-319c73082b60").bytes)
print(encode_str)

"

"fa190535-6b00-4452-8ab1-319c73082b60"是一个已知的UUID,应用程序显然使用以上C#代码来生成一个'ShortGuid'值为"NQUZ-gBrUkSKsTGccwgrYA"。

当我通过我的Python代码处理相同的UUID时,我得到的结果是:"-hkFNWsARFKKsTGccwgrYA=="

从这两个输出字符串中,这部分匹配:"KsTGccwgrYA",但其余部分不匹配。

"

2
使用urlsafe_b64decode解码NQUZ-gBrUkSKsTGccwgrYA==得到b'5\x05\x19\xfa\x00kRD\x8a\xb11\x9cs\x08+\',但是UUID("fa190535-6b00-4452-8ab1-319c73082b60").bytesb'\xfa\x19\x055k\x00DR\x8a\xb11\x9cs\x08+`'`,两者不同。你确定C#和Python中的UUID是相同的吗? - Aran-Fey
我相当确定的是,“fa190535-6b00-4452-8ab1-319c73082b60”是输入C#函数的起始UUID,而“NQUZ-gBrUkSKsTGccwgrYA”是它返回的值。上面的Python代码只是我尝试从相同的起始值得到相同的返回值,正如你所看到的,Python代码中的字符串部分匹配。 - MidnightThoughtful
1
@melpomene 我不认为那是一个重复的问题。毫无疑问,对于这个问题的回答应该包括一个使生成的UUID相同的解决方案。 - Aran-Fey
同意@Aran-Fey的观点-链接的内容对问题有帮助,但我不认为它是重复的。 - MidnightThoughtful
2个回答

8

NQUZ-gBrUkSKsTGccwgrYA 对应的字节序列为 350519fa006b52448ab1319c73082b60

如果我们在适当的位置添加 -,我们会得到:

 350519fa-006b-5244-8ab1-319c73082b60
#   \/     \/   \/
#   /\     /\   /\
 fa190535-6b00-4452-8ab1-319c73082b60

与您最初使用的已知UUID相比,字节相同,但前三个子组中的顺序被颠倒了。
要模拟.NET的操作,您需要使用UUID.bytes_le

UUID作为16字节字符串(其中time_lowtime_midtime_hi_version按小端字节顺序排列)。

另请参见为什么Guid.ToByteArray()以特定的顺序排序字节?

1
确实!这个字节交换在微软的文档中有记录,网址为https://msdn.microsoft.com/en-us/library/system.guid.tobytearray(v=vs.110).aspx - “请注意,返回的字节数组中字节的顺序与Guid值的字符串表示形式不同。开始的四字节组和接下来的两个双字节组的顺序被颠倒了,而最后的两个双字节组和结尾的六字节组的顺序是相同的。” - John Zwinck
有趣,我该如何在Python中进行更正?(我需要在两个方向上进行操作-从UUID到转换后的值,从转换后的值返回到UUID) - MidnightThoughtful

6

您需要使用bytes_le以使得字节序与Microsoft的一致:

base64.urlsafe_b64encode(uuid.UUID("fa190535-6b00-4452-8ab1-319c73082b60").bytes_le)

这给出了b'NQUZ-gBrUkSKsTGccwgrYA=='


太棒了,谢谢你,这正是我想要的结果! - MidnightThoughtful

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