En forma corta que podía:
- dividir la cadena en cualquier caracteres que no son datos de base64 válidos o el relleno
- intenta convertir cada ficha
- si la conversión se realiza correctamente, llame a sustituir en el cadena original para cambiar el token con el valor convertido
En código:
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
}
}
Sin un delimitador sin embargo, se puede lograr la conversión de texto no-base 64 que pasa a ser válido también como base64 texto.
En cuanto a su ejemplo de tratar de convertir a "Hello QXdlc29tZQ== World"
"Hello Awesome World"
el algoritmo anterior fácilmente podría generar algo así como "ée¡Ý•Í½µ”¢¹]"
por tratar de convertir a toda la cadena desde la base 64 ya que no hay delimitador entre texto plano y codificado.
Update (basado en los comentarios):
Si no hay '\n'
s en el contenido de base 64 y que siempre va precedida de "Content-Transfer-Encoding: base64\n"
, entonces hay una manera:
- dividir la cadena en
'\n'
- iterar sobre todas las fichas hasta que un contador termina en
"Content-Transfer-Encoding: base64"
- la siguiente muestra (si las hay) debe ser decodificado (si es posible) y luego el reemplazo debe ser ma de la cadena original
- retorno a iterando hasta que sin fichas
En el código:
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;
}
es el contenido delimitado base 64 en forma alguna ? – jball
Este es un problema XY. El verdadero problema es X: cómo terminaste con una cadena así. –
@Hans Passant Acepto, estoy intentando escribir una herramienta para corregir algunos datos que de alguna manera estaban corruptos. Ya hemos arreglado la parte que hace los datos corruptos, pero ahora tenemos que arreglarlo en aproximadamente 3 millones de registros. – Adam