【问题标题】:encode decode binary data编码解码二进制数据
【发布时间】:2014-08-09 19:11:23
【问题描述】:

我知道二进制值“1000001”转换为十进制后是65,根据ASCII表是字母A。

现在,我有一个二进制文件(xxx.bin),假设具有上述位序列。我怎么知道 tat 二进制值是表示十进制值 65 还是字符 A??

我想当我收到二进制文件时,我应该也知道这个二进制文件遵循什么字符编码或字符集文档?或者我能找出它是如何编码的吗??

有人可以弄清楚如何正确解码和读取二进制文件(xxx.bin)数据吗?只需将每个字节转换为十进制值或遵循一些字符编码逻辑???我对这部分感到困惑!

【问题讨论】:

    标签: binary ascii decode encode


    【解决方案1】:

    这是我编写的将字符串编码为“点”和“空格”的程序。如果提供了代码,它也可以将其解码回原始字符串。自己试试。其中有一个 encode_find() 函数,它将一个字符转换为其二进制等效项并将其存储在变量“en”中。逆过程可以实现decode_find()函数。

    import java.io.*;
    class ed2
    {
    
    BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
    
    void encode()throws InterruptedException,IOException
    {
        String rs,ren;
    
        encoder_symbol();
        rs = encode_input();
        ren = encode_find(rs);
        encode_display(ren);
    }
    
    void decode()throws InterruptedException,IOException
    {
        String rs,rde;
    
        decoder_symbol();
        rs = decode_input();
        rde = decode_find(rs);
        decode_display(rde);
    }
    
    void encoder_symbol()throws InterruptedException //just for fun
    {
        System.out.println("********  ***         ***  *********  ************  ******      ********  *****");
        Thread.sleep(100);
        System.out.println("********  ****        ***  *********  ************  ********    ********  *** **");
        Thread.sleep(100);
        System.out.println("***       *****       ***  ***        ***      ***  ***   ***   ***       ***  **");
        Thread.sleep(100);
        System.out.println("***       *** **      ***  ***        ***      ***  ***    ***  ***       *** **");
        Thread.sleep(100);
        System.out.println("******    ***  **     ***  ***        ***      ***  ***    ***  ******    *****");
        Thread.sleep(100);
        System.out.println("******    ***   **    ***  ***        ***      ***  ***    ***  ******    *****");
        Thread.sleep(100);
        System.out.println("***       ***     **  ***  ***        ***      ***  ***    ***  ***       *** **");
        Thread.sleep(100);
        System.out.println("***       ***      ** ***  ***        ***      ***  ***   ***   ***       ***  **");
        Thread.sleep(100);
        System.out.println("*******   ***       *****  *********  ************  ********    ********  ***   **");
        Thread.sleep(100);
        System.out.println("*******   ***        ****  *********  ************  ******      ********  ***    **");
        Thread.sleep(2700);
    
        System.out.println();
        System.out.println();
    }
    
    void decoder_symbol()throws InterruptedException // just for fun
    {
        System.out.println("******      ********  *********  ************  ******      ********  *****");
        Thread.sleep(100);
        System.out.println("********    ********  *********  ************  ********    ********  *** **");
        Thread.sleep(100);
        System.out.println("***   ***   ***       ***        ***      ***  ***   ***   ***       ***  **");
        Thread.sleep(100);
        System.out.println("***    ***  ***       ***        ***      ***  ***    ***  ***       *** **");
        Thread.sleep(100);
        System.out.println("***    ***  ******    ***        ***      ***  ***    ***  ******    *****");
        Thread.sleep(100);
        System.out.println("***    ***  ******    ***        ***      ***  ***    ***  ******    *****");
        Thread.sleep(100);
        System.out.println("***    ***  ***       ***        ***      ***  ***    ***  ***       *** **");
        Thread.sleep(100);
        System.out.println("***   ***   ***       ***        ***      ***  ***   ***   ***       ***  **");
        Thread.sleep(100);
        System.out.println("********    ********  *********  ************  ********    ********  ***   **");
        Thread.sleep(100);
        System.out.println("******      ********  *********  ************  ******      ********  ***    **");
        Thread.sleep(1000);
    
        System.out.println();
        System.out.println();
    }
    
    String encode_input()throws IOException
    {
        String s;
        System.out.println("ENTER THE STRING TO BE ENCODED");
        s = obj.readLine();
        return(s);
    }
    
    String decode_input()throws IOException
    {
        String s;
        System.out.println("ENTER THE CODE TO BE DECODED");
        s = obj.readLine();
        return(s);
    }
    
    String encode_find(String s)//converting the string into its binary equivalent
    {
         int ac,i,j,l,chklen;
         String bc,en="";
         char ic;
         l = s.length();    
         for(i=0;i<l;i++)
         {   
             ic = s.charAt(i); //takes out every character
             bc = ""; 
             ac = (int)ic;  //ASCII value of this character
             while(ac!=0)
             {
                 bc = Integer.toString((ac%2)) + bc; //converting the ASCII value into binary equivalent
                 ac = ac/2;
             }
             chklen = bc.length();//length of the binary equivalent
             if(chklen<7)
             {
                for(j=1;j<=(7-chklen);j++) //increasing the length of binary equivalent so that it becomes equal to 7
                {  
                    bc = "0" + bc;
                }
             }
             en = en+bc; //concatenating all the binary equivalent into one string
         }
         return (en);
    }
    
    String decode_find(String s)// converts binary(i.e. in the form of dots and space) to decimal
    {
        int f;//for the index of every character of code
        long l,i,j,ac;
        char c;
        String de="";
    
        l = s.length();
        f = 0;//index of first caharcter
        for(i=0;i<(l/7);i++)//since the length of every binary equivalent of a character is 7 therefore there will be (length/7) characters in a code of length l
        {
            ac = 0;//intializes the decimal(ASCII) equivalent to zero
            for(j=6;j>=0;j--)//loop will work 7 times for every binary equivalent of a character
            {
                c = s.charAt(f);//takes out every dot or space
                if(c=='.')//it means that c corresponds to 'one'
                {
                    ac = ac + ((int)Math.pow(2,j));//converting binary into decimal(ASCII) equivalent by adding all the powers of 2 which correspond to one('.') 
                }
                f++;//increasing the index for next character of binary equivalent
            }
            de = de + ((char)ac);//converts the ASCII equivalent into character and then concatenates it with the intitial string
        }
        return(de);
    }
    
    void encode_display(String en)//displays the code
    {
        int i,l;
        char ic;
        System.out.println("YOUR ENCODED MESSAGE IS :");
        l=en.length();
        for(i=0;i<l;i++)
        {
            ic=en.charAt(i);
            if(ic=='1')//for every 'one' it will print '.'(dot)
            {
                 System.out.print(".");
            }
            else if(ic=='0')//for every 'zero' it will print ' '(space)
            {
                 System.out.print(" ");
            }
        }
    }
    
    void decode_display(String de)
    {
        System.out.println(de);
    }
    
    public static void main(String args[])throws IOException,InterruptedException
    {
        BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
    
        char ch;
    
        ed2 ed = new ed2();
    
        System.out.println("PRESS 'E' TO ENCODE A MESSAGE OR PRESS 'D' TO DECODE A MESSAGE");
        ch = (char)obj.read();
    
        if((ch=='e')||(ch=='E'))
        {
            ed.encode();
        }
        else if((ch=='d')||(ch=='D'))
        {
            ed.decode();
        }
    }
    

    }

    【讨论】:

    • 当你说“ASCII”并使用 7 位时,它应该是“UTF-16 代码单元”和 16 位。用“”试试;它应该看起来像 0010000010101100。
    • 我不是说 7 个“位”,我说“长度”是 7。如果每个单独的二进制字符串的长度不同,解码器如何知道代码的长度它必须从用户输入的代码中提取。因此,为了简化一点,对于解码器,它总是提取“长度”为 7 的代码。这是通过在每个字母的二进制字符串之前添加所需数量的零来完成的,因为在 a 之前添加任意数量的零二进制数不会改变它的值。
    • 我的意思是 char 是 16 位。如果只处理C0 Controls and Basic Latin characters,则在ic &gt; '\u007F' 时抛出异常。
    【解决方案2】:

    如果您不知道文件的格式,那么您就会丢失数据。

    接下来的问题是如何防止丢失重要的“元数据”。典型的方式是通过协议和规范。

    在某些情况下,您可以确定文件具有在某些编码中无效的字节值或序列,例如 0x80 不是有效的 ASCII 并且 0xE2 0x20 不是有效的 UTF-8。有这种猜测的库。但是绝对不能排除CP437;因此,每个文件都可以被认为是一个文本文件,就像每个文件都可以被认为是 0-255 或 -128 到 127 的值序列一样,每个具有偶数字节的文件都可以被认为是......

    有根据各种嵌套协议解释字节的协议分析器,例如 Wireshark,还有显示字节和尝试转换为字符的十六进制编辑器。一些十六进制编辑器非常复杂,具有按字节查找、按文本查找等功能,允许您描述协议并将其应用于文件的某些部分。 (旧的磁盘扇区编辑器就是一个例子。)

    最重要的是,这是逆向工程,希望您不需要这样做。

    顺便说一句——65 是许多编码中的字母 A;不只是 ASCII。

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 2015-06-27
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2012-06-26
      • 2021-06-11
      • 2012-05-14
      • 2012-07-25
      相关资源
      最近更新 更多