Como posso criar um arquivo binário instructions.bincom os mesmos dados que instructions.txt. Em outras palavras, o .binarquivo deve ter os mesmos 192 bits que estão no .txtarquivo, com 32 bits por linha. Estou usando o bash no Ubuntu Linux. Eu estava tentando usar, xxd -b instructions.txtmas a saída é muito superior a 192 bits.
perl -neirá percorrer cada linha do arquivo de entrada fornecido em STDIN ( instructions.txt)
pack("B32", $_)pegará uma lista de strings de 32 bits ( $_que acabamos de ler de STDIN) e a converterá em valor binário (você pode usar alternativamente "b32"se quiser ordem crescente de bits dentro de cada byte em vez de ordem decrescente; veja perldoc -f packmais detalhes)
print produziria esse valor convertido para STDOUT, que depois redirecionaremos para nosso arquivo binário instructions.bin
Adicionar a -ropção (modo reverso) a xxd -bnão funciona como pretendido, porque o xxd simplesmente não suporta a combinação desses dois sinalizadores (ele ignora -bse os dois forem fornecidos). Em vez disso, você deve converter os bits para se hexagonizar primeiro. Por exemplo, assim:
( echo 'obase=16;ibase=2'; sed -Ee's/[01]{4}/;\0/g' instructions.txt )| bc | xxd -r -p > instructions.bin
Explicação completa:
A parte entre parênteses cria um bcscript. Primeiro, define a base de entrada como binária (2) e a base de saída como hexadecimal (16). Depois disso, o sedcomando imprime o conteúdo instructions.txtcom um ponto-e-vírgula entre cada grupo de 4 bits, o que corresponde a 1 dígito hexadecimal. O resultado é canalizado para bc.
O ponto-e-vírgula é um separador de comandos bc, portanto, todo o script faz é imprimir todos os números inteiros de entrada novamente (após a conversão base).
A saída de bcé uma sequência de dígitos hexadecimais, que pode ser convertida em um arquivo com o habitual xxd -r -p.
Desculpe, ainda há um erro de endianness nisso. Trabalhando em consertá-lo!
Nomadictype 10/10/19
1
Na verdade, está tudo bem. Eu estava confuso anteriormente usando a largura de saída incorreta no último comando xxd.
Nomadictype 10/10/19
1
Eu testei o roteiro e ele funciona, mas saídas: (standard_in) 1: syntax error. Você pode explicar a que syntax errorse refere ou por que isso ocorre? Isso também acontece na sua máquina?
dopamane 10/10
2
Minha resposta original estava incorreta - xxdnão posso aceitar -pou -rcom -b...
Dado que as outras respostas são viáveis e no interesse de " outra maneira ", que tal o seguinte:
Nota: em muitos shells |no final de uma linha funciona como uma barra invertida: o comando continua na próxima linha. Dessa forma, você pode se livrar de algumas barras invertidas. Não tenho certeza se o uso de símbolos de tubulação após LFs foi sua decisão informada. Estou mencionando o contrário, caso você não saiba.
Kamil Maciorowski 10/10
1
Eu não sabia, obrigado! Eu gosto de dividir o pipeline em linhas lógicas e ter os pipes |(ou redirecionamentos >, operadores booleanos &&, etc ...) explicitamente na frente para visibilidade / clareza ... talvez uma coisa estilística / preferencial.
Attie
1
Após algumas reflexões, posso começar a usar esse estilo, porque é possível dizer que as duas linhas estão conectadas, examinando qualquer uma delas. Se |estiver no final, a próxima linha pode parecer um comando independente, pode ser confusa. Por isso, pensei que o estilo poderia ser sua decisão informada.
(standard_in) 1: syntax error
. Você pode explicar a quesyntax error
se refere ou por que isso ocorre? Isso também acontece na sua máquina?Minha resposta original estava incorreta -
xxd
não posso aceitar-p
ou-r
com-b
...Dado que as outras respostas são viáveis e no interesse de " outra maneira ", que tal o seguinte:
Entrada
Resultado
Pipeline Bash:
cat
- desnecessário, mas usado para maior clarezatr -d $'\n'
- remova todas as novas linhas da entradaread -N 4 nibble
- leia exatamente 4 × caracteres nanibble
variávelprintf '%x' "$((2#${nibble}))"
converter a mordidela de binário em 1 × caractere hexadecimal$((2#...))
- converta o valor fornecido da base 2 (binária) para a base 10 (decimal)printf '%x'
- formate o valor fornecido da base 10 (decimal) para a base 16 (hexadecimal)xxd -r -p
- reverse (-r
) uma lixeira comum (-p
) - a partir de hexadecimal para binário rawPitão:
<< EOF
) não citado é usado para obter conteúdo no código Pythoncat
etr
- usado para obter uma entrada limpa (uma linha)range(0, len(d), 8)
- obtenha uma lista de números de 0 até o final da stringd
, percorrendo 8 × caracteres por vez.chr(int(d[i:i+8],2))
- converta a fatia atual (d[i:i+8]
) de binária em decimal (int(..., 2)
) e depois em um caractere bruto (chr(...)
)[ x for y in z]
- compreensão da lista''.join(...)
- converte a lista de caracteres em uma única stringprint(...)
- imprimafonte
|
no final de uma linha funciona como uma barra invertida: o comando continua na próxima linha. Dessa forma, você pode se livrar de algumas barras invertidas. Não tenho certeza se o uso de símbolos de tubulação após LFs foi sua decisão informada. Estou mencionando o contrário, caso você não saiba.|
(ou redirecionamentos>
, operadores booleanos&&
, etc ...) explicitamente na frente para visibilidade / clareza ... talvez uma coisa estilística / preferencial.|
estiver no final, a próxima linha pode parecer um comando independente, pode ser confusa. Por isso, pensei que o estilo poderia ser sua decisão informada.Você também pode postar isso no site CodeGolf SE, mas aqui está a minha versão alternativa do Python (apenas para o desafio do pontapé):
Supondo que você
input.txt
contenha seus dados e está formatado para 32 caracteres por linha.Isso usa o
struct
pacote Python 3 e a escrita / leitura para stdin / out. (No Python 2, seria mais curto).fonte