파일 확장자가없는 데이터 파일 을 찾은 문제를 해결하고있었습니다 . 이 file
명령은임을 나타냅니다 data file (application/octet-stream)
. 이 hd
명령은 GNP를 보여줍니다 . 마지막 줄에. 따라서이 파일을 뒤집 으면 .PNG 형식 파일을 얻습니다 . 모든 곳을 검색했지만 바이너리 파일의 내용을 뒤집는 방법을 설명하는 솔루션을 찾지 못했습니다.
파일 확장자가없는 데이터 파일 을 찾은 문제를 해결하고있었습니다 . 이 file
명령은임을 나타냅니다 data file (application/octet-stream)
. 이 hd
명령은 GNP를 보여줍니다 . 마지막 줄에. 따라서이 파일을 뒤집 으면 .PNG 형식 파일을 얻습니다 . 모든 곳을 검색했지만 바이너리 파일의 내용을 뒤집는 방법을 설명하는 솔루션을 찾지 못했습니다.
답변:
로 xxd
(에서 vim
) 및 tac
(GNU의로 coreutils에서, 또한 tail -r
일부 시스템) :
< file.gnp xxd -p -c1 | tac | xxd -p -r > file.png
에서 zsh
(유일한 고려해야하려는 경우가 아니면 내부적으로 (바이너리 데이터를 처리 할 수있는 쉘 접근 방식을 인코딩하는 경우 ksh93의 64 기수 )) :
zmodload zsh/mapfile
(LC_ALL=C; printf %s ${(s::Oa)mapfile[file.gnp]} > file.png)
LC_ALL=C
: 문자는 바이트입니다$mapfile[file.gnp]
: file.gnp
파일 내용s::
: 문자열을 바이트 구성 요소로 분할Oa
: 해당 배열의 rray 아래 첨자 O
에 리버스 rdera
zsh
이진 데이터를 처리 할 수있는 유일한 쉘은 아닙니다.
다음을 사용하여 이진 파일을 되 돌리는 한 가지 방법이 ksh93
있습니다. 이해하기 쉽도록 코드를 "느슨하게"남겨 두었습니다.
#!/bin/ksh93
typeset -b byte
redirect 3< image.gpj || exit 1
eof=$(3<#((EOF)))
read -r -u 3 -N 1 byte
printf "%B" byte > image.jpg
3<#((CUR - 1))
while (( $(3<#) > 0 ))
do
read -r -u 3 -N 1 byte
printf "%B" byte >> image.jpg
3<#((CUR - 2))
done
read -r -u 3 -N 1 byte
printf "%B" byte >> image.jpg
redirect 3<&- || echo 'cannot close FD 3'
exit 0
read
위 의 첫 번째 파일은 파일 끝에서 수행 된대로 아무것도 읽지 않아야합니다.
strace
하고 ksh93
이 파일 내에서 여기 저기를 추구하고, 한 번에 많은 양을 읽어 경우, 매우 이상하게 행동 것으로 보인다. 아마 github.com/att/ast/issues/15
strace
내가 의미하는 바를 보려면 스크립트를 사용해보십시오 . ksh93
파일을 수천 번 이상 읽습니다. 예를 들어, 첫 번째 바이트를 읽기 전에 파일 끝에서 64KiB를 찾고 64KiB를 읽은 다음 마지막 바이트 전에 찾고 1 바이트를 읽고 모든 바이트에 대해 비슷한 작업을 수행합니다. base64로 인코딩 된 문자열로 수행 할 수있는 작업은 제한되어 있으므로 한 번에 두 바이트 이상을 읽으면 개별 바이트를 추출하기가 더 어려워집니다.
펄로 :
perl -0777pe '$_=reverse $_' [input_file]
성능 테스트:
dd if=/dev/urandom of=/tmp/a bs=1M count=1
LC_ALL=C tac -rs $'.\\|\n' /tmp/a > /tmp/r
time perl -0777pe '$_=reverse $_' /tmp/a | diff -q - /tmp/r
time xxd -p -c1 /tmp/a | tac | xxd -p -r | diff -q - /tmp/r
time perl -0777 -F -ape '$_=reverse@F' /tmp/a | diff -q - /tmp/r
time LC_ALL=C tac -rs $'.\\|\n' /tmp/a | diff -q - /tmp/r
결과:
참고 : diff
출력이 동일해야하므로 모든 솔루션에 대해 실행 시간 이 동일해야합니다.
perl
것을 삭제했습니다 . 당시에는 reverse
문자열을 뒤집을 수도 있다는 것을 알지 못했기 때문에 분할하는 것이 의미가 없으며 버전이 훨씬 좋습니다.
나는 다음을 시도했다.
tac -rs '.' input.gnp > output.png
아이디어는 문자를 구분 기호로 사용하여 'tac'을 강제하는 것입니다. 바이너리 파일에서 시도했지만 작동하는 것처럼 보였지만 확인을 부탁드립니다.
주요 이점은 파일을 메모리에로드하지 않는다는 것입니다.
tac
입력에 줄 바꿈 문자가 포함되어 있으면 (여기서는 GNU 8.28에서) 작동하지 않습니다 . 대신 printf '1\n2' | tac -rs . | od -vAn -tc
출력 . 멀티 바이트 문자 가 필요 하거나 일치 할 수도 있습니다 . \n 2 1
2 \n 1
LC_ALL=C
.
LC_ALL=C tac -rs $'.\\|\n'
그래도 작동하는 것 같습니다.