Код для декодирования / кодирования модифицированного URL base64
Я хочу, чтобы base64 кодировал данные, чтобы поместить их в URL, а затем декодировать их в моем HttpHandler.
Я обнаружил, что Base64 Encoding допускает символ '/', который испортит мое соответствие UriTemplate. Затем я обнаружил, что существует понятие "модифицированный Base64 для URL" из Википедии:
Существует модифицированный вариант Base64 для URL, в котором не будет использоваться отступ "=", а символы "+" и "/" в стандартном Base64 соответственно заменяются на "-" и "_", так что с помощью кодировщиков / декодеров URL больше не требуется и не влияет на длину кодированного значения, оставляя ту же самую кодированную форму без изменений для использования в реляционных базах данных, веб-формах и идентификаторах объектов в целом.
Используя.NET, я хочу изменить свой текущий код от базового кодирования и декодирования base64 до использования метода "модифицированного base64 для URL". Кто-нибудь делал это?
Для декодирования, я знаю, это начинается с чего-то вроде:
string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');
// Append '=' char(s) if necessary - how best to do this?
// My normal base64 decoding now uses encodedText
Но мне нужно потенциально добавить один или два символа '=' в конец, что выглядит немного сложнее.
Моя логика кодирования должна быть немного проще:
// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);
// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');
Я видел запись Guid to Base64 для URL Stackru, но она имеет известную длину, и поэтому они могут жестко задавать количество знаков равенства, необходимых в конце.
5 ответов
Это должно правильно дополнить:
base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
Также проверьте класс HttpServerUtility с методами UrlTokenEncode и UrlTokenDecode, которые обрабатывают безопасное кодирование и декодирование Base64 URL.
Примечание 1: результат не является допустимой строкой Base64. Некоторые небезопасные символы для URL заменены.
Примечание 2: Результат отличается от алгоритма base64url в RFC4648.
///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
byte[] encbuff = Encoding.UTF8.GetBytes(str);
return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
return Encoding.UTF8.GetString(decbuff);
}
Недостаточно точек для комментариев, но в случае, если это поможет, фрагмент кода, который Sushil обнаружил в предоставленной ссылке (черновик JSON Web Signature ietf), работает при кодировании Base 64 в качестве параметра в URL.
Скопированный ниже фрагмент для тех, кто ленив:
static string Base64UrlEncode(byte[] arg)
{
string s = Convert.ToBase64String(arg); // Regular base64 encoder
s = s.Split('=')[0]; // Remove any trailing '='s
s = s.Replace('+', '-'); // 62nd char of encoding
s = s.Replace('/', '_'); // 63rd char of encoding
return s;
}
static byte[] Base64UrlDecode(string arg)
{
string s = arg;
s = s.Replace('-', '+'); // 62nd char of encoding
s = s.Replace('_', '/'); // 63rd char of encoding
switch (s.Length % 4) // Pad with trailing '='s
{
case 0: break; // No pad chars in this case
case 2: s += "=="; break; // Two pad chars
case 3: s += "="; break; // One pad char
default: throw new System.Exception(
"Illegal base64url string!");
}
return Convert.FromBase64String(s); // Standard base64 decoder
}
Я нажал здесь, когда искал код для кодирования / декодирования для кодирования base64url, который немного отличается от base64, как объяснено в вопросе.
Найденный фрагмент кода C# в этом документе. Проект JSON Web Signature ietf
По сравнению с принятым ответом, вот как вы бы в основном декодировали URL в кодировке base64, используя C#:
Decode:
string codedValue = "base64encodedUrlHere";
string decoded;
byte[] buffer = Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);