Pasti ada cara untuk melakukannya dengan mudah!
Saya telah mencoba aplikasi baris perintah Linux seperti sha1sum
dan md5sum
tetapi mereka tampaknya hanya dapat menghitung hash file individual dan mengeluarkan daftar nilai hash, satu untuk setiap file.
Saya perlu membuat satu hash untuk seluruh konten folder (bukan hanya nama file).
Saya ingin melakukan sesuatu seperti
sha1sum /folder/of/stuff > singlehashvalue
Sunting: untuk memperjelas, file saya ada di beberapa tingkatan dalam pohon direktori, mereka tidak semua berada di folder root yang sama.
Jawaban:
Salah satu cara yang mungkin adalah:
Jika ada seluruh pohon direktori, Anda mungkin lebih baik menggunakan find dan xargs. Satu perintah yang mungkin adalah
Dan, terakhir, jika Anda juga perlu mempertimbangkan izin dan direktori kosong:
(find path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum; find path/to/folder \( -type f -o -type d \) -print0 | sort -z | \ xargs -0 stat -c '%n %a') \ | sha1sum
Argumen untuk
stat
akan menyebabkannya mencetak nama file, diikuti dengan izin oktalnya. Kedua penemuan akan berjalan satu demi satu, menyebabkan dua kali jumlah IO disk, yang pertama menemukan semua nama file dan memeriksa isinya, yang kedua menemukan semua nama file dan direktori, nama dan mode pencetakan. Daftar "nama file dan checksum", diikuti dengan "nama dan direktori, dengan izin" kemudian akan di-checksum, untuk checksum yang lebih kecil.sumber
find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
/
dipath/to/folder
bit.Gunakan alat deteksi intrusi sistem file seperti ajudan .
hash bola tar direktori:
tar cvf - /path/to/folder | sha1sum
Kode sesuatu sendiri, seperti oneliner vatine :
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
sumber
git config --local core.fileMode false
sebelum melakukan untuk menghindari ini. Saya tidak tahu apakah ada peringatan seperti ini lagi.Anda dapat melakukan
tar -c /path/to/folder | sha1sum
sumber
--mtime
opsi seperti:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
.Jika Anda hanya ingin memeriksa apakah ada yang berubah di folder, saya merekomendasikan yang ini:
Ini hanya akan memberi Anda hash dari output ls, yang berisi folder, sub-folder, file mereka, stempel waktu, ukuran dan izinnya. Hampir semua yang Anda perlukan untuk menentukan apakah sesuatu telah berubah.
Harap dicatat bahwa perintah ini tidak akan menghasilkan hash untuk setiap file, tetapi itulah mengapa harus lebih cepat daripada menggunakan find.
sumber
Pendekatan yang kuat dan bersih
Inilah yang saya pikirkan, siapa pun yang telah menghabiskan beberapa waktu untuk mengerjakan ini secara praktis akan menangkap kasus gotcha dan pojok lainnya.
Ini adalah alat , sangat ringan pada memori, yang menangani sebagian besar kasus, mungkin agak kasar di tepinya tetapi telah cukup membantu.
Contoh penggunaan dan keluaran
dtreetrawl
.Cuplikan dari keluaran yang ramah manusia:
sumber
Jika Anda hanya ingin mencirikan konten file, mengabaikan nama file maka Anda dapat menggunakan
cat $FILES | md5sum
Pastikan Anda memiliki file dengan urutan yang sama saat menghitung hash:
cat $(echo $FILES | sort) | md5sum
Tetapi Anda tidak dapat memiliki direktori dalam daftar file Anda.
sumber
Alat lain untuk mencapai ini:
http://md5deep.sourceforge.net/
Seperti suara: seperti md5sum tetapi juga rekursif, ditambah fitur lainnya.
sumber
Jika ini adalah repo git dan Anda ingin mengabaikan file apa pun
.gitignore
, Anda mungkin ingin menggunakan ini:git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
Ini bekerja dengan baik untuk saya.
sumber
Ada skrip python untuk itu:
http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/
Jika Anda mengubah nama file tanpa mengubah urutan abjadnya, skrip hash tidak akan mendeteksinya. Namun, jika Anda mengubah urutan file atau konten file apa pun, menjalankan skrip akan memberi Anda hash yang berbeda dari sebelumnya.
sumber
Saya harus memeriksa seluruh direktori untuk perubahan file.
Tetapi dengan mengecualikan, cap waktu, kepemilikan direktori.
Tujuannya adalah untuk mendapatkan jumlah yang identik di mana saja, jika file tersebut identik.
Termasuk dihosting ke mesin lain, apa pun kecuali file, atau perubahan ke dalamnya.
md5sum * | md5sum | cut -d' ' -f1
Ini menghasilkan daftar hash berdasarkan file, kemudian menggabungkan hash tersebut menjadi satu.
Ini jauh lebih cepat daripada metode tar.
Untuk privasi yang lebih kuat di hash kami, kami dapat menggunakan sha512sum pada resep yang sama.
sha512sum * | sha512sum | cut -d' ' -f1
Hash juga identik di mana saja menggunakan sha512sum tetapi tidak ada cara yang diketahui untuk membalikkannya.
sumber
sha256sum /tmp/thd-agent/* | sort
adalah apa yang saya coba untuk pemesanan yang andal, lalu hashing saja.ls -r | sha256sum
?Cobalah membuatnya dalam dua langkah:
Seperti:
# for FILE in `find /folder/of/stuff -type f | sort`; do sha1sum $FILE >> hashes; done # sha1sum hashes
Atau lakukan semuanya sekaligus:
# cat `find /folder/of/stuff -type f | sort` | sha1sum
sumber
for F in 'find ...' ...
tidak berfungsi jika Anda memiliki spasi dalam nama (yang selalu Anda lakukan saat ini).Saya akan menyalurkan hasil untuk file individual melalui
sort
(untuk mencegah pengubahan urutan file hanya untuk mengubah hash) menjadimd5sum
atausha1sum
, mana pun yang Anda pilih.sumber
Saya telah menulis skrip Groovy untuk melakukan ini:
import java.security.MessageDigest public static String generateDigest(File file, String digest, int paddedLength){ MessageDigest md = MessageDigest.getInstance(digest) md.reset() def files = [] def directories = [] if(file.isDirectory()){ file.eachFileRecurse(){sf -> if(sf.isFile()){ files.add(sf) } else{ directories.add(file.toURI().relativize(sf.toURI()).toString()) } } } else if(file.isFile()){ files.add(file) } files.sort({a, b -> return a.getAbsolutePath() <=> b.getAbsolutePath()}) directories.sort() files.each(){f -> println file.toURI().relativize(f.toURI()).toString() f.withInputStream(){is -> byte[] buffer = new byte[8192] int read = 0 while((read = is.read(buffer)) > 0){ md.update(buffer, 0, read) } } } directories.each(){d -> println d md.update(d.getBytes()) } byte[] digestBytes = md.digest() BigInteger bigInt = new BigInteger(1, digestBytes) return bigInt.toString(16).padLeft(paddedLength, '0') } println "\n${generateDigest(new File(args[0]), 'SHA-256', 64)}"
Anda dapat menyesuaikan penggunaan untuk menghindari pencetakan setiap file, mengubah intisari pesan, mengambil hashing direktori, dll. Saya telah mengujinya terhadap data uji NIST dan berfungsi seperti yang diharapkan. http://www.nsrl.nist.gov/testdata/
sumber
Anda dapat
sha1sum
membuat daftar nilai hash dan kemudiansha1sum
daftar itu lagi, itu tergantung pada apa yang sebenarnya ingin Anda capai.sumber
Berikut adalah varian singkat dan sederhana di Python 3 yang berfungsi dengan baik untuk file berukuran kecil (misalnya pohon sumber atau sesuatu, di mana setiap file dapat masuk ke dalam RAM dengan mudah), mengabaikan direktori kosong, berdasarkan ide dari solusi lain:
import os, hashlib def hash_for_directory(path, hashfunc=hashlib.sha1): filenames = sorted(os.path.join(dp, fn) for dp, _, fns in os.walk(path) for fn in fns) index = '\n'.join('{}={}'.format(os.path.relpath(fn, path), hashfunc(open(fn, 'rb').read()).hexdigest()) for fn in filenames) return hashfunc(index.encode('utf-8')).hexdigest()
Ini bekerja seperti ini:
Anda dapat memasukkan fungsi hash yang berbeda sebagai parameter kedua jika SHA-1 bukan secangkir teh Anda.
sumber
Sejauh ini cara tercepat untuk melakukannya masih dengan tar. Dan dengan beberapa parameter tambahan kita juga dapat menghilangkan perbedaan yang disebabkan oleh metadata.
Untuk menggunakan tar untuk hash dir, perlu dipastikan Anda mengurutkan path selama tar, jika tidak maka akan selalu berbeda.
abaikan waktu
Jika Anda tidak peduli dengan waktu akses atau mengubah waktu juga gunakan sesuatu seperti
--mtime='UTC 2019-01-01'
untuk memastikan semua cap waktu sama.abaikan kepemilikan
Biasanya kita perlu menambahkan
--group=0 --owner=0 --numeric-owner
untuk menyatukan metadata pemilik.abaikan beberapa file
menggunakan
--exclude=PATTERN
sumber