咨询区
Vishvesh Phadnis:
在 C# 中如何实现对 URL 进行安全的 base64 编码,在 JAVA 中我可以使用 Codec
类库来实现此功能,我目前是这么实现的。
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
但上面这样做,会有 ==
字符,这样会被当作url参数处理的,请问是否有更好的方式处理。
回答区
Kevinoid:
如果你用的是 ASP.NET Core
,你可以使用 Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode
类,参考如下代码:
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!");
如果你的程序非 ASP.NET Core
的话, 可以使用 WebEncoders
。
public static byte[] Base64UrlDecode(string input, int offset, char[] buffer, int bufferOffset, int count)
{
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
ValidateParameters(input.Length, nameof(input), offset, count);
if (bufferOffset < 0)
{
throw new ArgumentOutOfRangeException(nameof(bufferOffset));
}
if (count == 0)
{
return Array.Empty<byte>();
}
// Assumption: input is base64url encoded without padding and contains no whitespace.
var paddingCharsToAdd = GetNumBase64PaddingCharsToAddForDecode(count);
var arraySizeRequired = checked(count + paddingCharsToAdd);
Debug.Assert(arraySizeRequired % 4 == 0, "Invariant: Array length must be a multiple of 4.");
if (buffer.Length - bufferOffset < arraySizeRequired)
{
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
EncoderResources.WebEncoders_InvalidCountOffsetOrLength,
nameof(count),
nameof(bufferOffset),
nameof(input)),
nameof(count));
}
// Copy input into buffer, fixing up '-' -> '+' and '_' -> '/'.
var i = bufferOffset;
for (var j = offset; i - bufferOffset < count; i++, j++)
{
var ch = input[j];
if (ch == '-')
{
buffer[i] = '+';
}
else if (ch == '_')
{
buffer[i] = '/';
}
else
{
buffer[i] = ch;
}
}
// Add the padding characters back.
for (; paddingCharsToAdd > 0; i++, paddingCharsToAdd--)
{
buffer[i] = '=';
}
// Decode.
// If the caller provided invalid base64 chars, they'll be caught here.
return Convert.FromBase64CharArray(buffer, bufferOffset, arraySizeRequired);
}
详细内容可以参见 github:https://github.com/dotnet/aspnetcore/blob/main/src/Shared/WebEncoders/WebEncoders.cs
当然,你如果不嫌麻烦,可以手工处理。
public string Decode(string str)
{
byte[] decbuff = Convert.FromBase64String(str.Replace(",", "=").Replace("-", "+").Replace("/", "_"));
return System.Text.Encoding.UTF8.GetString(decbuff);
}
public string Encode(string input)
{
byte[] encbuff = Encoding.UTF8.GetBytes(input ?? "");
return Convert.ToBase64String(encbuff).Replace("=", ",").Replace("+", "-").Replace("_", "/");
}
点评区
这个问题相信很多朋友都遇到过,导致 url 中的 base64 的一部分当成了参数处理,后来没办法只能将需要 base64 的参数放到了 post body 中,现在终于知道怎么解决了。