Reputation: 233
I am attempting to emulate the way a C# application converts a UUID to a Base64 value. For some reason, I can get part of the string to match the expected value, but not the whole string.
The C# code I was given:
public static string ToShortGuid(this Guid newGuid) {
string modifiedBase64 = Convert.ToBase64String(newGuid.ToByteArray())
.Replace('+', '-').Replace('/', '_') // avoid invalid URL characters
.Substring(0, 22);
return modifiedBase64;
}
What I have tried in 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" is a known UUID, and the application apparently uses the above c# code to generate a 'ShortGuid' value of "NQUZ-gBrUkSKsTGccwgrYA".
When I process the same UUID through my Python code, I get: "-hkFNWsARFKKsTGccwgrYA=="
From both of these output strings, this part matches: "KsTGccwgrYA", but the rest doesn't.
Upvotes: 3
Views: 4372
Reputation: 85767
NQUZ-gBrUkSKsTGccwgrYA
corresponds to a byte sequence of 350519fa006b52448ab1319c73082b60
.
If we add -
in the appropriate locations, we get:
350519fa-006b-5244-8ab1-319c73082b60
# \/ \/ \/
# /\ /\ /\
fa190535-6b00-4452-8ab1-319c73082b60
Compared to the known UUID you started with, the bytes are the same, but the order within the first 3 subgroups is reversed.
To emulate what .NET does, you need to use UUID.bytes_le:
The UUID as a 16-byte string (with time_low, time_mid, and time_hi_version in little-endian byte order).
See also Why does Guid.ToByteArray() order the bytes the way it does?
Upvotes: 8
Reputation: 249293
You need to use bytes_le
to get the endianness to match Microsoft's:
base64.urlsafe_b64encode(uuid.UUID("fa190535-6b00-4452-8ab1-319c73082b60").bytes_le)
That gives b'NQUZ-gBrUkSKsTGccwgrYA=='
.
Upvotes: 6