写一个1和0的字符串到二进制文件?

时间:2011-09-03 03:20:34

标签: java python c bash

我想取一个1和0的字符串并将其转换为实际的二进制文件(只需将1和0的字符串写入文件就可以使其成为包含“00110001”和“00110000”的ascii文件)。我更喜欢在python中或直接从bash shell中执行此操作,但java或C也可以。这可能是一次性使用。

感谢。

5 个答案:

答案 0 :(得分:17)

在Python中,使用int内置函数将0和1的字符串转换为数字:

>>> int("00100101", 2)
37

然后使用内置的chr将8位整数(即包含范围0-255)转换为字符。

>>> chr(_)
'%'

可以使用chr方法将file.write的结果简单地写入文件(以二进制模式打开)。

答案 1 :(得分:6)

如果你有超过8个字符要转换(我假设你这样做)那么你需要这样的东西(使用Python):

>>> b = '0010101001010101010111101010100101011011'
>>> bytearray(int(b[x:x+8], 2) for x in range(0, len(b), 8))
bytearray(b'*U^\xa9[')

这会将位串分成8个字符块(如果你的字符串不是8长的倍数你应该先填充它),将每个块转换成一个整数然后将整数列表转换为{{1可以直接写入二进制文件(不需要将其转换为字符串):

bytearray

如果您有更多这样的任务,那么有些库可以提供帮助,例如,使用我的bitstring模块进行相同的转换:

>>> with open('somefile', 'wb') as f:
...     f.write(the_bytearray)

答案 2 :(得分:3)

任何可以进行移位的语言都可以组合任何基数。虽然我喜欢不同语言可以轻松访问这些内容的不同方式/操作,但永远不要忘记所有这些都是一些非常基本的数学。

在这种情况下,二进制只是2的简单幂:

    1 << 1 = 1
    1 << 2 = 2
    1 << 3 = 4
    1 << 4 = 8

依旧......

如果您使用二进制字符串:10100101,您可以轻松地将其转换为字节,如下所示:

    (1 << 7) + (0 << 6) + (1 << 5) + (0 << 4) + (0 << 3) + (1 << 2) + (0 << 1) + 1

假设您已经完成并首先将每个“0”或“1”转换为它的数字格式。

如果你处理的位数大于上面的8位,这将开始变得有点乏味,但由于你一次做一个字节,你选择的语言中的一个简单的字节数组就足够了,允许你推送每个字节反过来。

值得一提的是,同样的过程可以用于其他基础,如果你没有移位工具,简单的乘法通常也可以。

如果你用二进制标记顶部的列,你可以很容易地看到我正在谈论的内容......采用上面的例子(记住它的所有权力都是2):

    1   0  1  0  0 1 0 1
    128 64 32 16 8 4 2 1 = 128 + 32 + 4 + 1 = 165

不是问题的一部分,而是相关......并且更进一步:

十六进制是值0到F(16个值),每个值可以容纳4位......所以

    1010 0101 (8+2) (4+1) - Binary using powers of 2 only on 4 bits (8 4 2 1)
    10   5    (Decimal) - (10 << 4) + 5 = 165
    A    5    (Hexadecimal)

答案 3 :(得分:1)

这不是那么实用,但这是一种可以在shell脚本中完成的方法。注意:它使用bc

#!/bin/bash

# Name of your output file
OFILE="output.txt"

# A goofy wrapper to convert a sequence of 8 1s and 0s into a 8-bit number, expressed in hex
function bstr_to_byte()
{
    echo "obase=16;ibase=2;$1" | bc
}


# Build input string from stdin
#   This can be done using pipes ( echo "1010101..." | ./binstr.sh
#   Or "interactively", so long as you enter q on it's own line when you are done entering your
#       binary string.
ISTR=""
while read data; do
    if [[ ${data} != "q" ]] ; then
        ISTR="${ISTR}${data}"
    else
        break
    fi
done

# Byte-by-byte conversion
while [[ $(expr length ${ISTR}) -ge 8 ]] ; do
    # Copy the first 8 characters
    BSTR=${ISTR:0:8}
    # Drop them from the input string
    ISTR=${ISTR:8}
    # Convert the byte-string into a byte
    BYTE=$(bstr_to_byte $BSTR)

    # Debug print
    ##echo "$BSTR => [ ${BYTE} ]"

    # Write character to file
    echo -en "\x${BYTE}" >> ${OFILE}

    # Check for empty ISTR, which will cause error on iteration
    if [[ -z ${ISTR} ]] ; then
        ##echo "String parsed evenly"
        break
    fi
done

##echo "Remaining, unparsed characters: ${ISTR}"

如果你的名字binstr.sh可以通过管道标准输入运行,例如:

echo "11001100" | ./binstr.sh

您可以使用hexdump等内容进行检查,例如hexdump output.txt

我应该指出,这假设您的字符串是首先使用MSB输入的。它也将简单地丢弃任何不形成完整字节的“位”。您可以更改此设置,或者只是确保填充输入。

最后,我留下了一些调试线,但注释了双#符号。

答案 4 :(得分:1)

在java中你有内置函数Integer.parseInt(String strBinaryNumber,int radix)方法。

哪个工作为..

             String strBinaryNumber="00100101";
     System.out.println(Integer.parseInt(strBinaryNumber,2));

输出将是:                     37

但 如果发生以下任何一种情况,则抛出NumberFormatException类型的异常:

  1. 第一个参数为null或是一个长度为零的字符串。
  2. 基数小于Character.MIN_RADIX或大于Character.MAX_RADIX。
  3. 字符串的任何字符都不是指定基数的数字,除非第一个字符可能是减号' - '('\ u002D'),前提是字符串长度超过长度1。 4.字符串表示的值不是int类型的值。