class UnixCrypt::SHABase

Protected Class Methods

apply_rounds_bounds(rounds) click to toggle source
# File lib/unix_crypt/sha.rb, line 41
def self.apply_rounds_bounds(rounds)
  rounds = 1000        if rounds < 1000
  rounds = 999_999_999 if rounds > 999_999_999
  rounds
end
default_rounds() click to toggle source
# File lib/unix_crypt/sha.rb, line 6
def self.default_rounds; 5000; end
default_salt_length() click to toggle source
# File lib/unix_crypt/sha.rb, line 4
def self.default_salt_length; 16; end
internal_hash(password, salt, rounds = nil) click to toggle source
# File lib/unix_crypt/sha.rb, line 8
def self.internal_hash(password, salt, rounds = nil)
  rounds = apply_rounds_bounds(rounds || default_rounds)
  salt = salt[0..15]

  b = digest.digest("#{password}#{salt}#{password}")

  a_string = password + salt + b * (password.length/length) + b[0...password.length % length]

  password_length = password.length
  while password_length > 0
    a_string += (password_length & 1 != 0) ? b : password
    password_length >>= 1
  end

  input = digest.digest(a_string)

  dp = digest.digest(password * password.length)
  p = dp * (password.length/length) + dp[0...password.length % length]

  ds = digest.digest(salt * (16 + input.bytes.first))
  s = ds * (salt.length/length) + ds[0...salt.length % length]

  rounds.times do |index|
    c_string = ((index & 1 != 0) ? p : input)
    c_string += s unless index % 3 == 0
    c_string += p unless index % 7 == 0
    c_string += ((index & 1 != 0) ? input : p)
    input = digest.digest(c_string)
  end

  input
end
max_salt_length() click to toggle source
# File lib/unix_crypt/sha.rb, line 5
def self.max_salt_length; 16; end
rounds_marker(rounds) click to toggle source
# File lib/unix_crypt/sha.rb, line 47
def self.rounds_marker(rounds)
  if rounds && rounds != default_rounds
    "rounds=#{apply_rounds_bounds(rounds)}$"
  end
end