class Decidim::FingerprintCalculator

This class will generate a unique fingerprint given an arbitrarily deep hash, ensuring that the same fingerprint will be generated regardless of ordering and whether keys are symbols or strings.

Public Class Methods

new(data) click to toggle source

Public: Initializes the class with a source data to be fingerprinted.

# File lib/decidim/fingerprint_calculator.rb, line 12
def initialize(data)
  @data = data
end

Public Instance Methods

source() click to toggle source

Public: Returns the fingerprint source before hashing, so that it can be inspected by the user.

Returns a String with the JSON representation of the normalized data.

# File lib/decidim/fingerprint_calculator.rb, line 27
def source
  @source ||= JSON.generate(sort_hash(@data))
end
value() click to toggle source

Public: Generates a fingerprint hash.

Returns a String with the fingerprint.

# File lib/decidim/fingerprint_calculator.rb, line 19
def value
  @value ||= Digest::SHA256.hexdigest(source)
end

Private Instance Methods

sort_hash(hash) click to toggle source
# File lib/decidim/fingerprint_calculator.rb, line 33
def sort_hash(hash)
  return hash unless hash.is_a?(Hash)

  Hash[
    hash.map { |key, value| [key, sort_hash(value)] }
        .sort_by { |key, _value| key }
  ]
end