当然,必须有一种方法可以轻松地做到这一点!
我已经尝试了Linux命令行应用程序,例如sha1sum
和,md5sum
但是它们似乎只能计算单个文件的哈希值并输出哈希值列表,每个文件一个哈希值。
我需要为文件夹的整个内容生成一个哈希(不仅仅是文件名)。
我想做类似的事情
sha1sum /folder/of/stuff > singlehashvalue
编辑:澄清一下,我的文件在目录树中处于多个级别,它们并不都位于同一根文件夹中。
当然,必须有一种方法可以轻松地做到这一点!
我已经尝试了Linux命令行应用程序,例如sha1sum
和,md5sum
但是它们似乎只能计算单个文件的哈希值并输出哈希值列表,每个文件一个哈希值。
我需要为文件夹的整个内容生成一个哈希(不仅仅是文件名)。
我想做类似的事情
sha1sum /folder/of/stuff > singlehashvalue
编辑:澄清一下,我的文件在目录树中处于多个级别,它们并不都位于同一根文件夹中。
Answers:
一种可能的方式是:
sha1sum路径/到/文件夹/ * | sha1sum
如果有一整个目录树,最好使用find和xargs。一种可能的命令是
查找路径/到/文件夹-type f -print0 | 排序-z | xargs -0 sha1sum | sha1sum
最后,如果您还需要考虑权限和空目录:
(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
的参数stat
将导致它打印文件名,然后是其八进制权限。这两个查找将一个接一个地运行,从而导致磁盘IO数量翻倍,第一个查找所有文件名并校验和内容,第二个查找所有文件和目录名,打印名称和方式。然后,将对“文件名和校验和”列表以及“具有权限的名称和目录”列表进行校验和,以得到较小的校验和。
find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
/
对path/to/folder
位。
使用aide之类的文件系统入侵检测工具。
哈希目录的tar球:
tar cvf - /path/to/folder | sha1sum
自己编写一些东西,例如vatine的oneliner:
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
git config --local core.fileMode false
才能避免这种情况。我不知道是否还有其他类似警告。
你可以做 tar -c /path/to/folder | sha1sum
--mtime
选项:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
。
如果您只想检查文件夹中的某些内容是否发生了变化,我建议您这样做:
ls -alR --full-time /folder/of/stuff | sha1sum
它只会给您ls输出的哈希,其中包含文件夹,子文件夹,它们的文件,它们的时间戳,大小和权限。确定是否已更改的几乎所有内容。
请注意,此命令不会为每个文件生成哈希,但这就是为什么它比使用find更快的原因。
这就是我的头等大事,任何花了一些时间从事这一工作的人实际上都会抓到其他陷阱和死角。
这是一个内存很少的工具,可以解决大多数情况,可能有些麻烦,但是很有帮助。
dtreetrawl
。Usage: dtreetrawl [OPTION...] "/trawl/me" [path2,...] Help Options: -h, --help Show help options Application Options: -t, --terse Produce a terse output; parsable. -j, --json Output as JSON -d, --delim=: Character or string delimiter/separator for terse output(default ':') -l, --max-level=N Do not traverse tree beyond N level(s) --hash Enable hashing(default is MD5). -c, --checksum=md5 Valid hashing algorithms: md5, sha1, sha256, sha512. -R, --only-root-hash Output only the root hash. Blank line if --hash is not set -N, --no-name-hash Exclude path name while calculating the root checksum -F, --no-content-hash Do not hash the contents of the file -s, --hash-symlink Include symbolic links' referent name while calculating the root checksum -e, --hash-dirent Include hash of directory entries while calculating root checksum
一段人类友好的输出:
... ... //clipped ... /home/lab/linux-4.14-rc8/CREDITS Base name : CREDITS Level : 1 Type : regular file Referent name : File size : 98443 bytes I-node number : 290850 No. directory entries : 0 Permission (octal) : 0644 Link count : 1 Ownership : UID=0, GID=0 Preferred I/O block size : 4096 bytes Blocks allocated : 200 Last status change : Tue, 21 Nov 17 21:28:18 +0530 Last file access : Thu, 28 Dec 17 00:53:27 +0530 Last file modification : Tue, 21 Nov 17 21:28:18 +0530 Hash : 9f0312d130016d103aa5fc9d16a2437e Stats for /home/lab/linux-4.14-rc8: Elapsed time : 1.305767 s Start time : Sun, 07 Jan 18 03:42:39 +0530 Root hash : 434e93111ad6f9335bb4954bc8f4eca4 Hash type : md5 Depth : 8 Total, size : 66850916 bytes entries : 12484 directories : 763 regular files : 11715 symlinks : 6 block devices : 0 char devices : 0 sockets : 0 FIFOs/pipes : 0
如果您只想散列文件的内容,而忽略文件名,则可以使用
cat $FILES | md5sum
计算哈希值时,请确保文件顺序相同:
cat $(echo $FILES | sort) | md5sum
但是,文件列表中不能包含目录。
如果这是一个git repo,而您想忽略中的任何文件.gitignore
,则可能要使用此命令:
git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
这对我来说很好。
有一个python脚本:
http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/
如果您更改文件名而不更改其字母顺序,则哈希脚本将无法检测到它。但是,如果您更改文件的顺序或任何文件的内容,则运行脚本将为您提供与以前不同的哈希值。
尝试分两个步骤进行:
像这样:
# for FILE in `find /folder/of/stuff -type f | sort`; do sha1sum $FILE >> hashes; done
# sha1sum hashes
或一次完成所有操作:
# cat `find /folder/of/stuff -type f | sort` | sha1sum
for F in 'find ...' ...
当名称中有空格时(现在一直如此),该功能将不起作用。
我觉得应该通过结果单个文件sort
(防止文件仅仅重新排序改变哈希)进入md5sum
或者sha1sum
,无论你选择。
我编写了一个Groovy脚本来做到这一点:
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)}"
您可以自定义用法,以避免打印每个文件,更改消息摘要,删除目录哈希等。我已经针对NIST测试数据对其进行了测试,并且可以正常工作。 http://www.nsrl.nist.gov/testdata/
gary-macbook:Scripts garypaduana$ groovy dirHash.groovy /Users/garypaduana/.config
.DS_Store
configstore/bower-github.yml
configstore/insight-bower.json
configstore/update-notifier-bower.json
filezilla/filezilla.xml
filezilla/layout.xml
filezilla/lockfile
filezilla/queue.sqlite3
filezilla/recentservers.xml
filezilla/sitemanager.xml
gtk-2.0/gtkfilechooser.ini
a/
configstore/
filezilla/
gtk-2.0/
lftp/
menus/
menus/applications-merged/
79de5e583734ca40ff651a3d9a54d106b52e94f1f8c2cd7133ca3bbddc0c6758
我必须检查整个目录以进行文件更改。
但要排除时间戳,目录所有权。
目标是在文件相同的情况下,在任何地方都获得相同的总和。
包括托管到其他计算机中,除了文件以外的任何东西,或对其进行更改。
md5sum * | md5sum | cut -d' ' -f1
它按文件生成一个哈希列表,然后将这些哈希串联为一个。
这比tar方法快得多。
为了更好地保护我们的哈希,我们可以在同一食谱上使用sha512sum。
sha512sum * | sha512sum | cut -d' ' -f1
使用sha512sum的哈希值在任何地方都是相同的,但是没有已知的方法可以将其反转。
sha256sum /tmp/thd-agent/* | sort
我正在尝试进行可靠的排序,然后对其进行哈希处理。
ls -r | sha256sum
呢?
这是Python 3中的一个简单,简短的变体,适用于小型文件(例如,源树或类似的东西,其中每个文件都可以轻松地放入RAM中),并根据其他解决方案的想法忽略了空目录:
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()
它是这样的:
如果SHA-1不是您喜欢的茶,则可以传入另一个哈希函数作为第二个参数。