긴 대답

긴 대답
if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt
fi

기본적으로 "out.txt" 파일에 파일의 아무 곳에나 "�"가 포함되어 있으면 "WORK"를 에코하고, "out.txt" 파일에 파일의 어느 곳에도 "�"가 포함되어 있지 않으면 다음을 원합니다. 고양이를 쫓아내다.txt

편집: 이것이 내가 하는 일입니다. 무차별 대입 OpenSSL 암호 해독을 시도하고 있습니다.

openssl enc는 성공 시 0을 반환하고, 그렇지 않으면 0이 아닌 값을 반환합니다. 참고: AES/CBC는 올바른 패딩을 기반으로 "암호 해독이 유효한지"만 확인할 수 있으므로 오탐지가 발생합니다. 따라서 파일은 해독되지만 올바른 비밀번호가 아니므로 횡설수설이 포함됩니다. 왜곡된 문자의 일반적인 문자는 "�"입니다. 따라서 출력에 "�"가 포함되어 있으면 do 루프를 계속 진행하고 싶습니다.

이것은 내 자식 링크입니다https://github.com/Raphaeangelo/OpenSSLCracker 이게 스크립트야

while read line
do
openssl aes-256-cbc -d -a -in $1 -pass pass:$line -out out.txt 2>out.txt >/dev/null && printf "==================================================\n"
if grep -q "�" out.txt
    then
        :
    else
        cat out.txt &&
            printf "\n==================================================" &&
            printfn"\npassword is $line\n" &&
            read -p "press return key to continue..." < /dev/tty; 
fi
done < ./password.txt

여전히 � 문자가 포함된 출력이 표시됩니다.

답변1

grep작업에 적합한 도구가 아닙니다.

당신은 그것을 보았다U+FFFD REPLACEMENT CHARACTER파일 내용에 실제로 존재하기 때문이 아니라 텍스트 기반 입력만 처리하는 도구를 사용하여 바이너리 파일을 보고 있기 때문입니다. 유효하지 않은 입력(예: 임의의 이진 데이터)을 처리하는 표준 방법은 화면에 들어가기 전에 현재 로케일(대부분 UTF-8)에서 유효하지 않은 모든 항목을 U+FFFD로 바꾸는 것입니다.

\xEF\xBF\xBD이는 리터럴 (U+FFFD 문자의 UTF-8 바이트 시퀀스) 이 파일에 나타나지 않을 가능성이 높다는 것을 의미합니다. grep아니오라고 말하는 것이 절대적으로 옳습니다.

파일에 알 수 없는 바이너리가 포함되어 있는지 감지하는 한 가지 방법은 다음 file(1)명령을 사용하는 것입니다.

$ head -c 100 /dev/urandom > rubbish.bin
$ file rubbish.bin
rubbish.bin: data

알 수 없는 파일 형식의 경우 간단히 dataTry 이라고 표시됩니다.

$ file out.txt | grep '^out.txt: data$'

파일에 실제로 임의의 바이너리가 포함되어 있는지 확인하십시오. 따라서 가비지일 가능성이 높습니다.

UTF-8로 인코딩된 텍스트 파일 인지 확인하려면 out.txt다음을 사용할 수도 있습니다 iconv.

$ iconv -f utf-8 -t utf-16 out.txt >/dev/null

답변2

간단히 말해서:

grep -axv '.*' out.txt 

긴 대답

현재 답변은 모두 매우 오해의 소지가 있으며 기본적으로 잘못되었습니다.

테스트하려면 다음 두 파일을 받으세요(높은 평가를 받는 개발자인 Markus Kuhn으로부터).

$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt

데모

첫 번째 UTF-8-demo.txt파일은 UTF-8이 다양한 언어, 수학, 점자 및 기타 유용한 문자 유형을 얼마나 잘 렌더링할 수 있는지 보여주기 위한 것입니다. utf-8을 이해하는 텍스트 편집기를 사용하여 살펴보면 많은 예제와아니요 .

한 가지 답변에서는 테스트를 제안합니다. 문자 범위를 로 제한하면 \x00-\x7F파일의 거의 모든 내용이 거부됩니다.
이것은 매우 잘못된 것입니다파일에 아무것도 없기 때문에 아무것도 삭제되지 않습니다.

이 답변에서 권장하는 테스트를 사용하면 72.5 %파일이 삭제됩니다.

$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058

이것은 (가장 실용적인 목적으로) 전체 파일입니다. 완전히 유효한 문자를 표시하는 잘 설계된 파일입니다.

시험

두 번째 파일은 UTF-8 리더가 제대로 작동하는지 확인하기 위해 여러 가지 극단적인 경우를 시도하도록 설계되었습니다. 여기에는 "�"이 표시되는 문자가 많이 포함되어 있습니다. 그러나 file이 파일에 대해 사용할 다른 답변 제안(선택한 답변)은 끔찍하게 실패합니다. 0바이트( \0)(기술적으로 유효한 ASCII)와 \x7f바이트(DEL - 삭제)(분명히 ASCII 문자도 삭제)를 삭제하세요.모두이 파일은 file다음 명령에 유효합니다.

$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt 
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators

file감지 할 수 없을 뿐만 아니라많은잘못된 문자이지만 UTF-8로 인코딩된 파일임을 감지하고 보고할 수 없습니다.

예, fileUTF-8로 인코딩된 텍스트를 감지하고 보고할 수 있습니다.

$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text

또한 file1~31 범위의 대부분의 제어 문자는 ASCII로 보고될 수 없습니다. ( file)는 특정 범위를 다음과 같이 보고합니다 data.

$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data

기타 ASCII text:

$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text

인쇄 가능한 문자 범위(개행 포함):

$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text

그러나 특정 범위에서는 이상한 결과가 발생할 수 있습니다.

$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655

이 프로그램은 file텍스트를 감지하는 도구가 아닙니다.마법실행 가능한 프로그램이나 파일 내의 숫자입니다.

내가 찾은 감지 범위 file와 해당 보고서 유형은 다음과 같습니다.

  • 1바이트 값(주로 ASCII):

    {1..6} {14..26} {28..31} 127   :data
    {128..132} {134..159}          :Non-ISO extended-ASCII text
    133                            :ASCII text, with LF, NEL line terminators
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {160..255}                     :ISO-8859 text
    
  • UTF-8 인코딩 범위:

    {1..6} {14..26} {28..31} 127   :data
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {128..132} {134..159}          :UTF-8 Unicode text
    133                            :UTF-8 Unicode text, with LF, NEL line terminators
    {160..255}                     :UTF-8 Unicode text
    {256..5120}                    :UTF-8 Unicode text
    

한 가지 가능한 해결책은 다음과 같습니다.


이전 답변.

게시한 문자의 유니코드 값은 다음과 같습니다.

$ printf '%x\n' "'�"
fffd

응 그거 하나야유니코드 문자 '대체 문자'(U+FFFD). 모든 문자를 대체하는 데 사용되는 문자입니다.유효하지 않은텍스트에 유니코드 문자가 있습니다. 실제 캐릭터라기보다는 '시각적 보조물'이다. 유효하지 않은 콘텐츠가 포함된 모든 전체 행을 찾아서 나열합니다.유니코드사용된 캐릭터:

grep -axv '.*' out.txt 

그러나 유효하지 않은 문자가 있는지 검색하려면 다음을 사용하세요.

grep -qaxv '.*' out.txt; echo $?

결과가 1파일이 깨끗 하면 0입니다 0.


문자를 찾는 방법을 묻는 경우 다음을 사용하세요.

➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)

또는 시스템이 UTF-8 텍스트를 올바르게 처리하는 경우 다음을 수행하십시오.

➤ echo "$a" | grep -oP '�'

답변3

이 초기 답변은 원래 게시물에 대한 응답입니다.

Bash 스크립트에서 유니코드를 grep하는 방법

if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt  fi

기본적으로 "out.txt" 파일에 파일의 아무 곳에나 "�"가 포함되어 있으면 "WORK"를 에코하고, "out.txt" 파일에 파일의 어느 곳에도 "�"가 포함되어 있지 않으면 다음을 원합니다. 고양이를 쫓아내다.txt

노력하다

grep -oP "[^\x00-\x7F]"

성명은 if .. then다음과 같습니다 :

if grep -oP "[^\x00-\x7F]" file.txt; then
    echo "grep found something ..."
else
    echo "Nothing found!"
fi

설명하다

답변4

인코딩 변환을 수행하는 도구 "iconv"와 원시 바이너리를 16진수로 변환하는 "xxd" 도구를 사용하여 이 문제를 해결할 수 있었습니다. 쉘이 추가 논리를 포함하지 않고 실제 유니코드 문자 코드 포인트를 확인할 수 있도록 파일을 UTF-32 BE(빅엔디안) 바이트 스트림으로 변환합니다.

이 예제 요청은 파일에서 단일 유니코드 문자의 존재만 감지합니다. 문자가 \u1234abcd(잘못되었지만 이는 단지 예일 뿐임) 이라고 가정해 보겠습니다 .

# iconv does its best to detect the encoding and convert it to UTF-32 BE
iconv -t utf32be out.txt | \
# xxd turns the raw binary into hex digits and some new lines.
# The '-g 1' attempts to avoid local computer endian-ness by grouping 1
# byte at a time.  It may not be necessary.
xxd -g 1 -R never -ps | \
# 'tr' strips out whitespace generated by 'xxd'.
tr -d '\r\n ' | \
# Loop over each 8 hex digit character.
# This causes the shell to read the input stream
# 8 characters at a time which, if everything above
# went right, is limited to 0-9 and a-f.  LANG=C
# just enforces 1 byte at a time.
while IFS='' LANG=C read -r -d '' -n 8 char ; do
  if [ "${char}" = "1234abcd" ] ; then
    echo "working"
    # No need to scan any other character.  Exit early.
    break
  fi
done

주요 질문과 달리 위 답변은 찾을 수 없는 경우 후속 실행을 수행하지 않습니다 cat out.txt. 이를 위해서는 내부 실행 외부에서 발견된 상태를 전달해야 합니다. 나의 일반적인 접근 방식은 파일이 존재하는 경우 표시하는 것입니다. 일부 진취적인 사람은 하위 프로세스와 종료 코드를 사용하여 grep과 유사한 접근 방식을 찾을 수도 있습니다.

# Create the marker file.
marker="$( mktemp )"

iconv -t utf32be out.txt | \
xxd -g 1 -R never -ps | \
tr -d '\r\n ' | \
while IFS='' LANG=C read -r -d '' -n 8 char ; do
  if [ "${char}" = "1234abcd" ] ; then
    echo "working"
    # Mark that it was found by removing the temporary file.
    rm "${marker}"
    break
  fi
done

# If the marker file exists, then it wasn't found in the loop.
if [ -f "${marker}" ] ; then
  rm "${marker}"
  cat out.txt
fi

16진수만 생성하고 엔디안 변환을 피하도록 매우 주의한다면 "xxd" 대신 "od" 또는 "hexdump"를 사용할 수 있습니다.

"xxd"는 원본 데이터를 반환하는 역방향 기능을 제공한다는 장점이 있습니다. "echo -e "\xAf"" 스타일 출력을 사용하여 동일한 작업을 수행할 수 있지만 이를 위해서는 구문 분석된 각 문자에 대해 새로운 에코 패스를 생성해야 합니다.

나는 이것을 넣었다주요 요점이는 출력을 UTF로 인코딩된 스트림으로 재조립하는 방법을 포함하여 더 큰 예제를 통해 설명됩니다.

관련 정보