¡Seguramente debe haber una manera de hacer esto fácilmente!
Probé las aplicaciones de línea de comandos de Linux como sha1sum
y, md5sum
pero parece que solo pueden calcular valores hash de archivos individuales y generar una lista de valores hash, uno para cada archivo.
Necesito generar un solo hash para todo el contenido de una carpeta (no solo los nombres de archivo).
Me gustaria hacer algo como
sha1sum /folder/of/stuff > singlehashvalue
Editar: para aclarar, mis archivos están en varios niveles en un árbol de directorios, no todos están en la misma carpeta raíz.
Respuestas:
Una forma posible sería:
Si hay un árbol de directorios completo, probablemente sea mejor usar find y xargs. Un posible comando sería
Y, finalmente, si también necesitas tener en cuenta los permisos y directorios vacíos:
(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
Los argumentos de
stat
harán que imprima el nombre del archivo, seguido de sus permisos octales. Los dos hallazgos se ejecutarán uno tras otro, lo que generará el doble de la cantidad de E / S del disco, el primero buscará todos los nombres de archivos y sumará el contenido, el segundo buscará todos los nombres de archivos y directorios, el nombre de impresión y el modo. La lista de "nombres de archivos y sumas de verificación", seguida de "nombres y directorios, con permisos", se agregará a la suma de verificación para obtener una suma de verificación más pequeña.fuente
find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
/
en elpath/to/folder
bit.Utilice una herramienta de detección de intrusiones en el sistema de archivos como asistente .
hash una bola de alquitrán del directorio:
tar cvf - /path/to/folder | sha1sum
Codifique algo usted mismo, como el delineador de vatine :
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
fuente
git config --local core.fileMode false
antes de comprometerte para evitar esto. No sé si hay más advertencias como esta.Tu puedes hacer
tar -c /path/to/folder | sha1sum
fuente
--mtime
opción de este modo:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
.Si solo desea verificar si algo en la carpeta cambió, le recomiendo este:
Solo le dará un hash de la salida de ls, que contiene carpetas, subcarpetas, sus archivos, su marca de tiempo, tamaño y permisos. Prácticamente todo lo que necesitaría para determinar si algo ha cambiado.
Tenga en cuenta que este comando no generará hash para cada archivo, pero es por eso que debería ser más rápido que usar find.
fuente
Un enfoque sólido y limpio
Esto es lo que tengo encima de mi cabeza, cualquiera que haya pasado algún tiempo trabajando en esto prácticamente habría captado otras trampas y casos de esquina.
Aquí hay una herramienta , muy liviana en memoria, que se ocupa de la mayoría de los casos, puede ser un poco tosca en los bordes, pero ha sido bastante útil.
Un ejemplo de uso y salida de
dtreetrawl
.Un fragmento de salida amigable para los humanos:
fuente
Si solo desea aplicar un hash al contenido de los archivos, ignorando los nombres de archivo, puede usar
cat $FILES | md5sum
Asegúrese de tener los archivos en el mismo orden al calcular el hash:
cat $(echo $FILES | sort) | md5sum
Pero no puede tener directorios en su lista de archivos.
fuente
Otra herramienta para lograrlo:
http://md5deep.sourceforge.net/
Como suena: como md5sum pero también recursivo, además de otras características.
fuente
Si se trata de un repositorio de git y desea ignorar cualquier archivo en
.gitignore
, es posible que desee utilizar esto:git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
Esto me está funcionando bien.
fuente
Hay un script de Python para eso:
http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/
Si cambia los nombres de un archivo sin cambiar su orden alfabético, el script hash no lo detectará. Pero, si cambia el orden de los archivos o el contenido de cualquier archivo, ejecutar el script le dará un hash diferente al anterior.
fuente
Tuve que registrarme en un directorio completo para ver los cambios de archivo.
Pero excluyendo, marcas de tiempo, propiedad de directorios.
El objetivo es obtener una suma idéntica en cualquier lugar, si los archivos son idénticos.
Incluyendo alojado en otras máquinas, sin importar nada menos los archivos, o un cambio en ellos.
md5sum * | md5sum | cut -d' ' -f1
Genera una lista de hash por archivo, luego concatena esos hash en uno.
Esto es mucho más rápido que el método tar.
Para una mayor privacidad en nuestros hashes, podemos usar sha512sum en la misma receta.
sha512sum * | sha512sum | cut -d' ' -f1
Los hash también son idénticos en cualquier lugar con sha512sum, pero no se conoce una forma de revertirlo.
fuente
sha256sum /tmp/thd-agent/* | sort
es lo que estoy tratando de hacer para un pedido confiable, y luego simplemente lo hago.ls -r | sha256sum
?Intenta hacerlo en dos pasos:
Al igual que:
# for FILE in `find /folder/of/stuff -type f | sort`; do sha1sum $FILE >> hashes; done # sha1sum hashes
O hazlo todo a la vez:
# cat `find /folder/of/stuff -type f | sort` | sha1sum
fuente
for F in 'find ...' ...
no funciona cuando tienes espacios en los nombres (lo que siempre haces hoy en día).Canalizaría los resultados para archivos individuales
sort
(para evitar una mera reordenación de archivos para cambiar el hash) enmd5sum
osha1sum
, lo que elija.fuente
Escribí un script de Groovy para hacer esto:
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)}"
Puede personalizar el uso para evitar imprimir cada archivo, cambiar el resumen del mensaje, eliminar el hash del directorio, etc. Lo he probado con los datos de prueba del NIST y funciona como se esperaba. http://www.nsrl.nist.gov/testdata/
fuente
Podría
sha1sum
generar la lista de valores hash y luegosha1sum
esa lista nuevamente, depende de qué es exactamente lo que desea lograr.fuente
Aquí hay una variante simple y corta en Python 3 que funciona bien para archivos de pequeño tamaño (por ejemplo, un árbol de fuentes o algo, donde cada archivo individualmente puede caber en la RAM fácilmente), ignorando los directorios vacíos, según las ideas de las otras soluciones:
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()
Funciona así:
Puede pasar una función hash diferente como segundo parámetro si SHA-1 no es su taza de té.
fuente
Hasta ahora, la forma más rápida de hacerlo sigue siendo con alquitrán. Y con varios parámetros adicionales también podemos deshacernos de la diferencia causada por los metadatos.
Para usar tar para hash en el directorio, es necesario asegurarse de ordenar la ruta durante tar, de lo contrario, siempre es diferente.
ignorar el tiempo
Si no le importa el tiempo de acceso o modificar el tiempo, también use algo como
--mtime='UTC 2019-01-01'
para asegurarse de que todas las marcas de tiempo sean iguales.ignorar la propiedad
Por lo general, necesitamos agregar
--group=0 --owner=0 --numeric-owner
para unificar los metadatos del propietario.ignorar algunos archivos
utilizar
--exclude=PATTERN
fuente