Como codificar / decodificar o arquivo JPG para a sequência int?

0

Eu sou um iniciante no shell script e quero converter meus arquivos JPG em int sequencias e depois reconverter para obter as imagens novamente.

Meu script.sh é assim:

FILE=$(cat $2)
TOTAL=$(echo ${#FILE} - 1 | bc);
for j in $(seq 0 $TOTAL)
do
    printf "%d " "'${FILE:j:1}" >> sai.out
done

Parece que está funcionando bem. Então sai.out recebe algo como 32767 32767 32767 32767 16 74 70 73 70 1 1 1 1 32767 32767 67 8 ... .

Com o mesmo código, mas digitando um arquivo de texto, a decodificação é fácil pela tabela ASCII e imprimindo %c .

O problema é: como posso obter o arquivo de imagem novamente a partir do meu arquivo sai.out ?

    
por eightShirt 17.09.2017 / 03:10

3 respostas

4

POSIXly:

od -An -vtu1 < file > file.encoded

Em que cada e e v ery byte do arquivo é codificado como um número decimal u nsigned, com n o A ddress.

Para decodificar, com algumas implementações awk (aquelas como gawk ou mawk onde printf("%c", 0) funciona):

awk '{for (i = 1; i <= NF; i++) printf "%c", $i}' < file.encoded > file

Algumas notas sobre por que sua abordagem não funciona:

  • shells diferentes de zsh não podem armazenar dados arbitrários (especialmente o byte NUL) em suas variáveis.
  • e substituição de comando em shells do tipo Bourne, arrastando caracteres de nova linha (0xa bytes na maioria dos sistemas)
  • você precisa citar variáveis em shells semelhantes a Bourne que não sejam zsh
  • Em shells que têm o operador ${var:offset:length} ksh93 ( ksh93 , bash , zsh , mksh ), offset e length são expressos em número de caracteres, não bytes ( No entanto, o UTF-8 é a única codificação de caracteres de múltiplos bytes suportada por mksh e somente quando a opção utf8-mode está ativada).
  • printf %d \'x retorna o número do código do caractere. Isso é apenas o valor de byte em conjuntos de caracteres de byte único. Aqui, você provavelmente está usando bash e está em uma localidade usando a codificação UTF-8 como bash ' printf fornece valores aleatórios para bytes que não fazem parte de caracteres válidos lá .
  • o texto é definido como sequências de linhas de texto, elas próprias sequências de caracteres não-NUL (limitadas a seqüências de bytes formando caracteres válidos) cujo tamanho (em número de bytes incluindo o caractere de nova linha) não excede LINE_MAX (consulte getconf LINE_MAX ) e é delimitado por um caractere de nova linha. Então, exceto para arquivos jpg muito pequenos, seu sai.out acabaria não sendo texto válido e você não teria garantia de que seria processado corretamente por utilitários de texto ( od aqui gera apenas alguns números por linha).
por 17.09.2017 / 08:36
3

Se hex é uma representação inteira válida, xxd faz o trabalho para você:

xxd -p image.jpg > image.hex

E, para reverter para uma imagem:

xxd -p -r image.hex > image-copy.jpg
    
por 17.09.2017 / 03:48
0

Minha resposta é baseada na dica de Arrow. Eu não sou especialista em sed , então acredito em uma solução melhor do que isso, mas funciona por enquanto.

A estratégia foi converter meu arquivo em hexadecimal com xxd e depois converter o hex a int.

Codificar:

xxd -p $1 | sed 's/.\{2\}/& /g' | sed 's/[^ ]* */0x&/g' | awk '{ for(i=1;i<=NF;i++) printf("%i ",$i); print ""; }' > $2

Decodificar:

awk '{ for(i=1;i<=NF;i++) printf("%02x ",$i); print ""; }' $IN > $OUT
xxd -p -r $OUT $OUT_IMAGE_NAME.jpg
rm $OUT
    
por 17.09.2017 / 06:21