В краткой форме вы могли бы:
- разбить строку на любые символы, которые не являются допустимыми данными base64 или отступом
- попробуйте конвертировать каждый токен
- если преобразование выполнено успешно, вызовите replace в исходной строке, чтобы переключить токен с преобразованным значением
В коде:
var delimiters = new char[] { /* non-base64 ASCII chars */ };
var possibles = value.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
//need to tweak to include padding chars in matches, but still split on padding?
//maybe better off creating a regex to match base64 + padding
//and using Regex.Split?
foreach(var match in possibles)
{
try
{
var converted = Convert.FromBase64String(match);
var text = System.Text.Encoding.UTF8.GetString(converted);
if(!string.IsNullOrEmpty(text))
{
value = value.Replace(match, text);
}
}
catch (System.ArgumentNullException)
{
//handle it
}
catch (System.FormatException)
{
//handle it
}
}
Однако без разделителя вы можете в конечном итоге преобразовать текст не в формате base64, который также будет действительным как кодированный в base64 текст.
Глядя на ваш пример попытки конвертировать "Hello QXdlc29tZQ== World"
в "Hello Awesome World"
, приведенный выше алгоритм может легко сгенерировать что-то вроде "ée¡Ý•Í½µ”¢¹]"
, пытаясь конвертировать всю строку из base64, поскольку нет разделителя между простым и закодированным текстом.
Обновление (на основе комментариев):
Если в содержимом base64 нет '\n'
s и ему всегда предшествует "Content-Transfer-Encoding: base64\n"
, то есть способ:
- разбить строку на
'\n'
- итерация по всем токенам, пока токен не заканчивается в
"Content-Transfer-Encoding: base64"
- следующий токен (если есть) должен быть декодирован (если возможно), а затем замена должна быть сделана в исходной строке
- возврат к итерации до выхода из токенов
В коде:
private string ConvertMixedUpTextAndBase64(string value)
{
var delimiters = new char[] { '\n' };
var possibles = value.Split(delimiters,
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < possibles.Length - 1; i++)
{
if (possibles[i].EndsWith("Content-Transfer-Encoding: base64"))
{
var nextTokenPlain = DecodeBase64(possibles[i + 1]);
if (!string.IsNullOrEmpty(nextTokenPlain))
{
value = value.Replace(possibles[i + 1], nextTokenPlain);
i++;
}
}
}
return value;
}
private string DecodeBase64(string text)
{
string result = null;
try
{
var converted = Convert.FromBase64String(text);
result = System.Text.Encoding.UTF8.GetString(converted);
}
catch (System.ArgumentNullException)
{
//handle it
}
catch (System.FormatException)
{
//handle it
}
return result;
}