【问题标题】:Print a file in binary form (1 and 0)以二进制形式打印文件(1 和 0)
【发布时间】:2012-07-20 12:53:59
【问题描述】:

在 GZip 解码器的上下文中,我需要一个 unix 工具或 C 解决方案来以二进制形式在我的屏幕上打印我的压缩 gzip 文件。我真正需要的是能够以二进制而不是八进制、十进制或十六进制打印的 hexdump。

我很确定这个工具存在但我找不到它:-(

编辑 我想这样的编辑器很难找到,因为用例不能很频繁。就我而言,我的文件非常小,需要出于调试目的来搜索可能跨越多个字节的二进制“模式”,例如 10010011

【问题讨论】:

标签: c bash hexdump


【解决方案1】:
perl -ne 'print unpack(B8,$_),$/for split//' FILE

或者一行有 8 个元素

perl -ne 'print unpack(B8,$_),++$i%8?" ":"\n"for split//;END{print"\n"}' 

没有换行符

perl -ne 'print unpack(B8,$_)for split//' FILE

【讨论】:

  • 完美!并且没有换行符,我应该如何修改它?
【解决方案2】:

因为Manuel让我重新发帖,所以我完成了上次写的评论,这里是电话:

od -t x1 FILE | sed 'h;x;s:^\(........\).*:\1:;x;s:^........::;s:0:0000:g;s:1:0001:g;s:2:0010:g;s:3:0011:g;s:4:0100:g;s:5:0101:g;s:6:0110:g;s:7:0111:g;s:8:1000:g;s:9:1001:g;s:a:1010:g;s:b:1011:g;s:c:1100:g;s:d:1101:g;s:e:1110:g;s:f:1111:g;H;x;s:\n::'

【讨论】:

  • 谢谢,不要责怪我对 sed 的无知 ;-)
【解决方案3】:

你的编译器可以支持这个实用函数ltoa

char *ltoa(long value, char * buffer, int radix);

这可以简化 radix = 2 的显示

【讨论】:

    【解决方案4】:

    从我做出的另一个答案(不幸的是,我现在找不到)我有这个功能可以将int 打印为二进制数字:

    void print_bin(int n)
    {
        for (int i = sizeof(n) * 8 - 1; i >= 0; i--)
            printf("%d", (int) ((n >> i) & 1));
    }
    

    您可以将文件读取为整数,并使用此函数将值打印为二进制数字。

    【讨论】:

    • 感谢您的提示。如果不存在这样的 heditor,我会从这个开始写一个小工具。
    • int(((n >> i) & 1)) 是什么意思?它不适合我?
    • @ManuelSelva 啊,我最初在 C++ 程序中使用它,现在编辑为 C 风格的转换。
    • 谢谢我明白了 ;-) 但为什么我不想这样做是因为您的解决方案打印的结果与另一个答案中提出的其他 C 手动编码解决方案不同;- )
    • @ManuelSelva 你是什么意思“不打印相同的结果”?如果您需要,该函数很容易更改为打印单个字节(只需将参数类型更改为char)?
    【解决方案5】:
    od -t x1 FILE | sed 's:0:0000:g;s:1:0001:g;\
    s:2:0010:g;s:3:0011;
    ...[replace every hex-digit up to F with the bin representation] '
    

    【讨论】:

    • 命令的语法不是goo。你能修一下吗,这正是我需要的
    【解决方案6】:

    只需要写一个小程序:

    #include <stdio.h>
    
    void binarywrite (unsigned char c)
    {
        int i = 0;
        for (i = 0; i < 8; i++)
        {
            printf("%1d",(c>>(7-i)) & 1 );
        }
        printf(" ");
    }
    
    int main(int argc, char* argv[])
    {
        char c = 0;
    
        if(argc >=2)
        {
            char* pfilename = argv[1];
            FILE *fp;
            fp = fopen(pfilename,"rb");
            char ch;
            while((ch = getc(fp)) != EOF)
            {
                binarywrite(ch);
            }
            fclose(fp);
        }
    
        return 0;
    } 
    

    您可以将其用作“./binarywite 文件名”

    【讨论】:

    • 感谢您的回答。但为什么我不想这样做是因为您的解决方案没有打印出与其他答案中提出的其他 C 手工编码解决方案相同的结果;-)
    【解决方案7】:

    xxd(通常是vim自带的)可以直接转换成二进制表示:

    xxd -b FILE
    

    要切断输出的格式,可以附加一点 awk,这样你就可以得到一个干净的 0 和 1 流:

    xxd -b FILE | \
        awk '{ for (i=0; i<NF; i=i+1)
               { if ($i ~ /^[01][01][01][01][01][01][01][01]$/) printf $i }
             }; END { print "" }
        '
    

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 2018-06-15
      • 2010-11-04
      • 2016-12-13
      • 1970-01-01
      • 2018-08-30
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多