Напишите строку из 1 и 0 в двоичный файл?

Я хочу взять строку из 1 и 0 и преобразовать ее в фактический двоичный файл (просто написать строку из 1 и 0 в файл просто сделает это либо файл ascii, содержащий "00110001" и "00110000" s). Я бы предпочел сделать это в python или непосредственно из оболочки bash, но java или C тоже в порядке. это, вероятно, одноразовое использование.

Спасибо.

Ответ 1

В Python используйте встроенную функцию int, чтобы преобразовать строку из 0s и 1s в число:

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

Затем используйте встроенный chr, чтобы преобразовать 8-разрядное целое число (то есть в инклюзивный диапазон 0-255) в символ.

>>> chr(_)
'%'

Результат chr может быть просто записан в файл (открыт в двоичном режиме) с помощью метода file.write.

Ответ 2

Если у вас есть более 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 длинам, вы должны сначала ее поместить), преобразует каждый фрагмент в целое число и затем преобразует список целых чисел в bytearray который может быть записан непосредственно в ваш двоичный файл (нет необходимости преобразовывать его в строку):

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

Если у вас больше таких задач, то есть библиотеки, которые могут помочь, например, здесь такое же преобразование, используя модуль bitstring:

>>> from bitstring import BitArray
>>> with open('somefile', 'wb') as f:
...     BitArray(bin=b).tofile(f)

Ответ 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)

Ответ 4

Это не все так практично, но здесь один способ это можно сделать в оболочке script. Примечание: он использует 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 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, может быть запущено с помощью stdin трубопровода, например:

echo "11001100" | ./binstr.sh

Вы можете проверить это с помощью чего-то вроде hexdump, например. hexdump output.txt

Я должен указать, что это предполагает, что ваша строка вводится сначала с MSB. Он также просто отбросит любое количество "бит", которые не образуют полный байт. Вы можете это изменить или просто убедитесь, что вы достаточно вставляете свой вход.

Наконец, есть некоторые строки отладки, которые я оставил там, но прокомментировал их двумя знаками #.

Ответ 5

В java u есть встроенная функция Integer.parseInt(String strBinaryNumber, int radix).

Какая работа как..

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

Выход будет:                   37

но Исключение типа NumberFormatException вызывается при возникновении любой из следующих ситуаций:

  • Первый аргумент равен null или является строкой с нулевой длиной.
  • Радиус либо меньше, чем Character.MIN_RADIX или больше, чем Character.MAX_RADIX.
  • Любой символ строки не является цифрой указанного радиуса, за исключением того, что первый символ может быть знаком минус '-' ('\ u002D') при условии, что строка длиннее длины 1. 4. Значение, представленное строкой, не является значением типа int.