Como enviar bits específicos para um novo arquivo?

2

Existe alguma maneira de eu enviar bits específicos para um novo arquivo, sem criar arquivos temporários e, em seguida, concatená-los?

Por exemplo, eu quero criar um arquivo de 10 octetos, onde os três primeiros são definidos como 4 , os próximos dois a 7 e os cinco finais a 32 .

  

0000.0100 0000.0100 0000.0100 0000.0111 0000.0111 0010.0000 0100.0000 0010.0000 0010.0000 0010.0000

Eu preciso de uma solução que permita criar arquivos grandes, onde bits específicos são repetidos muitas vezes.

    
por Paul 15.12.2011 / 00:07

2 respostas

1

Isso é bem simples em Python. Você pode iniciar o interpretador interativo apenas digitando python e fazer algo assim:

>>> open("test.bin", "wb").write("")

'wb' significa "abrir o arquivo para gravar dados binários para ele", simplesmente abrindo o arquivo com w assumirá que você quer escrever texto para ele.

Note que estes são números octal ( is 0x1a , ou 26)! Eles também podem ser hexadecimais ( \xff ), e você pode economizar algumas digitações fazendo algo assim:

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

A precedência normal do operador se aplica.

Para mais dados, você pode usar listas de inteiros decimais - que eu acho mais fáceis de ler e digitar:

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

Se preferir usar python3 , você usaria bytes() da seguinte forma:

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

Claro que 'aritmética' funciona como você esperaria:

>>> [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]

Literais binários, orais e hexadecimais são escritos assim:

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

(ou 014 , se você preferir)

Se você quiser fazer algumas coisas complicadas, abra o arquivo primeiro e, em seguida, escreva-o gradualmente:

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

E se você quiser fazer o script, você pode usar a opção -c para invocar o código diretamente da linha de comando:

python -c "open('test.bin', 'wb').write(''.join(chr(i) for i in [1, 2, 3]))"
    
por Stefano Palazzo 15.12.2011 / 09:35
2

Em ruby, escrevendo o padrão 10 vezes:

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

Ao escrever no arquivo em cada iteração, nós sempre mantemos uma única cópia do padrão de bits na memória. Dessa forma, você pode escrever arquivos arbitrariamente grandes alterando o 10.times para 10000.times etc.

Então, na linha de comando:

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

Em seguida, verifique o arquivo:

$ 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                        

Veja a documentação do Array.pack aqui .

    
por scottl 15.12.2011 / 02:18