lib/anybase.rb in anybase-0.0.9 vs lib/anybase.rb in anybase-0.0.10
- old
+ new
@@ -1,21 +1,32 @@
+require 'anybase/version'
+
class Anybase
UnrecognizedCharacterError = Class.new(RuntimeError)
attr_reader :chars, :char_map, :num_map
def initialize(chars, opts = nil)
@chars = chars
@ignore_case = opts && opts.key?(:ignore_case) ? opts[:ignore_case] : false
@synonyms = opts && opts[:synonyms]
+ @synonyms_tr = ['', ''] if @synonyms
@char_map = Hash.new{|h,k| raise UnrecognizedCharacterError.new("the character `#{k.chr}' is not included in #{@chars}")}
@num_map = {}
+ if ignore_case?
+ @chars.downcase!
+ end
@chars.split('').each_with_index do |c, i|
add_mapping(c, i)
@num_map[i] = c
- @synonyms[c].split('').each { |sc| add_mapping(sc, i) } if @synonyms && @synonyms[c]
+ if @synonyms && @synonyms[c]
+ @synonyms[c].split('').each { |sc|
+ @synonyms_tr[1] << c
+ @synonyms_tr[0] << sc
+ }
+ end
end
end
def ignore_case?
@ignore_case
@@ -23,10 +34,15 @@
def size(digits)
chars.length ** digits
end
+ def normalize(val)
+ val = val.downcase if ignore_case?
+ @synonyms ? val.tr(*@synonyms_tr) : val
+ end
+
def random(digits, opts = nil)
zero_pad = opts && opts.key?(:zero_pad) ? opts[:zero_pad] : true
number = ''
digits.times { number << chars[rand(chars.size)]}
unless zero_pad
@@ -35,10 +51,11 @@
end
number
end
def to_i(val)
+ val = normalize(val)
num = 0
(0...val.size).each{|i|
num += (chars.size ** (val.size - i - 1)) * char_map[val[i]]
}
num
@@ -57,10 +74,9 @@
str == '' ? num_map[0].dup : str
end
def add_mapping(c, i)
char_map[c[0]] = i
- char_map[c.swapcase[0]] = i if ignore_case?
end
private :add_mapping
Hex = Anybase.new('0123456789abcdef', :ignore_case => true)
Base62 = Anybase.new('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')