C# 指向 base64 的指南,用于 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1032376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:35:01  来源:igfitidea点击:

guid to base64, for URL

c#.netvb.netguidbase64

提问by Fredou

Question: is there a better way to do that?

问题:有没有更好的方法来做到这一点?

VB.Net

VB.Net

Function GuidToBase64(ByVal guid As Guid) As String
    Return Convert.ToBase64String(guid.ToByteArray).Replace("/", "-").Replace("+", "_").Replace("=", "")
End Function

Function Base64ToGuid(ByVal base64 As String) As Guid
    Dim guid As Guid
    base64 = base64.Replace("-", "/").Replace("_", "+") & "=="

    Try
        guid = New Guid(Convert.FromBase64String(base64))
    Catch ex As Exception
        Throw New Exception("Bad Base64 conversion to GUID", ex)
    End Try

    Return guid
End Function

C#

C#

public string GuidToBase64(Guid guid)
{
    return Convert.ToBase64String(guid.ToByteArray()).Replace("/", "-").Replace("+", "_").Replace("=", "");
}

public Guid Base64ToGuid(string base64)
{
   Guid guid = default(Guid);
   base64 = base64.Replace("-", "/").Replace("_", "+") + "==";

   try {
       guid = new Guid(Convert.FromBase64String(base64));
   }
   catch (Exception ex) {
       throw new Exception("Bad Base64 conversion to GUID", ex);
   }

   return guid;
}

采纳答案by Hemant

I understand that the reason you are clipping == in the end is that because you can be certain that for GUID (of 16 bytes), encoded string will alwaysend with ==. So 2 characters can be saved in every conversion.

我知道您最终剪裁 == 的原因是因为您可以确定对于 GUID(16 个字节),编码字符串将始终以 == 结尾。所以每次转换可以保存 2 个字符。

Beside the point @Skurmedal already mentioned (should throw an exception in case of invalid string as input), I think the code you posted is just good enough.

除了@Skurmedal 已经提到的点(在输入无效字符串的情况下应该抛出异常)之外,我认为您发布的代码已经足够好了。

回答by Skurmedel

If your method cannot convert the Base64 passed to it to a GUID, shouldn't you throw an exception? The data passed to the method is clearly erronous.

如果您的方法无法将传递给它的 Base64 转换为 GUID,您不应该抛出异常吗?传递给方法的数据显然是错误的。

回答by JamesBrownIsDead

You might want to check out this site: http://prettycode.org/2009/11/12/short-guid/

你可能想看看这个网站:http: //prettycode.org/2009/11/12/short-guid/

It looks very close to what you're doing.

它看起来非常接近你正在做的事情。

public class ShortGuid
{
    private readonly Guid guid;
    private readonly string value;

    /// <summary>Create a 22-character case-sensitive short GUID.</summary>
    public ShortGuid(Guid guid)
    {
        if (guid == null)
        {
            throw new ArgumentNullException("guid");
        }

        this.guid = guid;
        this.value = Convert.ToBase64String(guid.ToByteArray())
            .Substring(0, 22)
            .Replace("/", "_")
            .Replace("+", "-");
    }

    /// <summary>Get the short GUID as a string.</summary>
    public override string ToString()
    {
        return this.value;
    }

    /// <summary>Get the Guid object from which the short GUID was created.</summary>
    public Guid ToGuid()
    {
        return this.guid;
    }

    /// <summary>Get a short GUID as a Guid object.</summary>
    /// <exception cref="System.ArgumentNullException"></exception>
    /// <exception cref="System.FormatException"></exception>
    public static ShortGuid Parse(string shortGuid)
    {
        if (shortGuid == null)
        {
            throw new ArgumentNullException("shortGuid");
        }
        else if (shortGuid.Length != 22)
        {
            throw new FormatException("Input string was not in a correct format.");
        }

        return new ShortGuid(new Guid(Convert.FromBase64String
            (shortGuid.Replace("_", "/").Replace("-", "+") + "==")));
    }

    public static implicit operator String(ShortGuid guid)
    {
        return guid.ToString();
    }

    public static implicit operator Guid(ShortGuid shortGuid)
    {
        return shortGuid.guid;
    }
}

回答by Joe

One problem with using this technique to format a GUID for use in a URL or filename is that two distinct GUIDs can produce two values that differ only in case, e.g.:

使用这种技术来格式化用于 URL 或文件名的 GUID 的一个问题是,两个不同的 GUID 可以产生两个仅在大小写上不同的值,例如:

    var b1 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab83c"));
    var b2 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab8a4"));
    Console.WriteLine(b1);  // 80XQyRzi0EaXHbkuvCq4PA
    Console.WriteLine(b2);  // 80XQyRzi0EaXHbkuvCq4pA

Since URLs are sometimes interpreted as being case-insensitive, and in Windows file paths and filenames are case-insensitive. this could lead to collisions.

由于 URL 有时被解释为不区分大小写,并且在 Windows 中文件路径和文件名不区分大小写。这可能会导致碰撞。