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

我想在C#中实现Base64 URL安全编码。 在Java中,我们有通用的Codec库,它给了我一个URL安全编码的string。 我如何使用C#实现相同?

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

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

通常简单地将字母表换成在url中使用,这样就不需要%-encoding; 65个字符中只有3个是有问题的 – +/= 。 最常见的replace是-replace+_来代替/ 。 至于填充: 只是删除它= ); 你可以推断所需的填充量。 在另一端:只是扭转过程:

 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); 

然而有趣的问题是: 这是“通用编解码器库”使用的方法吗? 这当然是一个合理的首要考验 – 这是一个相当普遍的做法。

您可以使用名称空间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!"); 

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

基于这里的一些性能改进的答案,我们已经发布了一个非常容易使用的url安全base64实现NuGet与GitHub (麻省理工学院许可) 上提供的源代码。

用法和一样简单

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

这里是另一种解码url安全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); 

这里有很多好的答案。 摆脱+,/和=很容易在String.Replace上的每个string,但我通常有一个帮助类,在我的大部分项目中删除特殊字符。

  public static class Helpers { public static string RemoveSpecialCharacters(string str) { return Regex.Replace(str, "[^a-zA-Z0-9]", "", RegexOptions.Compiled); } } 

我用这个来帮助我创build一个令牌。

 using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { byte[] data = new byte[ByteLength]; rng.GetBytes(data); return Helpers.RemoveSpecialCharacters(Convert.ToBase64String(data)); }