Class: Archive::Fixity

Inherits:
Object
  • Object
show all
Defined in:
lib/archive/fixity.rb

Overview

Note:

Copyright © 2014 by The Board of Trustees of the Leland Stanford Junior University. All rights reserved. See LICENSE for details.

A helper class that facilites the generation and processing of checksums

Constant Summary collapse

@@default_checksum_types =
[:sha1, :sha256]
@@valid_checksum_types =
[
    ChecksumType.new(:md5, 32, ['MD5']),
    ChecksumType.new(:sha1, 40, ['SHA-1', 'SHA1']),
    ChecksumType.new(:sha256, 64, ['SHA-256', 'SHA256']),
    ChecksumType.new(:sha384, 96, ['SHA-384', 'SHA384']),
    ChecksumType.new(:sha512, 128, ['SHA-512', 'SHA512'])
]

Class Method Summary collapse

Class Method Details

.default_checksum_typesArray<Symbol>

Returns The list of checksum types to be used when generating fixity data.

Returns:

  • (Array<Symbol>)

    The list of checksum types to be used when generating fixity data



18
19
20
# File 'lib/archive/fixity.rb', line 18

def Fixity.default_checksum_types
  @@default_checksum_types
end

.default_checksum_types=(*types) ⇒ Void

Returns Set the list of checksum types to be used when generating fixity data.

Parameters:

  • types (Array<Symbol>)

    The list of checksum types to be used when generating fixity data

Returns:

  • (Void)

    Set the list of checksum types to be used when generating fixity data



24
25
26
# File 'lib/archive/fixity.rb', line 24

def Fixity.default_checksum_types=(*types)
  @@default_checksum_types = Fixity.validate_checksum_types(*types)
end

.file_checksum_hash(file_fixity_hash) ⇒ Hash<String,Hash<Symbol,String] A hash containing file ids and checksum data derived from the file_fixity_hash

Returns Hash<String,Hash<Symbol,String] A hash containing file ids and checksum data derived from the file_fixity_hash.

Parameters:

  • file_fixity_hash (Hash<String,FileFixity>)

    A hash containing file ids and fixity data derived from the manifest files

Returns:

  • (Hash<String,Hash<Symbol,String] A hash containing file ids and checksum data derived from the file_fixity_hash)

    Hash<String,Hash<Symbol,String] A hash containing file ids and checksum data derived from the file_fixity_hash



129
130
131
132
133
# File 'lib/archive/fixity.rb', line 129

def Fixity.file_checksum_hash(file_fixity_hash)
  checksum_hash = Hash.new
  file_fixity_hash.values.each{|file| checksum_hash[file.file_id] = file.checksums}
  checksum_hash
end

.fixity_from_checksum_values(file_id, checksum_values) ⇒ FileFixity

Returns Generate a FileFixity instance containing fixity properties supplied by the caller.

Parameters:

  • file_id (Object)

    The filename or relative path of the file from its base directory

  • checksum_values (Object)

    The digest values of the file

Returns:

  • (FileFixity)

    Generate a FileFixity instance containing fixity properties supplied by the caller



117
118
119
120
121
122
123
124
125
# File 'lib/archive/fixity.rb', line 117

def Fixity.fixity_from_checksum_values(file_id, checksum_values)
  file_fixity = FileFixity.new
  file_fixity.file_id = file_id
  checksum_values.each do |digest|
    checksum_type = Fixity.type_for_length(digest.length)
    file_fixity.checksums[checksum_type.id] = digest
  end
  file_fixity
end

.fixity_from_file(pathname, base_pathname, checksum_types = @@default_checksum_types) ⇒ FileFixity

Returns Generate a FileFixity instance containing fixity properties measured from of a physical file.

Parameters:

  • pathname (Pathname)

    The location of the file to be digested

  • base_pathname (Object)

    The base directory from which relative paths (file IDS) will be derived

  • checksum_types (Object) (defaults to: @@default_checksum_types)

    The list of checksum types being specified by the caller (or default list)

Returns:

  • (FileFixity)

    Generate a FileFixity instance containing fixity properties measured from of a physical file



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/archive/fixity.rb', line 81

def Fixity.fixity_from_file(pathname, base_pathname, checksum_types=@@default_checksum_types)
  file_fixity = FileFixity.new
  file_fixity.file_id = pathname.relative_path_from(base_pathname).to_s
  file_fixity.bytes = pathname.size
  digesters = Fixity.get_digesters(checksum_types)
  pathname.open("r") do |stream|
    while buffer = stream.read(8192)
      digesters.values.each { |digest| digest.update(buffer) }
    end
  end
  digesters.each { |checksum_type, digest| file_fixity.checksums[checksum_type] = digest.hexdigest }
  file_fixity
end

.generate_checksums(base_pathname, path_list, checksum_types = @@default_checksum_types) ⇒ Hash<String,FileFixity>

Returns A hash containing file ids and fixity data derived from the actual files.

Parameters:

  • path_list (Array<Pathname>)

    The list of pathnames for files whose fixity will be generated

Returns:

  • (Hash<String,FileFixity>)

    A hash containing file ids and fixity data derived from the actual files



98
99
100
101
102
103
104
105
106
# File 'lib/archive/fixity.rb', line 98

def Fixity.generate_checksums(base_pathname, path_list, checksum_types=@@default_checksum_types)
  path_list = base_pathname.find  if path_list.nil?
  file_fixity_hash = Hash.new
  path_list.select{|pathname| pathname.file?}.each  do |file|
    file_fixity = Fixity.fixity_from_file(file, base_pathname, checksum_types)
    file_fixity_hash[file_fixity.file_id] = file_fixity
  end
  file_fixity_hash
end

.get_digesters(checksum_types = @@default_checksum_types) ⇒ Array<Digest::Class>

Returns The list of digest implementation objects that will generate the checksums.

Parameters:

  • checksum_types (Array<Symbol>) (defaults to: @@default_checksum_types)

    The list of checksum types being specified by the caller

Returns:

  • (Array<Digest::Class>)

    The list of digest implementation objects that will generate the checksums



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/archive/fixity.rb', line 57

def Fixity.get_digesters(checksum_types=@@default_checksum_types)
  checksum_types.inject(Hash.new) do |digesters, checksum_type|
    case checksum_type
      when :md5
        digesters[checksum_type] = Digest::MD5.new
      when :sha1
        digesters[checksum_type] = Digest::SHA1.new
      when :sha256
        digesters[checksum_type] = Digest::SHA2.new(256)
      when :sha384
        digesters[checksum_type] = Digest::SHA2.new(384)
      when :sha512
        digesters[checksum_type] = Digest::SHA2.new(512)
      else
        raise "Unrecognized checksum type: #{checksum_type}"
    end
    digesters
  end
end

.openssl_digest(checksum_type, file_pathname) ⇒ String

Returns The checksum digest value for the file.

Parameters:

  • checksum_type (Symbol, String)

    The type of checksum digest to be generated

  • file_pathname (Pathname, String)

    The location of the file to digest

Returns:

  • (String)

    The checksum digest value for the file



146
147
148
149
150
151
# File 'lib/archive/fixity.rb', line 146

def Fixity.openssl_digest(checksum_type,file_pathname)
  command = openssl_digest_command(checksum_type,file_pathname)
  stdout = OperatingSystem.execute(command)
  checksum = stdout.scan(/[A-Za-z0-9]+/).last
  checksum
end

.openssl_digest_command(checksum_type, file_pathname) ⇒ String

Returns The operating system shell command that will generate the checksum digest value.

Parameters:

  • checksum_type (Symbol, String)

    The type of checksum digest to be generated

  • file_pathname (Pathname, String)

    The location of the file to digest

Returns:

  • (String)

    The operating system shell command that will generate the checksum digest value



138
139
140
141
# File 'lib/archive/fixity.rb', line 138

def Fixity.openssl_digest_command(checksum_type,file_pathname)
  command = "openssl dgst -#{checksum_type} #{file_pathname}"
  command
end

.type_for_length(length) ⇒ ChecksumType

Returns The ChecksumType struct that contains the properties of the matching checksum type.

Parameters:

  • length (Integer)

    The length of the checksum value in hex format

Returns:

  • (ChecksumType)

    The ChecksumType struct that contains the properties of the matching checksum type



110
111
112
# File 'lib/archive/fixity.rb', line 110

def Fixity.type_for_length(length)
  @@valid_checksum_types.select {|type| type.hex_length == length}.first
end

.valid_checksum_idsArray<Symbol>

Returns The list of allowed checksum types.

Returns:

  • (Array<Symbol>)

    The list of allowed checksum types



42
43
44
# File 'lib/archive/fixity.rb', line 42

def Fixity.valid_checksum_ids
  @@valid_checksum_types.map { |type| type.id }
end

.valid_checksum_typesArray<ChecksumType>

Returns The list of allowed ChecksumType structs containing the type’s properties.

Returns:

  • (Array<ChecksumType>)

    The list of allowed ChecksumType structs containing the type’s properties



37
38
39
# File 'lib/archive/fixity.rb', line 37

def Fixity.valid_checksum_types
  @@valid_checksum_types
end

.validate_checksum_types(*types) ⇒ Object

Returns The list of specified checksum types after being checked for validity.

Parameters:

  • types (Array<Symbol>)

    The list of checksum types being specified by the caller

Returns:

  • (Object)

    The list of specified checksum types after being checked for validity



48
49
50
51
52
53
# File 'lib/archive/fixity.rb', line 48

def Fixity.validate_checksum_types(*types)
  checksum_types = types.flatten
  invalid_types = checksum_types - valid_checksum_ids
  raise "Invalid digest type specified: #{invalid_types.inspect}" unless invalid_types.empty?
  checksum_types
end