Z pewnością musi istnieć sposób, aby to łatwo zrobić!
Wypróbowałem aplikacje wiersza poleceń systemu Linux, takie jak sha1sum
i, md5sum
ale wydaje się, że są w stanie obliczyć skróty poszczególnych plików i wyprowadzić listę wartości skrótu, po jednej dla każdego pliku.
Muszę wygenerować jeden skrót dla całej zawartości folderu (nie tylko nazw plików).
Chciałbym zrobić coś takiego
sha1sum /folder/of/stuff > singlehashvalue
Edycja: aby wyjaśnić, moje pliki znajdują się na wielu poziomach w drzewie katalogów, nie wszystkie znajdują się w tym samym folderze głównym.
Odpowiedzi:
Jednym z możliwych sposobów byłoby:
Jeśli istnieje całe drzewo katalogów, prawdopodobnie lepiej będzie użyć funkcji find i xargs. Jednym z możliwych poleceń byłoby
I na koniec, jeśli musisz również wziąć pod uwagę uprawnienia i puste katalogi:
(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
Argumenty do
stat
spowodują, że wypisze nazwę pliku, po której następują ósemkowe uprawnienia. Te dwa znalezienia zostaną uruchomione jedno po drugim, powodując podwojenie ilości operacji we / wy dysku, pierwsze wyszukując wszystkie nazwy plików i sumując zawartość, a drugie znajdując wszystkie nazwy plików i katalogów, drukując nazwę i tryb. Lista „nazw plików i sum kontrolnych”, po której następują „nazwy i katalogi z uprawnieniami”, zostanie sprawdzona jako suma kontrolna, aby uzyskać mniejszą sumę kontrolną.źródło
find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
/
na wędzidlepath/to/folder
.Użyj narzędzia do wykrywania włamań do systemu plików, takiego jak aide .
haszuj kulkę tar z katalogu:
tar cvf - /path/to/folder | sha1sum
Zakoduj coś samemu, na przykład oneliner Vatine :
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
źródło
git config --local core.fileMode false
przed zobowiązaniem, aby tego uniknąć. Nie wiem, czy jest więcej takich zastrzeżeń.Możesz to zrobić
tar -c /path/to/folder | sha1sum
źródło
--mtime
opcję tak:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
.Jeśli chcesz tylko sprawdzić, czy coś w folderze się zmieniło, polecam ten:
Po prostu da ci hash wyjścia ls, który zawiera foldery, podfoldery, ich pliki, ich znacznik czasu, rozmiar i uprawnienia. Prawie wszystko, czego potrzebujesz, aby ustalić, czy coś się zmieniło.
Zwróć uwagę, że to polecenie nie wygeneruje skrótu dla każdego pliku, ale dlatego powinno być szybsze niż użycie find.
źródło
Solidne i czyste podejście
To jest to, co mam na głowie, każdy, kto spędził trochę czasu nad tym, praktycznie złapałby inne pułapki i przypadki narożne.
Oto narzędzie , bardzo mało pamięci, które dotyczy większości przypadków, może być nieco szorstkie na krawędziach, ale było całkiem pomocne.
Przykładowe użycie i dane wyjściowe
dtreetrawl
.Fragment przyjaznego dla człowieka wyniku:
źródło
Jeśli chcesz po prostu zaszyfrować zawartość plików, ignorując nazwy plików, możesz użyć
cat $FILES | md5sum
Upewnij się, że masz pliki w tej samej kolejności podczas obliczania skrótu:
cat $(echo $FILES | sort) | md5sum
Ale nie możesz mieć katalogów na liście plików.
źródło
Kolejne narzędzie do osiągnięcia tego:
http://md5deep.sourceforge.net/
Jak to brzmi: jak md5sum, ale także rekurencyjne, plus inne funkcje.
źródło
Jeśli to jest repozytorium git i chcesz zignorować wszystkie pliki w programie
.gitignore
, możesz użyć tego:git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
To działa dobrze dla mnie.
źródło
Jest do tego skrypt w Pythonie:
http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/
Jeśli zmienisz nazwy pliku bez zmiany ich kolejności alfabetycznej, skrypt skrótu go nie wykryje. Ale jeśli zmienisz kolejność plików lub zawartość dowolnego pliku, uruchomienie skryptu da inny skrót niż poprzednio.
źródło
Musiałem sprawdzić cały katalog w poszukiwaniu zmian plików.
Ale z wykluczaniem, sygnaturami czasowymi, właścicielami katalogów.
Celem jest uzyskanie wszędzie identycznej sumy, jeśli pliki są identyczne.
W tym hostowane na innych komputerach, niezależnie od wszystkiego oprócz plików lub zmian w nich.
md5sum * | md5sum | cut -d' ' -f1
Generuje listę skrótów według pliku, a następnie łączy te skróty w jeden.
Jest to o wiele szybsze niż metoda tar.
Aby zapewnić większą prywatność w naszych hashach , możemy użyć sumy sha512 w tej samej recepturze.
sha512sum * | sha512sum | cut -d' ' -f1
Hasze są również identyczne wszędzie przy użyciu sumy sha512, ale nie ma znanego sposobu, aby to odwrócić.
źródło
sha256sum /tmp/thd-agent/* | sort
to jest to, czego staram się w celu uzyskania niezawodnego zamówienia, a następnie po prostu to wszystko.ls -r | sha256sum
?Spróbuj zrobić to w dwóch krokach:
Tak jak to:
# for FILE in `find /folder/of/stuff -type f | sort`; do sha1sum $FILE >> hashes; done # sha1sum hashes
Lub zrób to wszystko na raz:
# cat `find /folder/of/stuff -type f | sort` | sha1sum
źródło
for F in 'find ...' ...
nie działa, gdy masz spacje w nazwach (co zawsze robisz w dzisiejszych czasach).Przepuściłbym wyniki dla poszczególnych plików
sort
(aby zapobiec zwykłej zmianie kolejności plików w celu zmiany skrótu) domd5sum
lubsha1sum
, cokolwiek wybierzesz.źródło
Napisałem skrypt Groovy, aby to zrobić:
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)}"
Możesz dostosować użycie, aby uniknąć drukowania każdego pliku, zmienić skrót wiadomości, usunąć mieszanie katalogów itp. Przetestowałem to z danymi testowymi NIST i działa zgodnie z oczekiwaniami. http://www.nsrl.nist.gov/testdata/
źródło
Możesz
sha1sum
wygenerować listę wartości skrótu, a następniesha1sum
tę listę ponownie, zależy to od tego, co dokładnie chcesz osiągnąć.źródło
Oto prosty, krótki wariant w Pythonie 3, który działa dobrze w przypadku małych plików (np. Drzewo źródłowe lub coś takiego, gdzie każdy plik z osobna można łatwo zmieścić w pamięci RAM), ignorując puste katalogi, w oparciu o pomysły z innych rozwiązań:
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()
Działa to tak:
Możesz przekazać inną funkcję skrótu jako drugi parametr, jeśli SHA-1 nie jest twoją filiżanką herbaty.
źródło
Jak dotąd najszybszym sposobem jest nadal użycie smoły. Dzięki kilku dodatkowym parametrom możemy również pozbyć się różnicy spowodowanej przez metadane.
Aby użyć tar do haszowania katalogu, należy upewnić się, że sortujesz ścieżkę podczas tar, w przeciwnym razie zawsze jest inaczej.
ignoruj czas
Jeśli nie zależy Ci na czasie dostępu lub modyfikacji czasu, użyj czegoś takiego jak,
--mtime='UTC 2019-01-01'
aby upewnić się, że wszystkie znaczniki czasu są takie same.ignoruj własność
Zwykle musimy dodać,
--group=0 --owner=0 --numeric-owner
aby ujednolicić metadane właściciela.zignoruj niektóre pliki
posługiwać się
--exclude=PATTERN
źródło