如何在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)); }