Temukan file yang dapat dibaca manusia


14

Saya mencoba menemukan cara yang efisien untuk melakukan level 5 dari tantangan bandit OverTheWire .

Lagi pula, saya punya banyak file, dan hanya ada satu yang menghormati kriteria berikut:

  • Dapat dibaca oleh manusia
  • Berukuran 1033 byte
  • Tidak dapat dieksekusi

Saat ini, saya menggunakan findperintah, dan saya dapat menemukan file yang cocok dengan 2 kriteria terakhir:

find . -size 1033c ! -executable

Namun, saya tidak tahu bagaimana cara mengecualikan file yang tidak dapat dibaca manusia. Solusi yang saya temukan untuk tantangan itu menggunakan -readableparameter uji, tapi saya rasa ini tidak berhasil. -readablehanya melihat izin file, dan bukan pada isinya, sedangkan deskripsi tantangan meminta file ASCII atau sesuatu seperti itu.


1
Bagaimana Anda mendefinisikan dibaca manusia? Bukan biner?
terdon

2
file command is your friend :)
Romeo Ninov


3
Manusia adalah salah satu spesies paling dikenal di dunia. Mereka juga satu-satunya yang dikenal berpengalaman dengan komputer. Mereka dapat membaca sebagian besar file asalkan mereka dapat mengetahui jenis dan mendapatkan kunci enkripsi untuk yang terenkripsi.
Stéphane Chazelas

1
PERINGATAN SPOILER !!
Dan Bolser

Jawaban:


17

Ya, Anda dapat menggunakan finduntuk mencari file yang tidak dapat dieksekusi dengan ukuran yang tepat dan kemudian gunakan fileuntuk memeriksa ASCII. Sesuatu seperti:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

Namun, pertanyaannya tidak sesederhana kedengarannya. 'Dapat dibaca manusia' adalah istilah yang sangat tidak jelas. Agaknya, maksud Anda teks. OK, tapi teks seperti apa? Hanya karakter Latin ASCII? Unicode penuh? Sebagai contoh, perhatikan tiga file ini:

$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo

Ini semua adalah teks dan dapat dibaca manusia. Sekarang, mari kita lihat apa yang filemembuat mereka:

$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX shell script, ASCII text executable

Jadi, findperintah di atas hanya akan menemukan file1(demi contoh ini, mari kita bayangkan file-file tersebut memiliki 1033 karakter). Anda dapat memperluas finduntuk mencari string text:

find . -type f -size 1033c ! -executable -exec file {} + | grep -w text

Dengan -w, grephanya akan mencetak garis-garis di mana textditemukan sebagai kata yang berdiri sendiri. Itu seharusnya cukup dekat dengan apa yang Anda inginkan, tetapi saya tidak dapat menjamin bahwa tidak ada jenis file lain yang uraiannya mungkin juga menyertakan string text.


4

Meskipun -execsebagian besar digunakan untuk melakukan sesuatu dengan file-file yang ditemukan, itu juga dapat bertindak sebagai tes. Karena itu, kami dapat menambahkannya ke kriteria Anda yang lain:

find . \
  -size 1033c \
  -not -executable \
  -exec sh -c 'file {} | grep "text$"' \;

Ingat, grepkembalikan bukan nol ketika pola tidak ditemukan, dan sh -c "COMMAND"akan mengembalikan hasil evaluasi (asalkan valid). Jadi ini hanya akan mencetak file di mana file <filename>meludahkan sesuatu yang berakhir dengan text, misalnya "teks UTF-8 Unicode` atau" teks ASCII ", tetapi bukan" Teks non-ISO extended-ASCII, dengan urutan pelarian ".

Dalam satu baris, bahkan berakhir lebih pendek daripada melewati xargs:

find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;

Ingatlah bahwa Anda dapat mengganti sh -c 'file {} | grep "text$"'dengan perintah khusus apa pun. Jika Anda ingin memeriksa sesuatu yang sangat kompleks, mungkin ide yang lebih baik untuk menyediakan skrip shell dan menggunakannya:

find . -size 1033c -not -executable -exec is_human_readable.sh {} \;

yang, dalam jangka panjang, lebih mudah dipertahankan daripada riwayat shell Anda:

#!/bin/sh
file "$@" | grep "text$" > /dev/null

Bagus! Namun, perhatikan bahwa pencocokan text$akan mengecualikan hal-hal yang dikenali sebagai skrip shell. Apa pun dengan shebang diidentifikasi sebagai skrip, dan itu bisa dibaca manusia.
terdon

@terdon benar, tetapi skrip cenderung dapat dieksekusi: D. Karena itu, skrip yang tepat juga harus mengenali PDF. Tetapi di sisi lain, apakah PDF berisi gambar yang dapat dibaca manusia ? Apakah PNG dari beberapa teks dapat dibaca ? Mungkin. Saya kira tes yang lengkap akan ... menantang.
Zeta


1

Anda hanya perlu menggunakan:

find inhere -size 1033c

Ini akan memberi Anda satu-satunya file yang berisi kata sandi.


mengapa + 1033c mengembalikan lebih banyak file? Apakah itu seperti tanda-lebih besar atau sama?
szeitlin

1

Jalankan saja berikut ini terhadap isi direktori:

$ file -- *
-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data
$ cat -- \-file07
<output>

0
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: '{print $1}'

Silakan coba perintah gabungan ini. ini bekerja di stasiun saya.


0

Anda bisa mencoba ini

find . -size 1033c ! -executable -exec file {} +

Tantangan Anda tidak memungkinkan grep. file kata sandi akan dilaporkan sebagai "teks ASCII, dengan garis yang sangat panjang"


0

Untuk memfilter nama file yang dapat dibaca manusia, Anda dapat menggunakan nama kelas karakter[:print:] (yang dapat dicetak ) . Anda akan menemukan lebih banyak tentang kelas-kelas tersebut di manual untuk .grep

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

Setelah dipikir-pikir, persyaratan "yang dapat dibaca manusia" mungkin merujuk pada konten file, alih-alih namanya. Dengan kata lain, Anda akan mencari file teks . Itu sedikit lebih rumit. Seperti yang disarankan @D_Bye dalam komentar, Anda harus menggunakan fileperintah untuk menentukan tipe konten file. Tetapi itu bukan ide yang baik untuk dijalankan filesetelah pipa, karena itu akan menyulitkan tugas menampilkan nama file. Inilah yang saya sarankan:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

Ini adalah singkat bagaimana file-bagian bekerja:

  • The -execpredikat mengeksekusi sh -c 'file -b $0 | grep -q text' FILENAMEuntuk setiap FILENAMEyang memenuhi semua kondisi sebelumnya (jenis, ukuran, non-executable).
  • Untuk masing-masing file, shell ( sh) berjalan singkat ini naskah : file -b $0 | grep -q text, mengganti $0dengan nama file.
  • The fileProgram menentukan jenis konten setiap file dan output informasi ini. The -bmencegah opsi mencetak nama setiap file diuji.
  • grepmemfilter output yang berasal dari fileprogram, mencari baris yang berisi "teks" . (Lihat sendiri, bagaimana output khas dari fileperintah terlihat.)
  • Tetapi greptidak menampilkan teks yang difilter, karena ia memiliki opsi -q(sunyi) yang diberikan. Apa yang dilakukannya, hanya mengubah status keluarnya menjadi 0(yang mewakili "benar" - teks yang difilter ditemukan) atau 1 (artinya "kesalahan" - teks "teks" tidak muncul di keluaran dari file).
  • Status keluar benar / salah berasal dari grepditeruskan oleh shke finddan bertindak sebagai hasil akhir dari seluruh " -exec sh -c 'file $0 | grep -q text' {} \;" tes.
  • Dalam hal pengujian di atas dikembalikan benar , -printperintah dijalankan (yaitu nama file yang diuji dicetak).

0
bandit4@bandit:~$ ls
inhere

bandit4@bandit:~$ file inhere/*


inhere/-file00: data
inhere/-file01: data
inhere/-file02: data
inhere/-file03: data
inhere/-file04: data
inhere/-file05: data
inhere/-file06: data
inhere/-file07: ASCII text
inhere/-file08: data
inhere/-file09: data

bandit4@bandit:~$ pwd 

/home/bandit4

bandit4@bandit:~$ cat /home/bandit4/inhere/-file07

koReBOKuIDDepwhWk7jZC0RTdopnAYKh
bandit4@bandit:~$ 

Cukup gunakan file inhere / * dan cat / home / bandit4 / inhere / -file07

0
find  -type f ! -executable -size 1033c

akan memberi Anda file dari latihan



0

Saya pikir cara yang lebih lama untuk menemukan kata sandi untuk level bandit ini yang disebutkan oleh sebagian besar di atas menggunakan find dan grep adalah perintah yang paling deskriptif.

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

Tapi, setelah menggunakan perintah 'file' lebih saya menyadari cukup mudah untuk menemukan file yang dapat dibaca manusia (alias ASCII di tingkat ini) dengan cara ini dengan memeriksa seluruh jenis file direktori. Direktori inhere menyimpan file dengan nama '-filexx' atau dengan cepat memeriksa seluruh direktori inherefile ./*

Inilah pendekatan saya.

bandit4@bandit:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data

bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

-2
du --human-readable | find -not -executable -size 1033c

akan mendapatkan hasil Anda

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.