System.FormatException: Entry is not valid Base64 string

63 views Asked by At

I'm having trouble with reading a file that contains Base64 encoded items. Everything's ok until I try to add new items to the file and read it then.

This is the error code:

Error: System.FormatException: La entrada no es una cadena Base 64 valida porque contiene un caracter que no es Base 64, mas de dos caracteres de relleno o un caracter no valido entre los caracteres de relleno. en System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) en System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) en System.Convert.FromBase64String(String s) Error: 49652976

This is the code where I write the new line:

System.IO.File.AppendAllText(
    @"C:\Users\Public\Documents\Jurassic Command Line\" + _isla + "_Dinosaurs.jcl", System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("\n" + _especie)));
MessageBox.Show(System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("\n" + _especie)));

And this is the code where the file is read

comboBox.Items.Clear();
_data = File.ReadAllText(@"C:\Users\Public\Documents\Jurassic Command Line\Nublar_Dinosaurs.jcl");
_dataDecoded = Decodificar(_data);
File.WriteAllText(_filePath, _dataDecoded);
string[] lines = File.ReadAllLines(_filePath);

 static string Decodificar(string data)
 {
     byte[] encodedDataAsBytes = Convert.FromBase64String(data);
     string returnValue = Encoding.ASCII.GetString(encodedDataAsBytes);
     return returnValue;
 }

I've tried everything I could find, but nothing works.

2

There are 2 answers

0
derpirscher On

The general problem with your code is: Two concatenated base64 strings are not necessarily a valid base64 string. Especially, because base64 uses padding characters (=) at the end, which must not appear in the middle of a valid base64 string. For instance, the base64 encoding of hello is aGVsbG8=. But aGVsbG8=aGVsbG8= is not a valid base64 string.

To fix this issue I'd suggest two changes in your code:

First change the following line, when appending to your textfile: (I simplifed the code a bit by removing the namespaces)

File.AppendAllText(filename, Convert.ToBase64String(Encoding.ASCII.GetBytes("\n" + _especie)));

You should not add the \n into the encoded text (ie what's in _especie) but encode your text first, and then add it with a newline to your textfile. Ie do it as follows

File.AppendAllText(filename, "\n" + Convert.ToBase64String(Encoding.ASCII.GetBytes(_especie));

So each of the added entries will be in a new line of your file.

Second, when decoding the file, split the file contents into separate lines first, and decode each line on its own. With the help of LINQ this can be as easy as

string[] lines = File.ReadAllLines(filename)
  .Select(x => Encoding.ASCII.GetString(Convert.FromBase64String(data)))
  .ToArray();

Be aware, the above does not have any error handling what so ever. But if the file is created correctly (ie like shown above), there should not be any errors.

0
Unseen On

You can simply use base64 string check extensions for it. And dont forget to trim '"' char if you creating your base64 from another source.

public static class Extensions
{
    public static bool IsNotNull(this object obj) => obj is not null;
    public static bool IsValidBase64(this string value) => Base64.IsValid(value);

    public static bool CheckIfValidBase64(this string value) => value.IsNotNull() && value.IsValidBase64();
}
 static string Decodificar(string data)
 {
    var trimmedBase64Input = data.ReplaceLineEndings("").Trim('"');

    if(trimmedBase64Input.CheckIfValidBase64())
    {
      return Encoding.ASCII.GetString(Convert.FromBase64String(trimmedBase64Input ));
    }
    return string.Empty;
 }