Eu estava resolvendo um desafio em que encontrei um arquivo de dados sem extensão. O file
comando mostra que é a data file (application/octet-stream)
. O hd
comando mostra o GNP. na última linha. Portanto, se eu reverter esse arquivo, obterei o arquivo no formato .PNG , procurei em todos os lugares, mas não encontrei uma solução explicando como reverter o conteúdo de um arquivo binário.
11
In
zsh
(o único shell que pode lidar internamente com dados binários (a menos que você queira considerar a abordagem de codificação base64 do ksh93 )):LC_ALL=C
: caracteres são bytes$mapfile[file.gnp]
: conteúdo dofile.gnp
arquivos::
: divida a sequência em seus constituintes de bytesOa
:O
rder reverso noa
rray subscrito nessa matrizfonte
zsh
não é o único shell que pode lidar com dados binários.Aqui está uma maneira de reverter um arquivo binário usando
ksh93
. Deixei o código "frouxo" para facilitar a compreensão.fonte
read
acima não deve ler nada, como é feito no final do arquivo.strace
eksh93
parece estar se comportando de maneira estranha, onde ele procura por todo o lugar no arquivo e lê grandes quantidades na época. Talvez uma variante do github.com/att/ast/issues/15strace
o script para ver o que quero dizer.ksh93
lê os arquivos milhares de vezes. Por exemplo, antes de ler o primeiro byte, ele procura 64KiB no final do arquivo, lê 64KiB, depois procura antes do último byte e lê 1 byte e faz algo semelhante para cada byte. Observe que o que você pode fazer com essas cadeias codificadas em base64 é limitado; portanto, se você ler mais de um byte por vez, será mais difícil extrair os bytes individuais disso.Com perl:
Teste de performance:
Resultado:
perl -0777 -F
a mais lenta.xxd
a mais lenta.Nota: o tempo
diff
deve ser o mesmo para todas as soluções, pois a saída deve ser a mesma.fonte
perl
. Eu não tinha percebido na época quereverse
poderia reverter as cordas também, portanto, fazer essa divisão não fazia muito sentido e sua versão é muito melhor.Eu tentei o seguinte:
A idéia é forçar 'tac' usando qualquer caractere como separador. Eu tentei isso em um arquivo binário e parecia funcionar, mas qualquer confirmação seria apreciada.
A principal vantagem é que ele não carrega o arquivo na memória.
fonte
tac
8.28) quando a entrada contém caracteres de nova linha.printf '1\n2' | tac -rs . | od -vAn -tc
saídas em\n 2 1
vez de2 \n 1
. Você também precisariaLC_ALL=C
ou.
poderia corresponder a caracteres de vários bytes.LC_ALL=C tac -rs $'.\\|\n'
parece funcionar embora.