forked from git-lfs/git-lfs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhash-files
More file actions
executable file
·59 lines (51 loc) · 1.39 KB
/
hash-files
File metadata and controls
executable file
·59 lines (51 loc) · 1.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env ruby
require "openssl"
# This maps the OpenSSL name to the name used in the output file.
# The order used is the order they should appear in the output file.
DIGESTS = {
'BLAKE2b512' => 'BLAKE2b',
'BLAKE2s256' => 'BLAKE2s',
'SHA256' => 'SHA256',
'SHA384' => 'SHA384',
'SHA512' => 'SHA512',
'SHA512-256' => 'SHA512/256',
'SHA3-256' => 'SHA3-256',
'SHA3-384' => 'SHA3-384',
'SHA3-512' => 'SHA3-512',
}
class Hasher
def initialize(file)
@file = file
@hashers = DIGESTS.map do |openssl, output|
[output, OpenSSL::Digest.new(openssl)]
end.to_h
end
def update(s)
@hashers.values.each { |h| h.update(s) }
end
def to_a
@hashers.map do |name, ctx|
"#{name} (#{@file}) = #{ctx.digest.unpack("H*")[0]}\n"
end.to_a
end
end
results = []
ARGV.each do |file|
f = File.open(file)
h = Hasher.new(file)
while chunk = f.read(65536) do
h.update(chunk)
end
results += h.to_a
end
# Sort entries first by order of algorithm name in DIGESTS, then by filename,
# then print them.
# Create a mapping of output name digest to order in the hash.
names = DIGESTS.values.each_with_index.to_a.to_h
results.sort_by do |s|
# Split into digest name and remainder. The remainder starts with the
# filename.
pair = s.split(' ', 2).to_a
# Order by the index of the digest and then the filename.
[names[pair[0]], pair[1]]
end.each { |l| puts l }