class ScatterSwap::Hasher

Attributes

length[R]

@return [Fixnum] the number of digits in the computed hashes.

spin[R]

@return [Fixnum] A seed value to add some spice, so that different apps can have differently mapped hashes.

working_array[R]

@return [Array]

Public Class Methods

new(integer, spin = 0, length = 10) click to toggle source

Construct a new Hasher. @param [Fixnum] integer the numeric value to be hashed/reversed. @param [Fixnum] spin a seed value. @param [Fixnum] length the number of digits in the computed hashes.

# File lib/scatter_swap/hasher.rb, line 18
def initialize(integer, spin = 0, length = 10)
  @original_integer = integer.freeze
  @spin = (spin || 0).freeze
  @length = length.freeze
  zero_pad = integer.to_s.rjust(length, '0')
  @working_array = zero_pad.split('').collect { |d| d.to_i }
end

Public Instance Methods

hash() click to toggle source

Obfuscate the original integer value to a zero-padded String of {#length} digits. @return [String] the obfuscated hash.

# File lib/scatter_swap/hasher.rb, line 29
def hash
  swap
  scatter
  completed_string
end
reverse_hash() click to toggle source

De-obfuscate the original integer value to a zero-padded String of {#length} digits. @return [String] the de-obfuscated hash.

# File lib/scatter_swap/hasher.rb, line 38
def reverse_hash
  unscatter
  unswap
  completed_string
end

Private Instance Methods

completed_string() click to toggle source
# File lib/scatter_swap/hasher.rb, line 48
def completed_string
  @working_array.join
end
scatter() click to toggle source

Rearrange the order of each digit in a reversible way by using the sum of the digits (which doesn't change regardless of order) as a key to record how they were scattered

# File lib/scatter_swap/hasher.rb, line 78
def scatter
  sum_of_digits = @working_array.inject(:+).to_i
  @working_array = length.times.collect do
    @working_array.rotate!(spin ^ sum_of_digits).pop
  end
end
swap() click to toggle source

Using a unique map for each of the ten places, we swap out one number for another

# File lib/scatter_swap/hasher.rb, line 62
def swap
  @working_array = @working_array.collect.with_index do |digit, index|
    swapper_map(index)[digit]
  end
end
swapper_map(index) click to toggle source

We want a unique map for each place in the original number

# File lib/scatter_swap/hasher.rb, line 53
def swapper_map(index)
  array = (0..9).to_a
  10.times.collect.with_index do |i|
    array.rotate!(index + i ^ spin).pop
  end
end
unscatter() click to toggle source

Reverse the scatter

# File lib/scatter_swap/hasher.rb, line 86
def unscatter
  scattered_array = @working_array
  sum_of_digits = scattered_array.inject(:+).to_i
  @working_array = []
  @working_array.tap do |unscatter| 
    length.times do
      unscatter.push scattered_array.pop
      unscatter.rotate! (sum_of_digits ^ spin) * -1
    end
  end
end
unswap() click to toggle source

Reverse swap

# File lib/scatter_swap/hasher.rb, line 69
def unswap
  @working_array = @working_array.collect.with_index do |digit, index|
    swapper_map(index).rindex(digit)
  end
end