首页 文章

如何在C#中实现Base64 URL安全编码?

提问于
浏览
73

我想在C#中实现Base64 URL安全编码 . 在Java中,我们有一个通用的 Codec 库,它为我提供了一个URL安全编码字符串 . 如何使用C#实现相同的目标?

byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);

上面的代码将它转换为Base64,但它填充 == . 有没有办法实现URL安全编码?

7 回答

  • 0

    使用System.Web.HttpServerUtility.UrlTokenEncode(bytes)进行编码,并使用System.Web.HttpServerUtility.UrlTokenDecode(bytes)进行解码 .

  • 6

    通常只需交换字母表以便在网址中使用,这样就不需要%编码; 65个字符中只有3个有问题 - +/= . 最常见的替代品是 - 代替 +_ 代替 / . 至于填充:只需删除它( = );你可以推断出所需的填充量 . 在另一端:只需逆转过程:

    string returnValue = System.Convert.ToBase64String(toEncodeAsBytes)
            .TrimEnd(padding).Replace('+', '-').Replace('/', '_');
    

    有:

    static readonly char[] padding = { '=' };
    

    并扭转:

    string incoming = returnValue
        .Replace('_', '/').Replace('-', '+');
    switch(returnValue.Length % 4) {
        case 2: incoming += "=="; break;
        case 3: incoming += "="; break;
    }
    byte[] bytes = Convert.FromBase64String(incoming);
    string originalText = Encoding.ASCII.GetString(bytes);
    

    然而,有趣的问题是:这与"common codec library"使用的方法相同吗?测试肯定是合理的第一件事 - 这是一种非常常见的方法 .

  • 7

    您可以使用命名空间 Microsoft.IdentityModel.Tokens 中的类 Base64UrlEncoder .

    const string StringToEncode = "He=llo+Wo/rld";
    
    var encodedStr = Base64UrlEncoder.Encode(StringToEncode);
    var decodedStr = Base64UrlEncoder.Decode(encodedStr);
    
    if (decodedStr == StringToEncode)
        Console.WriteLine("It works!");
    else
        Console.WriteLine("Dangit!");
    
  • 133

    基于这里的答案和一些性能改进,我们发布了一个非常容易使用的url-safe base64 implementation to NuGet源代码available on GitHub(MIT许可) .

    用法很简单

    var bytes = Encoding.UTF8.GetBytes("Foo");
    var encoded = UrlBase64.Encode(bytes);
    var decoded = UrlBase64.Decode(encoded);
    
  • 3

    如果您使用的是ASP.NET Core,则另一个选项是使用Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode .

    如果您不使用ASP.NET Core,the WebEncoders source可在Apache 2.0 License下找到 .

  • 0

    这是解码url-safe base64的另一种方法,用与Marc相同的方式进行编码 . 我只是不明白为什么 4-length%4 工作(确实如此) .

    如下所示,只有原点的位长是6和8的公倍数,base64不会在结果中附加“=” .

    1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8 
    1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6
                    "=="            "="
    

    所以我们可以相反地做,如果结果的位长度不能被8整除,则附加:

    base64String = base64String.Replace("-", "+").Replace("_", "/");
    var base64 = Encoding.ASCII.GetBytes(base64String);
    var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2
    if (padding != 0)
    {
        base64String = base64String.PadRight(base64String.Length + padding, '=');
    }
    return Convert.FromBase64String(base64String);
    
  • 50

    在UWP中使用Microsoft加密引擎 .

    uint length = 32;
    
    IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
    string base64Str = CryptographicBuffer.EncodeToBase64String(buffer)
                       // ensure url safe
                       .TrimEnd('=').Replace('+', '-').Replace('/', '_');
    
    return base64Str;
    

相关问题