How to achieve Base64 URL safe encoding in C#?
我想在C中实现base64 URL安全编码。在Java中,我们有一个通用的EDCOX1×0库,它提供了一个URL安全编码的字符串。如何使用c_实现相同的效果?
1 2 | byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode"); string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); |
上面的代码将其转换为base64,但它会填充
简单地交换字母以在URL中使用是很常见的,因此不需要%编码;65个字符中只有3个有问题-
1 2 | string returnValue = System.Convert.ToBase64String(toEncodeAsBytes) .TrimEnd(padding).Replace('+', '-').Replace('/', '_'); |
用:
1 | static readonly char[] padding = { '=' }; |
并扭转:
1 2 3 4 5 6 7 8 | 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); |
然而,有趣的问题是:这是"公共编解码器库"使用的相同方法吗?这当然是一个合理的第一件事来测试-这是一个相当常见的方法。
可以使用命名空间
1 2 3 4 5 6 7 8 9 | 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!"); |
基于这里的答案和一些性能改进,我们发布了一个非常容易使用的URL安全base64实现来nuget,其源代码在GitHub(MIT许可)上可用。
使用起来就像
1 2 3 | var bytes = Encoding.UTF8.GetBytes("Foo"); var encoded = UrlBase64.Encode(bytes); var decoded = UrlBase64.Decode(encoded); |
使用system.web.httpserverputility.urltokenencode(bytes)进行编码,以及要解码的system.web.httpserverputility.urltokendecode(字节)。
另一种选择是,如果您使用的是ASP.NET内核,则使用
如果您不使用ASP.NET核心,则可以在Apache2.0许可证下使用
在UWP中使用Microsoft加密引擎。
1 2 3 4 5 6 7 8 | uint length = 32; IBuffer buffer = CryptographicBuffer.GenerateRandom(length); string base64Str = CryptographicBuffer.EncodeToBase64String(buffer) // ensure url safe .TrimEnd('=').Replace('+', '-').Replace('/', '_'); return base64Str; |
这是另一种解码URL安全base64的方法,与marc的编码方法相同。我就是不明白为什么
如下所示,只有原点的位长度是6和8的公共倍数,base64不向结果附加"="。
1 2 3 | 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整除,那么它已经被附加:
1 2 3 4 5 6 7 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); |