sha1sum untuk direktori direktori

33
sha1sum ./path/to/directory/* | sha1sum 

di atas telah diposting sebagai cara untuk menghitung sha1sum dari direktori yang berisi file. Perintah ini gagal jika direktori menyertakan lebih banyak direktori. Apakah ada cara untuk secara rekursif menghitung sha1sum dari direktori direktori secara universal (tanpa penyesuaian kustom algoritma ke direktori tertentu yang bersangkutan)?

Ocasta Eshu
sumber

Jawaban:

14

Berkat posting SO ini -

find . -type f \( -exec sha1sum "$PWD"/{} \; \) | sha1sum

Peringatan: Kode ini tidak diuji ! Edit pertanyaan ini jika salah dan Anda dapat memperbaikinya; Saya akan menyetujui hasil edit Anda.

allquixotic
sumber
Maaf; Saya tidak bisa menolak! ;-) Rekursi itu menyenangkan. Tentu ada caranya. Saya akan menulis jawaban yang tepat sekarang.
allquixotic
3
Ini tidak akan menghasilkan hash yang sama untuk folder yang sama persis pada mesin yang berbeda karena output juga berisi <hash> dan <file path> yang path file berbeda pada mesin yang berbeda dan menyebabkan hash berbeda pada mesin yang berbeda. Baris yang benar harus seperti find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
alper
1
Selain itu, hash file harus diurutkan yang juga akan menyebabkan hash yang berbeda jika urutannya berbeda pada mesin yang berbeda.
alper
40

Saya biasanya menyukai pola "find | xargs", seperti:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

Anda harus menggunakan "-print0" dan "-0", jika ada spasi dalam nama file.

Namun, ini sangat mirip dengan pola "find -exec cmd {}".

Lihat diskusi yang membandingkan kedua pola di sini: https://stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs

Matthew Bohnsack
sumber
Jawaban Anda hanya mengembalikan hash file. Hash folder harus diperoleh dengan menggunakan find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum.
alper
5

UPDATE: Sudah beberapa tahun sejak saya memposting balasan ini dan sementara itu saya telah menulis ulang dan memperbaiki skrip yang telah saya presentasikan di sini beberapa kali. Saya telah memutuskan untuk mengirim ulang skrip baru sebagai jawaban baru. Saya akan sangat merekomendasikan ini.

PENGANTAR

Saya telah mengamati bahwa urutan di mana perintah find mengeluarkan elemen-elemen yang ditemukan dalam direktori bervariasi dalam direktori yang identik pada partisi yang berbeda. Jika Anda membandingkan hash dari direktori yang sama, Anda tidak perlu khawatir tentang hal itu tetapi jika Anda mendapatkan hash untuk memastikan bahwa tidak ada file yang terlewat atau rusak selama salinan, Anda harus menyertakan baris tambahan untuk menyortir konten direktori dan elemen-elemennya. Misalnya, jawaban Matthew Bohnsack cukup elegan:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

Tetapi jika Anda menggunakannya untuk membandingkan direktori yang disalin dengan aslinya, Anda akan mengirim output ke file txt yang akan Anda bandingkan dengan daftar yang dihasilkan dari direktori lain menggunakan Kompare atau WinMerge atau dengan hanya mendapatkan hash dari setiap lis . Masalahnya adalah, karena urutan di mana alat menemukan akan menampilkan konten dapat bervariasi dari satu direktori ke yang lain, Kompare akan memberi sinyal banyak perbedaan karena hash tidak dihitung dalam urutan yang sama. Bukan masalah besar untuk direktori kecil tetapi cukup menjengkelkan jika Anda berurusan dengan 30000 file. Oleh karena itu, Anda telah melakukan langkah-langkah tambahan untuk menyortir output agar lebih mudah membandingkan daftar hash antara dua direktori.

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum > sha1sum_list_unsorted.txt
sort sha1sum_list_unsorted.txt > sha1sum_list_sorted.txt

Ini akan mengurutkan output sehingga file dengan hash yang sama akan berada di baris yang sama ketika menjalankan program differencing (asalkan tidak ada file yang hilang direktori baru).

DAN KE ATAS SCRIPT ...

Berikut skrip yang saya tulis. Ia melakukan hal yang sama dengan jawaban find / xarg tetapi akan mengurutkan file sebelum mendapatkan sha1sum (menyimpannya di direktori yang sama). Baris pertama skrip menemukan semua file dalam direktori secara rekursif. Yang berikutnya mengurutkan hasil secara alfabet. Dua berikut, mengambil konten yang diurutkan dan menambahkan sha1sum dan tanda kutip ke file dalam daftar yang diurutkan, membuat skrip shell besar yang menghitung hash setiap file, satu per satu dan menampilkannya ke content_sha1sum.txt.

#!/bin/bash
find . -type f > content.txt
sort content.txt > content_sorted.txt
awk '{print "sha1sum \""$0}' content_sorted.txt > temp.txt
awk '{print $0"\""}' temp.txt > get_sha1.sh
chmod +x get_sha1.sh
./get_sha1.sh > content_sha1sum.txt
rm content.txt
rm content_sorted.txt
rm temp.txt
rm get_sha1.sh
xdg-open content_sha1sum.txt

Semoga ini membantu.

aturan kebun
sumber
Ketika panjang total semua nama file sesuai dengan baris perintah, pemipaan melalui sort -z( --zero-terminated) lebih mudah daripada mengacaukan banyak file.
Anton Samsonov
@AntonSamsonov Ini adalah skrip yang sangat lama, saya baru belajar skrip pada saat itu. Sejak itu saya menulis ulang beberapa kali. Berkenaan dengan komentar Anda apa penghentian nol lakukan ketika menyortir: Saya membaca halaman manual semacam itu. Mereka mengatakan nol mengakhiri tongkat nol byte di akhir baris, bukan baris baru. Apa yang dilakukan itu?
thebunnyrules
Saya telah mengirim pembaruan ke skrip ini sebagai jawaban terpisah di sini: superuser.com/questions/458326/…
thebunnyrules
4

PENGANTAR

Beberapa tahun yang lalu, saya menulis dan menyajikan (dalam utas ini) sebuah skrip yang dapat memeriksa tanda tangan hash dari semua file individu dalam struktur direktori saat ini dan menampilkannya sebagai daftar dalam file teks.

Sejak itu, saya telah memperbaiki formula ini beberapa kali. Saya memutuskan untuk mengirim ulang skrip saya yang baru dan lebih baik di sini sebagai jawaban terpisah. Ini ditulis untuk sha256 tetapi siapa pun yang masih ingin menggunakan sha1 dapat melakukan pencarian sederhana dan ganti di gedit untuk menukar sha256 dengan sha1. Secara pribadi, saya belum pernah menggunakan sha1 selama beberapa tahun dan saya tidak akan merekomendasikannya karena sudah kuno dan google telah menunjukkan bagaimana hal itu dapat dikompromikan .

Inilah yang dilakukan skrip baru saya:

  1. Anda cukup menggunakan skrip dengan masuk ke direktori yang ingin Anda hash dan masukkan:

    sha256rec

    Atau, Anda dapat memanggil skrip ini dari direktori lain dengan melakukan:

    sha256rec "/path/to/target/directory/you/want/hash"
  2. Script akan mendeteksi jika Anda memiliki hak istimewa menulis dalam direktori saat ini. Jika Anda melakukannya, hasilnya akan disimpan di direktori saat ini. Jika Anda tidak memiliki hak istimewa menulis atau jika direktori Anda saat ini berada dalam sistem read-only (seperti cdrom), hasilnya akan disimpan ke direktori home pengguna saat ini.

  3. Script akan mendeteksi jika beberapa sub direktori tidak dapat diakses pada hak pengguna saat ini. Jika semua dapat dibaca maka tidak ada peningkatan hak istimewa yang terjadi, jika tidak, maka hak pengguna akan ditingkatkan ke root.

  4. Find digunakan untuk menemukan semua file dalam struktur dir saat ini (termasuk semua sub-direktori). Sortir digunakan untuk memastikan hasil yang dikeluarkan sesuai abjad. Daftar yang dihasilkan mengalami sha256sum dan dikeluarkan ke file teks.

  5. Sejak menulis skrip lama saya telah mengadopsi filosofi desain bahwa file temp adalah jahat dan harus dihindari bila memungkinkan karena mereka membiarkan pengguna terbuka untuk mengintip dan merusak oleh pihak ketiga yang berbahaya. Jadi semua data dalam skrip baru ini dimanipulasi sebagai variabel hingga menit terakhir di mana hasilnya ditampilkan sebagai file teks.

  6. File yang dihasilkan itu sendiri adalah hash dan path / hash dihasilkan di terminal. Saya suka mengambil gambar hash ini dengan kamera offline sekolah lama untuk dapat memastikan bahwa file hasil belum diubah ketika saya merujuknya di kemudian hari.

  7. File hasil lama diabaikan dalam penghitungan. Itu membuat membandingkan hasil lebih mudah.

Ini adalah contoh keluaran terminal saat menjalankan skrip saya:

kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ sha256rec
======================================================================= 
sha256rec:         
=======================================================================        
Current Folder : /usr/src/linux-headers-4.13.0-16-generic   
Target Folder  : /usr/src/linux-headers-4.13.0-16-generic
Output File    : /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt


Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder.
f3ddb06212622c375c6bcc11bd629ce38f6c48b7474054ca6f569ded4b4af9d8  /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt
Operation Length: 10 Seconds.
=======================================================================
kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ 

Berikut adalah cuplikan dari output yang dapat ditemukan di 000_sha256sum_recurs_linux-header-4.13.0-16-generic_d_22-04-2018_t_02.17.txt:

79c3f378a42bd225642220cc1e4801deb35c046475bb069a96870ad773082805  ./.9491.d
2e336c69cde866c6f01a3495048d0ebc2871dd9c4cb5d647be029e0205d15ce6  ./.config
174f23ff7a7fba897bfb7cf17e9a501bcecacf7ef0c0d5cf030414c1e257d4e3  ./.config.old
389d83f546b250304a9a01bb3072ff79f9d9e380c8a2106cadbf714a872afe33  ./.missing-syscalls.d
035dc77da819101cb9889b4e515023dddd2c953f00d2653b87c6196a6560903e  ./Module.symvers
b28054d7995233e6d003ceb9ed119a0b3354f5ccf77b8d687fc0353ae3c5bfb8  ./arch/x86/include/generated/asm/.syscalls_32.h.cmd
01cf821170e3e6e592e36a96e8628377151c762ac2ee3210c96004bfaef22f5f  ./arch/x86/include/generated/asm/.syscalls_64.h.cmd
111efa83187c58a74a9b0170fd496b497b0682d109a7c240c17e2ffcc734f4f4  ./arch/x86/include/generated/asm/.unistd_32_ia32.h.cmd
fcba4e8abf9e95472c31708555db844ac43c87260fb0ba706b6f519404bf9aba  ./arch/x86/include/generated/asm/.unistd_64_x32.h.cmd
3264438a54cbf7e62b05d38a93c5df8fe4202ac782a5d83ed202cba9eee71139  ./arch/x86/include/generated/asm/.xen-hypercalls.h.cmd
4bd7a45837da7de379b87242efe562ce06bf9d8ab8f636c205bb5ef384c8f759  ./arch/x86/include/generated/asm/clkdev.h
0d96461abd23bbf2da522822948455413a345f9ef8ac7a7f81c6126584b3c964  ./arch/x86/include/generated/asm/dma-contiguous.h
b1a54c24a12ce2c0f283661121974436cdb09ae91822497458072f5f97447c5d  ./arch/x86/include/generated/asm/early_ioremap.h
dd864107295503e102ea339e0fd4496204c697bdd5c1b1a35864dfefe504a990  ./arch/x86/include/generated/asm/mcs_spinlock.h
782ce66804d000472b3c601978fa9bd98dcf3b2750d608c684dc52dd1aa0eb7e  ./arch/x86/include/generated/asm/mm-arch-hooks.h
cd9913197f90cd06e55b19be1e02746655b5e52e388f13ec29032294c2f75897  ./arch/x86/include/generated/asm/syscalls_32.h
758ce35908e8cfeec956f57a206d8064a83a49298e47d47b7e9a7d37b5d96d59  ./arch/x86/include/generated/asm/syscalls_64.h
1147ca3a8443d9ccbdf9cd1f4b9b633f0b77f0559b83ec5e4fa594eadb2548be  ./arch/x86/include/generated/asm/unistd_32_ia32.h
ca5223fbf8f03613a6b000e20eb275d9b8081c8059bc540481a303ce722d42f3  ./arch/x86/include/generated/asm/unistd_64_x32.h
31703052c0d2ab8fe14b4e5dfcc45fcbd5feb5016b0a729b6ba92caa52b069e2  ./arch/x86/include/generated/asm/xen-hypercalls.h
c085ff1b6e9d06faa3fc6a55f69f9065c54098d206827deec7fe0a59d316fc99  ./arch/x86/include/generated/uapi/asm/.unistd_32.h.cmd
7929c16d349845cebb9e303e0ff15f67d924cac42940d0f7271584f1346635fc  ./arch/x86/include/generated/uapi/asm/.unistd_64.h.cmd
9aa492c5a75f5547f8d1dc454bef78189b8f262d1c4b00323a577907f138a63e  ./arch/x86/include/generated/uapi/asm/.unistd_x32.h.cmd
f568e151bbbb5d51fd531604a4a5ca9f17004142cd38ce019f0d5c661d32e36b  ./arch/x86/include/generated/uapi/asm/unistd_32.h
c45cf378498aa06b808bb9ccf5c3c4518e26501667f06c907a385671c60f14ae  ./arch/x86/include/generated/uapi/asm/unistd_64.h
a0088d8d86d7fd96798faa32aa427ed87743d3a0db76605b153d5124845161e2  ./arch/x86/include/generated/uapi/asm/unistd_x32.h
e757eb6420dffa6b24b7aa38ca57e6d6f0bfa7d6f3ea23bbc08789c7e31d15fa  ./arch/x86/kernel/.asm-offsets.s.cmd
f9e703e4f148d370d445c2f8c95f4a1b1ccde28c149cff2db5067c949a63d542  ./arch/x86/kernel/asm-offsets.s
7971fb3e0cc3a3564302b9a3e1ad188d2a00b653189968bbc155d42c70ce6fbf  ./arch/x86/purgatory/.entry64.o.cmd
8352d79fe81d2cf694880f428e283d79fd4b498cea5a425644da25a9641be26b  ./arch/x86/purgatory/.kexec-purgatory.c.cmd
37f3edbee777e955ba3b402098cb6c07500cf9dc7e1d44737f772ac222e6eb3e  ./arch/x86/purgatory/.purgatory.o.cmd
bb8b895cbd2611b69e2f46c2565b4c2e63a85afb56cff946a555f2d277ee99b2  ./arch/x86/purgatory/.purgatory.ro.cmd
bcc2365c9d3d027f1469806eb4f77b0f3ede6eb0855ea0fcd28aa65884046a54  ./arch/x86/purgatory/.setup-x86_64.o.cmd
872229f334fdcc8562e31b9f6581008c1571ac91f12889cd0ff413590585155a  ./arch/x86/purgatory/.sha256.o.cmd
6fb0cbef120aadee282f7bc3b5ea2f912980f16712281f8f7b65901005194422  ./arch/x86/purgatory/.stack.o.cmd
cd1b61063ae3cf45ee0c58b2c55039f3eac5f67a5154726d288b4708c4d43deb  ./arch/x86/purgatory/.string.o.cmd
e5826f0216fd590972bbc8162dd175f87f9f7140c8101505d8ca5849c850ec91  ./arch/x86/purgatory/entry64.o

(Ini berlangsung selama 7000+ baris lain seperti ini tetapi Anda mendapatkan ide)

INSTALASI

  1. Buka terminal dan masukkan perintah berikut:

    cd /usr/bin
    sudo su
    echo '#!/bin/bash'> /usr/bin/sha256rec
    chmod +x /usr/bin/sha256rec
    touch /usr/bin/sha256rec
    nano /usr/bin/sha256rec
  2. Di nano, gunakan Shif + Ctrl + v untuk menempel. Ctrl-O dan Enter untuk menyimpan. Ctr-X keluar. Rekatkan skrip saya di sana:

(tempel setelah #! / bin / bash)

  #FUNCTIONS OR FUNCTYOU?
  function s_readonly { err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; echo $(cat /tmp/$err|grep -i "Read-only file system"|wc -l);shred -n 0 -uz /tmp/$err; }
  function w_denied { echo $(err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function r_denied { echo $(err=$(date +%s%N); cd "$1" >/dev/null 2> /tmp/$err; find . >/dev/null 2>> /tmp/$err; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function rando_name { rando=$(echo $(date +%s%N)|sha256sum|awk '{print $1}'); rando=${rando::$(shuf -i 30-77 -n 1)}; echo $rando;}
  function ms0 { ms0=$(($(date +%s%N)/1000000)); }; function mstot { echo $(($(($(date +%s%N)/1000000))-$ms0));}
  function s0 { s0=$(date +%s); }; function stot { echo $(($(date +%s)-$s0));}
  s0

  #CHECK IF A TARGET DIR WAS SPECIFIED (-t= or --target= switch)
  if [ ! -z "$1" ]; then arg1="$1"; arg1_3=${arg1::3}; arg1_9=${arg1::9};fi
  if [ "$arg1_3" = "-t=" -o "$arg1_9" = "--target=" ]; then 
    switch=$(echo $arg1|awk -F '=' '{print $1}')
    switch_chr=$((${#switch}+1))
    target=${arg1:$switch_chr}
    current=$(pwd)
    cd "$target"
    arg1="" #<- cancels the not path in the find line
  else
    current=$(pwd)
    target=$(pwd) 
  fi

  echo -e  "=======================================================================\
    \nsha256rec: \
          \n=======================================================================\
          \nCurrent Folder : $current \
    \nTarget Folder  : $target"

  #GETS DEFAULT_USER, ASSUME'S YOU'RE USER 1000, IF 1000 DOESN'T EXIST SEARCHES 999, THEN 1001, 1002
  default_user=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)
  if [ -z "$default_user" ]; then default_user=$(awk -v val=999 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1001 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1002 -F ":" '$3==val{print $1}' /etc/passwd); fi

  if [ "$(users | wc -l)" = "1" ]; then USER=$(users|awk '{print $1}'); else USER=$default_user;fi #not perfect but meh...

  #running rando_name in this very specific spot between USER detection and Permission detection, some interfers somehow with detection functions... 
  #the rando function placed underneath the user detection is somehow turning c=$current from the dir path to whatever rando_name puts out.

  #FIGURE OUT WHERE TO PUT HASH LIST
  hash_file="000_sha256sum_recurs_${target##*/}_d_$(date +%d-%m-20%y)_t_$(date +%H.%M).txt"
  if [ $(s_readonly "$current") -gt 0 -o $(w_denied "$current") -gt 0 ]; then if [ "$(whoami)" != root ]; then dest="/home/$(whoami)";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder."; else dest="/home/$USER";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently a Read-Only system. You can find the hash results in $USER's home folder.";fi; else dest="$current";echo -e "Output File    : $dest/$hash_file\n\n";echo "Results will be saved here.";fi



  #CAN REGULAR USER ACCESS TARGET DIR? ARE ALL IT'S SUBDIRS READABLE?
  if [ $(r_denied "$target") -gt 0 ]; then sudo=sudo; echo "Some folder were not read-able as a regular user. User elevation will be required.";fi

  #PERFORM RECURSIVE HASHING
  command=$($sudo find . -type f -not -type l -not -path "$arg1"  -not -path "$2"  -not -path "$3" -not -path "$4"  -not -path "$5"  -not -path "$6" -not -path "$7"  -not -path "$8"  -not -path "$9" |grep -v "\./000_sha"|sort|awk "{print \"$sudo sha256sum \\\"\"\$0}"|awk '{print $0"\""}'|tr '\n' ';')
  eval $command > "$dest/$hash_file"

  sha256sum "$dest/$hash_file"
  echo "Operation Length: $(stot) Seconds."
  echo -e  "======================================================================="



  if [ "$target" != "$current" ]; then cd "$current";fi


  exit
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1. Saat Anda keluar dari nano, pastikan untuk keluar dari status yang ditinggikan dengan memasukkan:

    exit

PIKIRAN FINAL

  1. Ini hanya akan berfungsi jika Anda telah menginstal bash. Saya telah menggunakan beberapa sintaks untuk manipulasi substring yang tidak berfungsi dengan sh, dash, ksh, atau zsh. Anda masih dapat menggunakan shell lain sebagai driver harian Anda tetapi bash perlu diinstal.

  2. Daftar keluaran dapat dibandingkan dengan berbagai alat seperti: (di terminal) diff, sdiff (dan grafis) difus, kdiff, winmerge.

  3. File saya mengurutkan output berdasarkan path, untuk membuatnya lebih mudah dibaca oleh manusia. Saya perhatikan perintah sortir bekerja secara berbeda di distro yang berbeda. Misalnya, dalam satu distro, huruf MODAL lebih diprioritaskan daripada yang bukan huruf kapital dan yang lain tidak. Ini mempengaruhi urutan baris file output dan dapat membuat file sulit untuk dibandingkan. Ini seharusnya tidak menimbulkan masalah jika Anda selalu menggunakan skrip di distro yang sama tetapi mungkin jika daftar hash dihasilkan di dua lingkungan yang berbeda. Ini mudah diperbaiki dengan mengurutkan file hash waktu tambahan sehingga baris menjadi dipesan oleh hash daripada path:

     cat 000_sha256sum_oldhashlist|sort> ./old
     cat 000_sha256sum_newhashlist|sort> ./new
     sha256sum ./old ./new; diff ./old ./new
aturan kebun
sumber
Garis shebang yang lebih kuat adalah #!/usr/bin/env bash- ia akan menemukan Bash di direktori lain juga, karena yang terakhir mungkin dipasang di / usr / bin daripada / bin , misalnya, sementara itu env cenderung berada di / usr / bin setiap saat. sejauh yang saya perhatikan. Yang juga perlu diperhatikan adalah bahwa, karena Anda memerlukan Bash, Anda dapat menggunakan [[ blah-blah ]]ekspresi bersyarat braket ganda alih-alih [ blah-blah ]varian braket tunggal yang lebih umum .
Anton Samsonov
Terima kasih untuk petunjuknya. Saya baru saja selesai mencari [[persyaratan]. Mereka terlihat sangat berguna.
thebunnyrules
Kekhawatiran tentang SHA1 yang dikompromikan tidak benar-benar berlaku dalam hal membandingkan file setelah menyalin untuk memverifikasi integritas. Kemungkinan file rusak dalam perjalanan tetapi masih memiliki SHA1 yang sama praktis nihil. Jika Anda mencurigai penyerang mungkin memiliki cukup waktu untuk membuat file berbeda dengan SHA1 yang bertabrakan, maka gunakan SHA256, tetapi untuk kasus penyalinan file biasa, itu terlalu banyak dan lebih lambat daripada SHA1 atau MD5 .
Dan Dascalescu
Argumen Anda sendiri dapat digunakan untuk melawan dirinya sendiri. Jika Anda khawatir tentang korupsi normal (tidak terkait serangan), maka sha1 itu sendiri terlalu banyak. Anda bisa mendapatkan hasil yang lebih cepat menggunakan md5 / crc32. Dalam kedua situasi (deteksi kerusakan atau korupsi) sha1 tidak cocok. Secara pribadi, saya menggunakan daftar hash ini untuk kedua skenario dan belum melihat adanya peningkatan kinerja yang terlihat sejak saya memutakhirkan ke sha256 tapi saya juga tidak menjalankan server mega. Seperti yang saya katakan di jawaban, Anda bebas menggunakan hash apa pun yang Anda inginkan dengan mengganti perintah sha256sum saya dengan yang Anda inginkan: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules
1

Ini sepertinya bekerja untuk saya:

find . \( -not -name . \) -type f -exec cat {} + | sha1sum

EDIT: ini hanya akan sha1sum semua file yang terkandung dalam pohon direktori. Jika nama direktori diubah, ini tidak akan menangkapnya. Mungkin sesuatu seperti:

find . -exec sha1sum {} + 2>&1 | sha1sum

Akan melakukannya. Tentang jawaban yang sama dengan yang lainnya

d0c_s4vage
sumber
1

Trik lain mungkin menggunakan tar untuk hash isi file & metadata:

tar -cf - ./path/to/directory | sha1sum
kvz
sumber
Sayang sekali saya hanya memiliki satu suara
166_MMX
1
Ini tidak bekerja. tar menyertakan stempel waktu untuk beberapa OS (seperti OSX) dan sha1sum akan berbeda setiap kali dijalankan.
srossross
Apa yang dikatakan @srossross. Plus, jika Anda memiliki versi tar yang berbeda pada dua host, hasilnya akan berbeda.
Dan Dascalescu
1

Solusi cepat, kuat, dan portabel

Tidak seperti beberapa solusi lain yang melibatkan tar, solusi di bawah ini berfungsi pada mesin apa pun yang memiliki utilitas Unix standar, dan lebih cepat daripada semua solusi lain dengan memaralelkan checksumming:

find . -type f | xargs -d'\n' -P0 -n1 md5sum | sort -k 2 | md5sum

Karena menggunakan semacam di akhir, tidak ada kemajuan waktu nyata, jadi biarkan perintah berjalan.

Inilah yang dilakukan argumen:

  • find . -type f menemukan semua file di direktori saat ini dan subdirektori
  • xargs -d'\n'membagi output find menjadi baris (jika Anda berharap memiliki file dengan baris baru di dalamnya, maka lakukan yang biasa find -print0 | xargs -0)
  • -P0 n1berjalan md5sumdalam proses paralel, menggunakan jumlah maksimum proses yang didukung oleh mesin (multi-core!)
  • sort -k 2mengurutkan berdasarkan bidang kedua dari md5sumoutput, yang merupakan path lengkap ke setiap file (yang pertama adalah MD5)
  • final md5summenghitung checksum dari daftar checksum file, sehingga Anda mendapatkan checksum dari seluruh direktori pada satu baris, yang dapat Anda bandingkan dengan mudah secara visual di seluruh jendela terminal

Sebelum Anda mengatakan bahwa "MD5 telah dikompromikan", ingatlah apa model ancaman Anda. Apakah Anda mencoba memastikan bahwa file yang Anda salin dari host atau disk lain tiba utuh? Maka MD5 lebih dari cukup, karena kemungkinan file rusak dalam perjalanan tetapi memiliki MD5 yang sama adalah nol. Tetapi jika Anda takut penyerang punya waktu untuk mengganti file dengan yang berbeda dengan collum checksum, maka gunakan sha256sum. Kelemahannya adalah fungsi SHA lebih lambat dari MD5 .

Kemajuan verbose waktu-nyata

Akhirnya, jika Anda ingin melihat kemajuan waktu nyata, ubah pipa untuk menggunakan file sementara untuk checksum:

find . -type f | xargs -d\\n -P0 -n1 md5sum | tee /tmp/sums && sort -k 2 /tmp/sums | md5sum

(Perhatikan bahwa memindahkan sorthak setelah findtidak akan berfungsi, karena xargs -P0diparalelkan md5sum, dan hasilnya dapat keluar dari urutan.)

Versi perintah ini juga memungkinkan Anda untuk membedakan kedua /tmp/sumsfile (pastikan untuk mengganti nama yang kedua jika menggunakan mesin yang sama) dan melihat file mana yang berbeda.

Dan Dascalescu
sumber
0

Alih-alih memiliki SATU file besar yang berisi semua informasi hash saya mencari cara untuk membuat file di setiap folder pohon. Saya mengambil beberapa inspirasi dari komentar di sini. Milik saya sedikit lebih kompleks daripada yang diposting di sini. Saya menggunakan rotasi file tetapi ini adalah yang paling kompleks untuk pemain baru. Versi ini akan menimpanya dengan jumlah cek lama dengan yang baru. Mungkin baik untuk menyimpan 2-3 versi tergantung pada seberapa sering Anda menjalankannya dan kebutuhan Anda untuk 'mendalam'.

[user @ host bin] $ cat mkshaindir 
#! / bin / dash
cd $ 1
sha512sum *> .sha512sum

[user @ host bin] $ find / var / tmp -type d -print0 | xargs -0 -i mkshaindir {}

Perhatikan bahwa mkshaindir, untuk tujuan saya, adalah komponen terpisah karena mungkin ada kebutuhan bagi saya untuk membuat hash file dalam folder baru, atau salah satu yang baru saja diubah. Ini semua dapat digabungkan menjadi satu skrip jika diperlukan.

Sisanya dibiarkan sebagai latihan untuk pembaca.

Chris
sumber
0

berdasarkan jawaban sebelumnya :

find ./path/to/directory -print0 | LC_ALL=C sort --zero-terminated | tar --create --no-recursion --null --files-from /dev/stdin --file /dev/stdout --verbose --numeric-owner | sha1sum

  • semacam stabil
  • pemilik numerik dan id grup
  • kemajuan verbose
  • nama file aman
166_MMX
sumber
Ini tidak berfungsi pada direktori yang disalin yang hanya berisi satu file, dan saya menduga itu karena saya menjalankan versi tar (1.28) yang sedikit lebih tua pada host jarak jauh, vs 1,29 pada host lokal. Sayangnya, tar 1.29 belum di- backport di Xenial.
Dan Dascalescu
0

@allquixoticJawabannya tidak menghasilkan hash yang sama pada mesin yang berbeda yang tidak akan membantu kami memverifikasi dan memiliki hash yang konsisten.

Baris find . -type f \( -exec md5sum "$PWD"/{} \; \)berikut mengembalikan output berikut:

d41d8cd98f00b204e9800998ecf8427e  /home/helloWorld.c
24811012be8faa36c8f487bbaaadeb71  /home/helloMars.c

Karenanya jalan akan berbeda pada mesin yang berbeda. awk '{print $1}'akan membantu kami memperoleh kolom pertama, yang hanya memiliki hash file. Kemudian kita perlu mengurutkan hash tersebut, di mana urutannya mungkin berbeda pada mesin yang berbeda, yang juga dapat menyebabkan kita memiliki hash yang berbeda jika ada lebih dari dua file.


Larutan:

Untuk Mac:

find ./path/to/directory/ -type f \( -exec md5 -q  "$PWD"/{} \; \) | awk '{print $1}' | sort | md5

Untuk Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
Alper
sumber