Lendo um arquivo binário como uma matriz de bytes ou 16 ou 32 bits usando o shell script

4

Estou trabalhando em uma máquina host com modem Linux baseada em ARM e preciso ler um arquivo bin como um array de 8, 16 ou 32 bits. Eu basicamente preciso criptografar o arquivo em questão e estava pensando apenas em XOR-ing os bits com uma seqüência de bits aleatória (eu não preciso de um sistema muito complexo). O host Linux não possui módulos C ou PERL, portanto, não posso usá-los e, portanto, preciso fazê-lo usando um script de shell. Alguém pode me dar algumas dicas sobre como proceder com isso?

    
por anshu 19.06.2013 / 11:02

3 respostas

3

Use tr (aqui rot128):

LC_ALL=C tr '
LC_ALL=C tr '
set -- $(od -An -vtu1 < infile)
-7' '3210765432107654321076543210765432107654321076543210765432107654
for i in $(od -An -vtu1 < infile); do
  echo "$(($i ^ 123))"
done | awk '{printf "%c", $0}' > outfile
32107654321076543210765432107654321076543210765432107654321076543210765432107654321076543210765432107654321076543210765432107654'
-7' '0-7
LC_ALL=C tr '
LC_ALL=C tr '
set -- $(od -An -vtu1 < infile)
-7' '3210765432107654321076543210765432107654321076543210765432107654
for i in $(od -An -vtu1 < infile); do
  echo "$(($i ^ 123))"
done | awk '{printf "%c", $0}' > outfile
32107654321076543210765432107654321076543210765432107654321076543210765432107654321076543210765432107654321076543210765432107654'
-7' '0-7%pre%-7' < infile > outfile
-7' < infile > outfile

Para o XOR 123, você precisaria calcular a linha tr correspondente:

%pre%

Mais geralmente, para responder à pergunta, converter um arquivo em uma matriz de números a ser usada pelo shell com comandos padrão:

%pre%

Você pode aplicar as transformações desejadas e convertê-las novamente em um arquivo com awk ' printf("%c") .

Isso vai ser muito ineficiente.

Como:

%pre%

Você pode usar od -An -vtu2 , para obter números de 16 bits, mas observe que está no endianness local, portanto, ao converter de volta para os caracteres, você deve levar isso em conta.

    
por 19.06.2013 / 12:06
2

Você não pode usar terminadores nulos na maioria das variáveis do shell (ou melhor, você pode, mas eles serão terminados como, em geral, eles são armazenados como tal), então isso é uma grande limitação de qualquer leitura binária. / p>

Se você tiver xxd :

xxd -b | awk '{ for(i=2 ; i<=NF-1 ; i++) { print $i } }'

Por exemplo:

echo -n mayonnaise | xxd -b | awk '{ for(i=2 ; i<=NF-1 ; i++) { print $i } }'
01101101
01100001
01111001
01101111
01101110
01101110
01100001
01101001
01110011
01100101
    
por 19.06.2013 / 12:05
2

Eu usei essa função muito crua para x dois arquivos de 128 bytes:

one_time_pad() {
    asrc="$1"
    bsrc="$2"
    dst="$3"

    atmp="'mktemp'"
    btmp="'mktemp'"

    hexdump -v -e '1/1 "%02x" " "' "$asrc" > "$atmp"
    hexdump -v -e '1/1 "%02x" " "' "$bsrc" > "$btmp"

    rm "$dst"
    touch "$dst"

    for i in 'seq 1 128'
    do
        a='awk '{print $'$i';}' < "$atmp"'
        b='awk '{print $'$i';}' < "$btmp"'

        echo -n -e '\x''printf "%x" $((0x$a^0x$b))' >> "$dst"
    done
}

one_time_pad in1 in2 out

Em termos de desempenho, isso é totalmente horrível (está chamando awk duas vezes para cada byte!). No meu caso, o desempenho simplesmente não era um problema. Tenho certeza que você pode encontrar uma maneira muito melhor.

    
por 19.06.2013 / 15:58