关于c#:引导到base64,用于URL

guid to base64, for URL

问题:有更好的方法吗?

VB.Net

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
}


您可能想查看以下站点:http://prettycode.org/2009/11/12/short-guid/

它看起来非常接近您的工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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;
    }
}

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

1
2
3
4
    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

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


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

除了已经提到的@Skurmedal问题(如果输入的字符串无效,应该抛出异常),我认为您发布的代码就足够了。


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