将文件转换为二进制11111111110然后执行反向路径以获取图像

问题描述

我有一个 jpg 图像,可以将其转换为二进制数序列,但之后无法恢复。它最终损坏了。

using System;
using System.IO;
using System.Net.Mime;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputFilename = "test.jpg";
            byte[] fileBytes = File.ReadAllBytes(inputFilename);

            var test =  ToBinaryString(fileBytes);
            byte[] bytes = Encoding.ASCII.GetBytes(test);  
            string fileresult = Convert.ToBase64String(bytes);
            byte[] fileresutl2 = Convert.FromBase64String(fileresult);


            File.WriteallBytes("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test7.txt",fileresutl2);
            string text = System.IO.File.ReadAllText("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test7.txt");

            var result =  Convert.ToBase64String(FromBinaryString(text));
            File.WriteallBytes("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test8.jpg",FromBinaryString(test));
            Console.WriteLine(test);
        }
        
        public static string ToBinaryString(byte[] array)
        {
            var s = new StringBuilder();
            foreach (byte b in array)
                s.Append(Convert.ToString(b,2));

            return s.ToString();
        }
        
        public static byte[] FromBinaryString(string s)  
        {
            int count = s.Length / 8;
            var b = new byte[count];
            for (int i = 0; i < count ; i++)
                b[i] = Convert.ToByte(s.Substring(i * 8,8),2);

            return b;
        }
    }
}

我不知道什么会损坏我的文件。 对不起,文件的组织,它只是一个快速编码的测试代码

解决方法

代码中有一些奇怪的东西,例如无用地转换为 base64 并返回,但让我们直接进入问题的核心:将字节转换为二进制字符串

public static string ToBinaryString(byte[] array)
{
    var s = new StringBuilder();
    foreach (byte b in array)
        s.Append(Convert.ToString(b,2));

    return s.ToString();
}

从表面上看,这似乎是合理的。字节进去,二进制串出来。但这里有一些示例,我希望它们能让您相信这种转换存在问题:

Console.WriteLine(ToBinaryString(new byte[]{1,1}));
Console.WriteLine(ToBinaryString(new byte[]{3}));

( https://ideone.com/y6dB1Z )

这两个都显示为“11”。这很糟糕,这意味着转换是不可逆的。出错的原因是最重要的零被丢弃,然后下一个字节“移入”该位置。正如您的解码函数所期望的那样,每个字节都应该由 8 位精确表示。例如:

public static string ToBinaryString(byte[] array)
{
    var s = new StringBuilder();
    foreach (byte b in array)
        s.Append(Convert.ToString(b,2).PadLeft(8,'0'));

    return s.ToString();
}

顺便说一下,你实际上不应该使用这样的东西(除非在试验时,它看起来就是你正在做的,所以没关系),它会增加文件大小8 倍,实际上并没有做任何有用的事情。例如,如果您要解码 JPG,请直接使用文件的字节进行解码,而不是使用“将文件作为二进制字符串”。即使是霍夫曼代码也不应该那样做。