0

I read a file as binary, convert to hex string, convert back to binary, and write to a new file. I expect a duplicate, but get a corrupted file.

I have been trying different ways to convert the binary into the hex string but can't seem to retain the entire file.

            byte[] binary1 = File.ReadAllBytes(@"....Input.jpg");

            string hexString = "";                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
            int counter1 = 0;
            foreach (byte b in binary1)
            {
                counter1++;
                hexString += (Convert.ToString(b, 16));
            }

            List<byte> bytelist = new List<byte>();

            int counter2 = 0;
            for (int i = 0; i < hexString.Length/2; i++)
            {
                counter2++;
                    string ch = hexString.Substring(i*2,2);
                bytelist.Add(Convert.ToByte(ch, 16));

            }
            byte[] binary2 = bytelist.ToArray();

            File.WriteAllBytes(@"....Output.jpg", binary2);

Counter 1 and counter 2 should be the same count, but counter 2 is always about 10% smaller.

I want to get a duplicate file output that I could have transferred around via that string value.

Zeckal
  • 145
  • 1
  • 9
  • You should check which bytes are different. That could help you solving this issue. – Julian Jun 26 '19 at 21:02
  • Most bytes are different, about 95%. This is probably due to the missing bytes causing the lists to become offset from each other. – Zeckal Jun 26 '19 at 21:10
  • do you have a small byte array to reproduce the problem? (to replace ` byte[] binary1`) – Julian Jun 26 '19 at 21:14
  • The smallest input I can give it with a .jpg file type still has 600 bytes and still seems to just drop some bytes. If I give it a .txt file it works without error. – Zeckal Jun 26 '19 at 21:25
  • got it already reproducible with 1 byte ;) See answer – Julian Jun 26 '19 at 21:26

1 Answers1

1

Converting byte 10 will give a single char, and not 2 characters. Your convert back method (logically) build on 2 chars per byte.

this case works

byte[] binary1 = new byte[] { 100 }; // convert will result in "64"

and this case fails

byte[] binary1 = new byte[] { 10 }; // convert will result in "a"

I quick fixed your code, by padding with a "0" in case of a single char.

so working code:

byte[] binary1 = new byte[] { 100 };

string hexString = "";
int counter1 = 0;
foreach (byte b in binary1)
{
    counter1++;
    var s = (Convert.ToString(b, 16));
    // new
    if (s.Length < 2)
    {
        hexString += "0";
    }
    // end new
    hexString += s;
}

List<byte> bytelist = new List<byte>();

int counter2 = 0;
for (int i = 0; i < hexString.Length / 2; i++)
{
    counter2++;
    string ch = hexString.Substring(i * 2, 2);
    var item = Convert.ToByte(ch, 16);
    bytelist.Add(item);

}
byte[] binary2 = bytelist.ToArray();

Please note, your code could use some refactoring, e.g. don't string concat in a loop and maybe check the Single Responsibility Principle.

Update, got it fixed, but there are better solutions here: How do you convert a byte array to a hexadecimal string, and vice versa?

Julian
  • 33,915
  • 22
  • 119
  • 174
  • I don't know what the { 10 } vs { 100 } does but the link you provided has the solution that works. – Zeckal Jun 28 '19 at 20:38