Linux操作系统:计算一个哈希给定文件夹和内容是什么?

问题描述 投票:69回答:14

当然,必须有一个方法可以轻松地做到这一点!

我试图在Linux命令行应用程序,如sha1summd5sum但他们似乎只能够计算个人文件和输出一个为每个文件的散列值的列表,的散列。

我需要生成一个文件夹(而不仅仅是文件名)的全部内容单一的哈希值。

我想这样做

sha1sum /folder/of/stuff > singlehashvalue

编辑:为了澄清,我的文件是在一个目录树多层次的,他们不是都坐在同一个根文件夹。

linux bash hash
14个回答
94
投票

一种可能的方法是:

sha1sum path/to/folder/* | sha1sum

如果有一个整个目录树,你可能关闭使用查找和xargs的更好。一个可能的命令是

find path/to/folder -type f -print0 | sort -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,首次发现的所有文件名的双倍数量和执行校验的内容,第二个发现所有的文件和目录名,打印的名字和模式。的“文件名和校验”,其次是“名和目录,具有权限”列表将被校验和,一个较小的校验和。


1
投票

我写了一个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

0
投票

尽量做到在两个步骤:

  1. 在文件夹中创建散列文件的所有文件
  2. 哈希这个文件

像这样:

# 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

0
投票

你可以sha1sum生成散列值的列表,然后再sha1sum该名单,这取决于究竟什么是你想要完成的任务。


0
投票

我检查到文件更改整个目录。

但不包括,时间戳,目录所有权。

目标是获得相同的总和的任何地方,如果文件是相同的。

包括托管到其他机器上,无论任何事情,但这些文件,或将改变他们。

md5sum * | md5sum | cut -d' ' -f1

它通过文件生成散列的列表,然后串联这些散列成一个。

这比焦油法的方式更快。

对于我们的哈希更强的隐私,我们可以在相同的配方使用sha512sum。

sha512sum * | sha512sum | cut -d' ' -f1

哈希也identicals任何地方使用sha512sum但没有扭转它没有已知的方法。


0
投票

下面是在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()                          

它的工作原理是这样的:

  1. 递归查找目录中的所有文件和名称进行排序
  2. 计算哈希值(默认:SHA-1)的每个文件(读取整个文件到内存)
  3. 请以“文件名=散”行文本索引
  4. 编码指数回成UTF-8字节串和散那

您可以在different hash function作为第二个参数传递,如果SHA-1是不是你的那杯茶。


0
投票

如果这是一个git回购和你想忽略.gitignore任何文件,你可能想用这个:

git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1

这对我来说工作良好。


21
投票
  • 使用像aide文件系统入侵检测工具。
  • 哈希目录的焦油球: tar cvf - /path/to/folder | sha1sum
  • 代码自己的东西,像vatine's onelinerfind /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum

9
投票

你可以做tar -c /path/to/folder | sha1sum


6
投票

如果你只是想检查,如果事情的文件夹中改变了,我建议这一个:

ls -alR --full-time /folder/of/stuff | sha1sum

这将只是给你的LS输出,包含文件夹,子文件夹,它们的文件,它们的时间戳,大小和权限的哈希值。几乎一切,你需要确定,如果事情发生了变化。

请注意,这个命令不会产生对每个文件的哈希,但是这就是为什么它应该比使用查找快。


3
投票

如果你只是想哈希文件的内容,忽略了文件名,那么你可以使用

cat $FILES | md5sum

请确保您有在计算散列时的顺序相同的文件:

cat $(echo $FILES | sort) | md5sum

但是你不能有目录中的文件列表。


2
投票

有是一个Python脚本:

http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/

如果更改一个文件的名称,而不改变其字母顺序,哈希脚本不对其进行检测。但是,如果更改的文件或文件的内容,运行脚本的命令会给你一个不同的哈希比以前。


2
投票

A robust and clean approach

  • 首先第一件事情,别占着可用内存!散列块文件,而不是将整个文件。
  • 不同的方法针对不同的需求/目的(全部低于或挑什么都适用): 在目录树哈希只有所有条目的条目名称 哈希所有条目的文件内容(离开像,索引节点号,的ctime,atime的,修改时间,大小等元,你的想法) 对于符号链接,其内容是指称名。哈希,或选择跳过 按照或者不跟随(解析的名称)的符号链接,而散列条目的内容 如果它是一个目录,其内容仅仅是目录条目。虽然递归遍历他们最终会被哈希,但应该是水平的目录条目名称被散列到这个目录标记?有用在需要哈希快速识别的改变,而无需深入遍历散列的内容使用情况。一个例子是文件的名称更改,但内容的其余部分保持不变,他们都是相当大的文件 处理大文件以及(再一次,介意RAM) 处理非常深目录树(介意打开文件描述符) 处理非标准文件名 如何使用是插座,管道/ FIFO中,块设备文件,字符设备进行呢?必须哈希它们吗? 不要更新而穿越任何条目的访问时间,因为这将是对某些使用情况的副作用和适得其反(直觉?)。

这就是我在上面我的头,谁花了一些时间在这个几乎就已经引起了其他陷阱和角落的情况下工作的任何一个。

Here's a tool,记忆很轻,这解决了大多数情况下,可能是周围的边缘有点粗糙,但已经相当有帮助的。

An example usage and output of 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

1
投票

我会通过管道将sort结果为单个文件(防止文件仅仅重新排序,以改变散列)到md5sumsha1sum,无论你选择。


1
投票

另一种工具来实现这一点:

http://md5deep.sourceforge.net/

由于是一种声音:像的md5sum也递归,再加上其他的功能。

© www.soinside.com 2019 - 2024. All rights reserved.