Class: HashMan::Hasher
- Inherits:
-
Object
- Object
- HashMan::Hasher
- Defined in:
- lib/hashman/hasher.rb
Constant Summary collapse
- MIN_ALPHABET_LENGTH =
VERSION = "1.0.2"
16
- SEP_DIV =
3.5
- GUARD_DIV =
12.0
- DEFAULT_SEPS =
"cfhistuCFHISTU"
- DEFAULT_ALPHABET =
"abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "1234567890"
Instance Attribute Summary collapse
-
#alphabet ⇒ Object
readonly
Returns the value of attribute alphabet.
-
#guards ⇒ Object
readonly
Returns the value of attribute guards.
-
#min_hash_length ⇒ Object
readonly
Returns the value of attribute min_hash_length.
-
#salt ⇒ Object
readonly
Returns the value of attribute salt.
-
#seps ⇒ Object
readonly
Returns the value of attribute seps.
Instance Method Summary collapse
- #consistent_shuffle(alphabet, salt) ⇒ Object protected
- #decode(hash) ⇒ Object
- #decode_hex(hash) ⇒ Object
- #encode(*numbers) ⇒ Object
- #encode_hex(str) ⇒ Object
- #hash(input, alphabet) ⇒ Object protected
-
#initialize(salt = "", min_hash_length = 0, alphabet = DEFAULT_ALPHABET) ⇒ Hasher
constructor
A new instance of Hasher.
- #internal_decode(hash, alphabet) ⇒ Object protected
- #internal_encode(numbers) ⇒ Object protected
- #unhash(input, alphabet) ⇒ Object protected
Constructor Details
#initialize(salt = "", min_hash_length = 0, alphabet = DEFAULT_ALPHABET) ⇒ Hasher
Returns a new instance of Hasher.
17 18 19 20 21 22 23 |
# File 'lib/hashman/hasher.rb', line 17 def initialize(salt = "", min_hash_length = 0, alphabet = DEFAULT_ALPHABET) @salt = salt @min_hash_length = min_hash_length @alphabet = alphabet setup_alphabet end |
Instance Attribute Details
#alphabet ⇒ Object (readonly)
Returns the value of attribute alphabet.
15 16 17 |
# File 'lib/hashman/hasher.rb', line 15 def alphabet @alphabet end |
#guards ⇒ Object (readonly)
Returns the value of attribute guards.
15 16 17 |
# File 'lib/hashman/hasher.rb', line 15 def guards @guards end |
#min_hash_length ⇒ Object (readonly)
Returns the value of attribute min_hash_length.
15 16 17 |
# File 'lib/hashman/hasher.rb', line 15 def min_hash_length @min_hash_length end |
#salt ⇒ Object (readonly)
Returns the value of attribute salt.
15 16 17 |
# File 'lib/hashman/hasher.rb', line 15 def salt @salt end |
#seps ⇒ Object (readonly)
Returns the value of attribute seps.
15 16 17 |
# File 'lib/hashman/hasher.rb', line 15 def seps @seps end |
Instance Method Details
#consistent_shuffle(alphabet, salt) ⇒ Object (protected)
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/hashman/hasher.rb', line 142 def consistent_shuffle(alphabet, salt) return alphabet if salt.nil? || salt.empty? v = 0 p = 0 (alphabet.length-1).downto(1) do |i| v = v % salt.length p += n = salt[v].ord j = (n + v + p) % i tmp_char = alphabet[j] alphabet = alphabet[0, j] + alphabet[i] + alphabet[j + 1..-1] alphabet = alphabet[0, i] + tmp_char + alphabet[i + 1..-1] v += 1 end alphabet end |
#decode(hash) ⇒ Object
45 46 47 48 49 |
# File 'lib/hashman/hasher.rb', line 45 def decode(hash) return [] if hash.nil? || hash.empty? internal_decode(hash, @alphabet) end |
#decode_hex(hash) ⇒ Object
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/hashman/hasher.rb', line 51 def decode_hex(hash) ret = "" numbers = decode(hash) numbers.length.times do |i| ret += numbers[i].to_s(16)[1 .. -1] end ret.upcase end |
#encode(*numbers) ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/hashman/hasher.rb', line 25 def encode(*numbers) numbers.flatten! if numbers.length == 1 if numbers.empty? || numbers.reject { |n| Integer(n) && n >= 0 }.any? "" else internal_encode(numbers) end end |
#encode_hex(str) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/hashman/hasher.rb', line 35 def encode_hex(str) return "" unless hex_string?(str) numbers = str.scan(/[\w\W]{1,12}/).map do |num| "1#{num}".to_i(16) end encode(numbers) end |
#hash(input, alphabet) ⇒ Object (protected)
164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/hashman/hasher.rb', line 164 def hash(input, alphabet) num = input.to_i len = alphabet.length res = "" begin res = "#{alphabet[num % len]}#{res}" num = num.div(alphabet.length) end while num > 0 res end |
#internal_decode(hash, alphabet) ⇒ Object (protected)
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/hashman/hasher.rb', line 113 def internal_decode(hash, alphabet) ret = [] breakdown = hash.gsub(/[#{@guards}]/, " ") array = breakdown.split(" ") i = [3,2].include?(array.length) ? 1 : 0 if breakdown = array[i] lottery = breakdown[0] breakdown = breakdown[1 .. -1].gsub(/[#{@seps}]/, " ") array = breakdown.split(" ") array.length.times do |i| sub_hash = array[i] buffer = lottery + salt + alphabet alphabet = consistent_shuffle(alphabet, buffer[0, alphabet.length]) ret.push unhash(sub_hash, alphabet) end if encode(ret) != hash ret = [] end end ret end |
#internal_encode(numbers) ⇒ Object (protected)
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/hashman/hasher.rb', line 64 def internal_encode(numbers) ret = "" alphabet = @alphabet length = numbers.length hash_int = 0 length.times do |i| hash_int += (numbers[i] % (i + 100)) end lottery = ret = alphabet[hash_int % alphabet.length] length.times do |i| num = numbers[i] buf = lottery + salt + alphabet alphabet = consistent_shuffle(alphabet, buf[0, alphabet.length]) last = hash(num, alphabet) ret += last if (i + 1) < length num %= (last.ord + i) ret += seps[num % seps.length] end end if ret.length < min_hash_length ret = guards[(hash_int + ret[0].ord) % guards.length] + ret if ret.length < min_hash_length ret += guards[(hash_int + ret[2].ord) % guards.length] end end half_length = alphabet.length.div(2) while(ret.length < min_hash_length) alphabet = consistent_shuffle(alphabet, alphabet) ret = alphabet[half_length .. -1] + ret + alphabet[0, half_length] excess = ret.length - min_hash_length ret = ret[excess / 2, min_hash_length] if excess > 0 end ret end |
#unhash(input, alphabet) ⇒ Object (protected)
177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/hashman/hasher.rb', line 177 def unhash(input, alphabet) num = 0 input.length.times do |i| pos = alphabet.index(input[i]) raise InputError, "unable to unhash" unless pos num += pos * alphabet.length ** (input.length - i - 1) end num end |