Вопрос Как переместить определенные биты в новый файл?


Есть ли способ, чтобы я мог вставлять определенные биты в новый файл, не создавая временных файлов, а затем конкатенировать их?

Например, я хочу создать файл из 10 октетов, где первые три 4, следующие два 7 и последние пять 32,

0000.0100 0000.0100 0000.0100 0000.0111 0000.0111 0010.0000 0100.0000 0010.0000 0010.0000 0010.0000

Мне нужно решение, которое позволит мне создавать большие файлы, где определенные биты повторяются много раз.


2
2017-12-14 23:07


происхождения


Возможный дубликат: askubuntu.com/questions/85951/... - Caesium
@Caesium Ответ на этот вопрос не будет работать для меня. Мне нужно создать большие файлы, где конкретные биты повторяются очень много раз. - Paul
@Caesium Если есть какое-то (желательно предварительно упакованное) решение оболочки, я должен просто конкатенировать несколько файлов. Я не думаю, что писать C или Perl оправдано для этой проблемы. :) - Paul


ответы:


Это довольно просто в Python. Вы можете запустить интерактивный интерпретатор, просто набрав python и сделать что-то вроде этого:

>>> open("test.bin", "wb").write("\4\4\4\7\7\32\32\32\32\32")

'wb' означает «открыть файл для записи двоичных данных», просто открыв файл с помощью w Предположим, вы хотите написать текст к нему.

Обратите внимание, что это восьмеричный номера (\32 является 0x1a, или 26)! Они также могут быть шестнадцатеричными (\xff), и вы можете сохранить некоторые типизации, делая что-то вроде этого:

>>> "\x00" * 4 + "\x09"
'\x00\x00\x00\x00\x09'

Применяется нормальный приоритет оператора.

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

>>> d = [1, 2, 3, 4, 5]
>>> ''.join(chr(i) for i in d)
'\x01\x02\x03\x04\x05'

Если вы предпочитаете использовать python3, вы должны использовать bytes() как это:

>>> bytes([1, 2, 3, 4, 5])

Конечно, «арифметика» работает так, как вы ожидали:

>>> [1, 2, 3] * 2 + [9] * 4 + range(4)
[1, 2, 3, 1, 2, 3, 9, 9, 9, 9, 0, 1, 2, 3]
>>> range(10, 0, -3)
[10, 7, 4, 1]

Бинарные, оркальные и шестнадцатеричные литералы написаны так:

0b1100 == 0o14 == 12 == 0xc

(Или 014 Если вы предпочитаете)

Если вы хотите сделать некоторые сложные вещи, сначала откройте файл, а затем постепенно напишите ему:

>>> f = open("test.bin", "wb")
>>> f.write("\xff" * 100)
>>> for i in range(10):
...     f.write("\xff\xfa\x03")
...
>>> f.close()

И если вы хотите создать сценарий, вы можете использовать -c переключиться на вызов кода непосредственно из командной строки:

python -c "open('test.bin', 'wb').write(''.join(chr(i) for i in [1, 2, 3]))"

1
2017-12-15 08:35





В рубине, написав образец 10 раз:

File.open('bits','w') do |f|
    10.times do
        f << ([0x04]*3+[0x07]*2+[0x20]*5).pack('C*')
    end
end

При записи в файл на каждой итерации мы сохраняем только одну копию битового паттерна в памяти. Таким образом, вы можете записать произвольно большие файлы, изменив 10.times в 10000.times и т.п.

Итак, из командной строки:

$ ruby -e "File.open('bits','w'){|f|10.times{f<<([0x04]*3+[0x07]*2+[0x20]*5).pack('C*')}}"

Затем проверьте файл:

$ xxd -b bits 
0000000: 00000100 00000100 00000100 00000111 00000111 00100000  ..... 
0000006: 00100000 00100000 00100000 00100000 00000100 00000100      ..
000000c: 00000100 00000111 00000111 00100000 00100000 00100000  ...   
0000012: 00100000 00100000 00000100 00000100 00000100 00000111    ....
0000018: 00000111 00100000 00100000 00100000 00100000 00100000  .     
000001e: 00000100 00000100 00000100 00000111 00000111 00100000  ..... 
0000024: 00100000 00100000 00100000 00100000 00000100 00000100      ..
000002a: 00000100 00000111 00000111 00100000 00100000 00100000  ...   
0000030: 00100000 00100000 00000100 00000100 00000100 00000111    ....
0000036: 00000111 00100000 00100000 00100000 00100000 00100000  .     
000003c: 00000100 00000100 00000100 00000111 00000111 00100000  ..... 
0000042: 00100000 00100000 00100000 00100000 00000100 00000100      ..
0000048: 00000100 00000111 00000111 00100000 00100000 00100000  ...   
000004e: 00100000 00100000 00000100 00000100 00000100 00000111    ....
0000054: 00000111 00100000 00100000 00100000 00100000 00100000  .     
000005a: 00000100 00000100 00000100 00000111 00000111 00100000  ..... 
0000060: 00100000 00100000 00100000 00100000                        

См. Документацию для Array.pack Вот,


2
2017-12-15 01:18



Я дал вам +1, но я выберу ответ Стефано, потому что я знаю Python, но не Ruby. - Paul