-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add short and URL friendly string representation to System.Guid
#55290
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsBackground and MotivationThe shortest form of a string representation of
It would be worthwhile to add support for a new format specifier, perhaps Proposed APIThe following changes will be required:
Usage Examplesvar str = Guid.NewGuid().ToString("U");
Console.WriteLine(str); // prints out something like: "abcdefgh123" Alternative DesignsWe could also add extension methods. RisksAll I can think of is that Notes
|
Your sample has the comment prints out something like: "abcdefgh123". Can you give a concrete example of the type of output you expect? For example, what would be the exact output of |
I think you won't be able to do much better than base64-encoding the bytes of the GUID. If you do that, you'll get a 24 character string (22 if you remove padding). And since you can already easily do that today (e.g. |
As for Web, Base64Url encoding fits better, there is a nice helper method in ASP.NET Core. |
You got it. Effectively, we want to base64url encode the var guid = Guid.NewGuid();
Span<byte> bytes = stackalloc byte[16];
guid.TryWriteBytes(bytes);
// now convert the bytes to a string using a base64URL encoder...
var result = Base64UrlEncode(bytes); This is messy and given how often we have all seen Thoughts? |
I don't see much appetite for adding a domain-specific method (base64url encoding) directly on the |
@GrabYourPitchforks, totally agree that we might end up with Base45. I would not look at this as a domain specific thing here. The actual problem I am trying to solve right now is to pass shorter correlation id ( In fact, |
That last response kinda provides evidence for my point that this is domain-specific, no? :) The problem as originally stated is that you wanted something appropriate for placement in URLs; but #55290 (comment) shows that you actually want something that's the shortest ASCII computer-readable representation of arbitrary binary data (which doesn't need to be URL-safe); and that making something human-readable and URL-appropriate might require yet another format (like base45). But I'm sympathetic to the problem, but since your desire is for the shortest possible representation and that you're willing to use a non-standard format to accomplish it, what's wrong with defining your own extension method? public static string ToMinimalRepresentation(this Guid guid)
{
Span<byte> asBytes = stackalloc byte[16];
Guid.TryWriteBytes(asBytes);
Span<char> asChars = stackalloc char[22];
Base64UrlEncode(from: asBytes, to: asChars);
return asChars.ToString(); // the one and only allocation
} |
@GrabYourPitchforks, I can certainly do this and in fact have done so. My point is this pattern is pretty common out there. From websites to HTTP headers, to logs, etc. One of the reasons is that frameworks just don't make it available/easy for all devs to use these. Open any of our logs in Kusto/Cosmos and you will be shocked that no-one has taken the time to use a shorter version for a correlation id. Why? Is it because they can't write the code? No. It is because we don't make it easy for them to use an out of the box formatter and they are busy with so many other things. A good framework is there to simplify these types of work. Let me ask you this: Why do we have so many other format specifiers but feel hesitant to add one more that has serious and real use cases? For instance, have you ever seen a Another question: What is the downside of adding this format? I am totally with you that we need to have a high bar for corlib but I believe I have made a good case here with so many use cases. |
If you care about saving every byte of bandwidth, why are you using a globally unique identifier? Wouldn't an identifier that's unique just to your application serve you as well, while being much shorter? On the other hand, I just googled "guid to short string" and it seems to be a relatively common problem (with base64 usually being the suggested solution).
Maybe there was a reason for the other formats when they were first added. Maybe there still is. Or maybe they were a mistake. In any case, I don't that's really a justification to add one more format. |
@svick, still need something globally unique. This is not for a single application. It will potentially be used by all of Azure if I get my way. HTH |
Agree with @GrabYourPitchforks that this seems like a very domain specific API and not something we'd be interested in expose on Given that |
Background and Motivation
The shortest form of a string representation of
System.Guid
is 32 characters long (format = "N"
). Although this is URL friendly, it is not the most concise URL friendly representation of it. From RFC2396 Section 2.3, the URL safe characters are:It would be worthwhile to add support for a new format specifier, perhaps
U
toSystem.Guid
that generates a shorter URL friendly string representation of the guid.Proposed API
The following changes will be required:
System.Guid.Parse(string input)
System.Guid.Parse(ReadOnlySpan<char> input)
System.Guid.ParseExact(string input, string format)
format
is"U"
System.Guid.ParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format)
format
is"U"
System.Guid.TryParse([NotNullWhen(true)] string? input, out Guid result)
System.Guid.TryParse(ReadOnlySpan<char> input, out Guid result)
System.Guid.TryParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format, out Guid result)
format
is"U"
System.Guid.TryParseExact([NotNullWhen(true)] string? input, [NotNullWhen(true)] string? format, out Guid result)
format
is"U"
System.Guid.ToString(string? format)
format
isU
System.Guid.TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default)
Guid
instance into the provided character span in its shorter string form whenformat
is"U"
Usage Examples
Alternative Designs
We could also add extension methods.
Risks
All I can think of is that
TryParse(...)
now requires an extra check on the length of the string to determine if it should try to parse the string as a short representation of the URL.Notes
marks
characters ("-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
) to keep the URLs even more readable.The text was updated successfully, but these errors were encountered: