class Bundler::Checksum

def ==(other)

def ==(other)
  match?(other) && other.sources == sources
end

def formatted_sources

def formatted_sources
  sources.join("\n    and ").concat("\n")
end

def from_api(digest, source_uri, algo = DEFAULT_ALGORITHM)

def from_api(digest, source_uri, algo = DEFAULT_ALGORITHM)
  return if Bundler.settings[:disable_checksum_validation]
  Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:api, source_uri))
end

def from_gem(io, pathname, algo = DEFAULT_ALGORITHM)

def from_gem(io, pathname, algo = DEFAULT_ALGORITHM)
  digest = Bundler::SharedHelpers.digest(algo.upcase).new
  buf = String.new(capacity: DEFAULT_BLOCK_SIZE)
  digest << io.readpartial(DEFAULT_BLOCK_SIZE, buf) until io.eof?
  Checksum.new(algo, digest.hexdigest!, Source.new(:gem, pathname))
end

def from_gem_package(gem_package, algo = DEFAULT_ALGORITHM)

def from_gem_package(gem_package, algo = DEFAULT_ALGORITHM)
  return if Bundler.settings[:disable_checksum_validation]
  return unless source = gem_package.instance_variable_get(:@gem)
  return unless source.respond_to?(:with_read_io)
  source.with_read_io do |io|
    from_gem(io, source.path)
  ensure
    io.rewind
  end
end

def from_lock(lock_checksum, lockfile_location)

def from_lock(lock_checksum, lockfile_location)
  algo, digest = lock_checksum.strip.split(ALGO_SEPARATOR, 2)
  Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:lock, lockfile_location))
end

def hash

def hash
  digest.hash
end

def initialize(algo, digest, source)

def initialize(algo, digest, source)
  @algo = algo
  @digest = digest
  @sources = [source]
end

def inspect

def inspect
  abbr = "#{algo}#{ALGO_SEPARATOR}#{digest[0, 8]}"
  from = "from #{sources.join(" and ")}"
  "#<#{self.class}:#{object_id} #{abbr} #{from}>"
end

def match?(other)

def match?(other)
  other.is_a?(self.class) && other.digest == digest && other.algo == algo
end

def merge!(other)

def merge!(other)
  return nil unless match?(other)
  @sources.concat(other.sources).uniq!
  self
end

def removable?

def removable?
  sources.all?(&:removable?)
end

def removal_instructions

def removal_instructions
  msg = +""
  i = 1
  sources.each do |source|
    msg << "  #{i}. #{source.removal}\n"
    i += 1
  end
  msg << "  #{i}. run `bundle install`\n"
end

def same_source?(other)

def same_source?(other)
  sources.include?(other.sources.first)
end

def to_hexdigest(digest, algo = DEFAULT_ALGORITHM)

def to_hexdigest(digest, algo = DEFAULT_ALGORITHM)
  return digest unless algo == DEFAULT_ALGORITHM
  return digest if digest.match?(/\A[0-9a-f]{64}\z/i)
  if digest.match?(%r{\A[-0-9a-z_+/]{43}={0,2}\z}i)
    digest = digest.tr("-_", "+/") # fix urlsafe base64
    digest.unpack1("m0").unpack1("H*")
  else
    raise ArgumentError, "#{digest.inspect} is not a valid SHA256 hex or base64 digest"
  end
end

def to_lock

def to_lock
  "#{algo}#{ALGO_SEPARATOR}#{digest}"
end

def to_s

def to_s
  "#{to_lock} (from #{sources.first}#{", ..." if sources.size > 1})"
end