base_convert 3.0.191224 → 3.1.191231

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20e33ba2c83ac2c66ed25c9047af914ce03450c41b104e5ea46e36dfa16bb155
4
- data.tar.gz: a4303de9c930084f602a58330119e721d28a713d90f5b86fce75f9d33da8b1b4
3
+ metadata.gz: '09e96875804850531f1e4e890eeac10d8a53275be55d875f3ea262a03624218d'
4
+ data.tar.gz: c374bb673c441bb11c314accdcd1b2afef057cf1e23252225cbf08347c83c9ef
5
5
  SHA512:
6
- metadata.gz: e960d364647497d8a4e3c24198097570ea05de2d669a39cf48abdf4c634297d40c49d42b190eb5615c33835daeeeffdc6fbc45aea54d18dafa96a8eee8372d05
7
- data.tar.gz: ff6bb256ba739c191aca4fd969a04fb85aad4a4a193a2120f5256383e911718140963b4dfa227ab7742830400f6f4fcea98fc26e6ce208704f7f2573d7cb9333
6
+ metadata.gz: 05ddba6c9079bf3c8a737b8e176e52f560beb6d19ed8aadda1230bd2f09691c112ffbf52cf5b329853f5dd96ab31ade73553938fb83eb7c29783337105bbd31b
7
+ data.tar.gz: 2b246aeea822d1aa57b281bc6bc93eb118751c86f938dea9c2eb719741efb53c0ca4e5dc7c26f2d38eb81ee535adc9a8d8cc7226c40de931dd087561f5fa741f
data/README.md CHANGED
@@ -69,21 +69,42 @@ You can work with arbitrary digits:
69
69
  toi('&&&&', base, digits) #=> 4095
70
70
  tob(4095, base, digits) #=> "&&&&"
71
71
 
72
- For convenience, `base_convert` provides under `module BaseConvert::Configuration` some predefined sets of digits.
72
+ Note that one can always explicitly specify the ordered digits to be used.
73
+ But for convenience, `base_convert` provides some predefined sets of digits:
73
74
 
74
- * `GRAPH` are the ASCII graph characters.
75
- * `QGRAPH` are the ASCII graph characters except quotes: double-quote, single-quote, and back-tick.
76
- * `BASE64` is the standard base 64 digits from people with no sense of order.
77
- * `WORD_` are the ASCII word characters including underscore(`_`).
78
- * `WORD` are the ASCII word characters except underscore(`_`).
79
- * `UNAMBIGUOUS` are the characters in `WORD` without the `AMBIGUOUS` characters(B8G6I1l0OQDS5Z2).
75
+ * `GRAPH :graph :g`, the ASCII graph characters:
76
+
77
+ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
78
+
79
+ * `QGRAPH :qgraph :q`, the ASCII graph characters except `QUOTES`:
80
+
81
+ !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~
82
+
83
+ * `BASE64 :base64 :b64`, the standard base 64 digits from people with no sense of order:
84
+
85
+ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
86
+
87
+ * `WORD_ :word_ :w_`, the ASCII word characters including `UNDERSCORE`:
88
+
89
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
90
+
91
+ * `WORD :word :w`, the ASCII word characters except `UNDERSCORE`:
92
+
93
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
94
+
95
+ * `UNAMBIGUOUS :unambigous :u`, the characters in `WORD` without the `AMBIGUOUS` characters(B8G6I1l0OQDS5Z2):
96
+
97
+ 3479ACEFHJKLMNPRTUVWXYabcdefghijkmnopqrstuvwxyz
98
+
99
+ * `G94 :g94` is the library's default defined as `WORD+QGRAPH.delete(WORD_)+QUOTES+UNDERSCORE`
100
+
101
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+,-./:;<=>?@[\]^{|}~"'`_
80
102
 
81
103
  Some examples:
82
104
 
83
- Configuration::UNAMBIGUOUS #=> "3479ACEFHJKLMNPRTUVWXYabcdefghijkmnopqrstuvwxyz"
105
+ UNAMBIGUOUS #=> "3479ACEFHJKLMNPRTUVWXYabcdefghijkmnopqrstuvwxyz"
84
106
  # etc...
85
- tob 255, 16, Configuration::WORD #=> "FF"
86
- include Configuration
107
+ tob 255, 16, WORD #=> "FF"
87
108
  tob 255, 64, BASE64 #=> "D/"
88
109
 
89
110
  The second way to convert is via a conversion object of `BaseConvert::FromTo`.
@@ -101,11 +122,7 @@ The third way to work with variant base and digits numbers is via the `BaseConve
101
122
  hexadecimal.to_i #=> 65535
102
123
 
103
124
  # Number will infer your most likely meaning:
104
- Number.new('FF', 16).to_i #=> 255
105
-
106
- # And given a string of at least length 8,
107
- # it'll go ahead and guess at your meaning:
108
- Number.new('FFFFFFFF').to_i #=> 4294967295
125
+ Number.new('FF').to_i #=> 255
109
126
 
110
127
  # But best practice is to fully specify,
111
128
  # which is easy to do with keys:
@@ -135,6 +152,7 @@ one can use a mnemonic key:
135
152
 
136
153
  | long key | short key | DIGITS | BASE NUMBER |
137
154
  | -------------- | --------- | ------------- | ----------- |
155
+ | `:g94` | | `G94` | 94 |
138
156
  | `:graph` | `:g` | `GRAPH` | 94 |
139
157
  | `:qgraph` | `:q` | `QGRAPH` | 91 |
140
158
  | `:base64` | `:b64` | `BASE64` | 64 |
@@ -149,6 +167,13 @@ one can use a mnemonic key:
149
167
  | `:octal` | `:oct, :o` | 8 |
150
168
  | `:binary` | `:bin, :b` | 2 |
151
169
 
170
+ Example:
171
+
172
+ # For some pseudo-random string of unambigous characters
173
+ # of very likely length 16:
174
+ p = BaseConvert::Number.new(rand(47**16), digits: :u)
175
+ p.to_s #=> "CxesjJqHcvpnp7bp"
176
+
152
177
  ## LICENSE:
153
178
 
154
179
  (The MIT License)
@@ -1,30 +1,8 @@
1
- # http://rosettacode.org/wiki/Non-decimal_radices/Convert#Ruby
2
1
  module BaseConvert
3
- VERSION = '3.0.191224'
4
-
5
- def toi(string=@string, base=@base, digits=@digits)
6
- integer = 0
7
- string.each_char do |c|
8
- index = digits.index(c)
9
- integer = integer * base + index
10
- end
11
- integer
12
- end
13
-
14
- def tob(integer=@integer, base=@base, digits=@digits)
15
- return digits[0] if integer == 0
16
- string = ''
17
- while integer > 0
18
- integer, index = integer.divmod(base)
19
- string = string.insert(0, digits[index])
20
- end
21
- string
22
- end
23
-
24
- extend self
25
-
26
- autoload :Configuration, 'base_convert/configuration'
27
- autoload :FromTo, 'base_convert/from_to'
28
- autoload :Number, 'base_convert/number'
2
+ VERSION = '3.1.191231'
3
+ require 'base_convert/base_convert'
4
+ require 'base_convert/configuration'
5
+ require 'base_convert/from_to'
6
+ require 'base_convert/number'
29
7
  end
30
8
  #`ruby`
@@ -0,0 +1,23 @@
1
+ # http://rosettacode.org/wiki/Non-decimal_radices/Convert#Ruby
2
+ module BaseConvert
3
+ def toi(string=@string, base=@base, digits=@digits)
4
+ integer = 0
5
+ string.each_char do |c|
6
+ index = digits.index(c)
7
+ integer = integer * base + index
8
+ end
9
+ integer
10
+ end
11
+
12
+ def tob(integer=@integer, base=@base, digits=@digits)
13
+ return digits[0] if integer == 0
14
+ string = ''
15
+ while integer > 0
16
+ integer, index = integer.divmod(base)
17
+ string = string.insert(0, digits[index])
18
+ end
19
+ string
20
+ end
21
+
22
+ extend self
23
+ end
@@ -1,24 +1,26 @@
1
1
  module BaseConvert
2
- module Configuration
3
-
4
- GRAPH = 0.upto(255).map{|i| i.chr}.select{|c| c=~/[[:graph:]]/}.join.freeze
5
- QGRAPH = GRAPH.delete(%('"`)).freeze
6
-
7
- WORD_ = 0.upto(255).map{|i| i.chr}.select{|c| c=~/\w/}.join.freeze
8
- WORD = WORD_.delete('_').freeze
9
- INDEXa = WORD.index('a')
10
-
2
+ QUOTES = %("'`).freeze
3
+ UNDERSCORE = '_'.freeze
11
4
  AMBIGUOUS = 'B8G6I1l0OQDS5Z2'.freeze
5
+
6
+ GRAPH = 0.upto(255).map{|i| i.chr}.select{|c| c=~/[[:graph:]]/}.join.freeze
7
+ QGRAPH = GRAPH.delete(QUOTES).freeze
8
+ WORD_ = QGRAPH.chars.select{|c| c=~/\w/}.join.freeze
9
+ WORD = WORD_.delete(UNDERSCORE).freeze
12
10
  UNAMBIGUOUS = WORD.delete(AMBIGUOUS).freeze
11
+ G94 = (WORD + QGRAPH.delete(WORD_) + QUOTES + UNDERSCORE).freeze
13
12
 
14
- BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
13
+ BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.freeze
14
+
15
+ INDEXa = G94.index('a')
15
16
 
16
17
  BASE = {
17
- :graph => GRAPH.length,
18
- :qgraph => QGRAPH.length,
19
- :word_ => WORD_.length,
20
- :word => WORD.length,
21
- :unambiguous => UNAMBIGUOUS.length,
18
+ :g94 => G94.length, # 94
19
+ :graph => GRAPH.length, # 94
20
+ :qgraph => QGRAPH.length, # 91
21
+ :word_ => WORD_.length, # 63
22
+ :word => WORD.length, # 62
23
+ :unambiguous => UNAMBIGUOUS.length, # 47
22
24
  :base64 => 64,
23
25
  :b64 => 64,
24
26
  :hexadecimal => 16,
@@ -35,13 +37,14 @@ module Configuration
35
37
  :b => 2,
36
38
  }
37
39
 
38
- BASE[:g] = BASE[:graph]
39
- BASE[:q] = BASE[:qgraph]
40
- BASE[:w_] = BASE[:word_]
41
- BASE[:w] = BASE[:word]
42
- BASE[:u] = BASE[:unambiguous]
40
+ BASE[:g] = BASE[:graph]
41
+ BASE[:q] = BASE[:qgraph]
42
+ BASE[:w_] = BASE[:word_]
43
+ BASE[:w] = BASE[:word]
44
+ BASE[:u] = BASE[:unambiguous]
43
45
 
44
46
  DIGITS = {
47
+ :g94 => G94,
45
48
  :graph => GRAPH,
46
49
  :g => GRAPH,
47
50
  :qgraph => QGRAPH,
@@ -55,6 +58,4 @@ module Configuration
55
58
  :base64 => BASE64,
56
59
  :b64 => BASE64,
57
60
  }
58
-
59
- end
60
61
  end
@@ -1,9 +1,8 @@
1
1
  module BaseConvert
2
2
  class FromTo
3
- include Configuration
4
3
  include BaseConvert
5
4
 
6
- def initialize(base: 10, to_base: base, digits: WORD, to_digits: digits)
5
+ def initialize(base: 10, to_base: base, digits: G94, to_digits: digits)
7
6
  base = BASE[base] if base.is_a? Symbol
8
7
  to_base = BASE[to_base] if to_base.is_a? Symbol
9
8
  digits = DIGITS[digits] if digits.is_a? Symbol
@@ -1,129 +1,86 @@
1
1
  module BaseConvert
2
2
  class Number
3
- include Configuration
4
3
  include BaseConvert
5
4
 
6
- def _infer_digits_from_string
7
- if @string.chars.all?{|_|WORD_.include?_}
8
- @string.include?('_')? WORD_ : WORD
9
- elsif @string.chars.all?{|_|GRAPH.include?_}
10
- @string.match?(/['"`]/)? GRAPH : QGRAPH
11
- else
12
- raise "Need digits."
5
+ def self.infer(string)
6
+ return 2, G94 if string.empty?
7
+ chars = string.chars
8
+ raise 'Need digits.' unless chars.all?{|_|G94.include?_}
9
+ max = chars.map{|_|G94.index(_)}.max
10
+ return 2, G94 if max < 2
11
+ return 4, G94 if max < 4
12
+ return 8, G94 if max < 8
13
+ return 10, G94 if max < 10
14
+ return 16, G94 if max < 16
15
+ return 32, G94 if max < 32
16
+ [UNAMBIGUOUS, BASE64].each do |digits|
17
+ return digits.length, digits if chars.all?{|_|digits.include?_}
13
18
  end
19
+ return 64, G94 if max < 64
20
+ return G94.length, G94 if max < 64
14
21
  end
15
22
 
16
- def _infer_base_from_string
17
- min = 1 + @digits.index(@string.chars.max)
18
- max = @digits.length
19
- return max if max==min
20
- case @digits
21
- when WORD, WORD_
22
- if min <= 32
23
- raise "Need base for WORD or WORD_." if @string.length < 8
24
- return 8 if min <= 8
25
- return 16 if min <= 16
26
- return 32
27
- end
28
- when UNAMBIGUOUS
29
- if min <= 22
30
- raise "Need base for UNAMBIGUOUS." if @string.length < 8
31
- return 22
32
- end
33
- when QGRAPH, GRAPH
34
- n = @digits.index 'a'
35
- if min <= n
36
- raise "Need base for QGRAPH or GRAPH." if @string.length < 8
37
- return n
38
- end
39
- end
40
- return max
41
- end
42
-
43
- def _digits!
44
- if @digits.nil?
45
- @digits = @integer.nil? ? _infer_digits_from_string : WORD
46
- if @base and @base > @digits.length
47
- if @base == 64
48
- @digits = BASE64
49
- elsif @base <= QGRAPH.length
50
- @digits = QGRAPH
51
- elsif @base <= GRAPH.length
52
- @digits = GRAPH
53
- else
54
- raise "Need digits that can cover base #{@base}."
55
- end
56
- end
23
+ attr_reader :base, :digits
24
+ def initialize(counter=0, base: nil, digits: nil, validate: true)
25
+ # validate
26
+ case validate
27
+ when true, false
28
+ @validate = validate
57
29
  else
58
- if @digits.is_a? Symbol
59
- digits = DIGITS[@digits]
60
- raise "Unrecognized digits #{@digits}." if digits.nil?
61
- @digits = digits
62
- else
63
- raise "digits must be a String of at least length 2." unless @digits.is_a?(String) and @digits.length > 1
64
- end
30
+ raise "validate must be either true of false."
65
31
  end
66
- end
67
32
 
68
- def _base!
69
- if @base.nil?
70
- _digits!
71
- if @integer.nil?
72
- @base = _infer_base_from_string
73
- else
74
- @base = @digits.length
75
- end
33
+ # counter
34
+ case counter
35
+ when String
36
+ @string = counter
37
+ base, digits = Number.infer(counter) if base.nil? and digits.nil?
38
+ when Integer
39
+ @integer = counter
40
+ base, digits = 10, G94 if base.nil? and digits.nil?
76
41
  else
77
- if @base.is_a? Symbol
78
- base = BASE[@base]
79
- raise "Unrecognized base #{@base}." if base.nil?
80
- @base = base
81
- else
82
- raise "base must be an Integer greater than 1." unless @base.is_a?(Integer) and @base > 1
83
- end
84
- _digits!
42
+ raise "Need counter String|Integer."
85
43
  end
86
- end
87
44
 
88
- def _validate
89
- raise "digits must cover base." if @base > @digits.length
90
- raise "digits must not have duplicates." if @digits.length > @digits.chars.uniq.length
91
- unless @string.nil?
92
- raise "digits must cover string." unless @string.chars.all?{|_|@digits.include?_}
93
- raise "digits in string must be under base." unless @base > @digits.index(@string.chars.max)
45
+ # digits
46
+ if digits.is_a? Symbol
47
+ digits = DIGITS[digits]
48
+ raise "Unrecognized digits." if digits.nil?
94
49
  end
95
- unless @integer.nil?
96
- raise "integer can't be negative." if @integer < 0
50
+ digits = DIGITS[base] if digits.nil?
51
+ digits = G94 if digits.nil?
52
+ raise "digits must be a String of at least length 2." unless digits.is_a?(String) and digits.length > 1
53
+ @digits = digits
54
+
55
+ # base
56
+ if base.is_a? Symbol
57
+ base = BASE[base]
58
+ raise "Unrecognized base." if base.nil?
97
59
  end
98
- end
60
+ base = @digits.length if base.nil?
61
+ raise "base must be an Integer greater than 1." unless base.is_a?(Integer) and base > 1
62
+ @base = base
99
63
 
100
- def _integer!
101
- _base!
102
- @string.upcase! if @base <= INDEXa and @digits == WORD
103
- _validate if @validate
104
- @integer = toi
105
- end
64
+ # validate
65
+ if @validate
66
+ raise "digits must cover base." if @base > @digits.length
67
+ raise "digits must not have duplicates." if @digits.length > @digits.chars.uniq.length
68
+ unless @string.nil? or @string.empty?
69
+ @string.upcase! if @base <= INDEXa and @digits.equal? G94
70
+ raise "digits must cover string." unless @string.chars.all?{|_|@digits.include?_}
71
+ raise "digits in string must be under base." unless @base > @string.chars.map{|_|@digits.index(_)}.max
72
+ end
73
+ unless @integer.nil?
74
+ raise "integer can't be negative." if @integer < 0
75
+ end
76
+ end
106
77
 
107
- def _string!
108
- _base!
109
- _validate if @validate
110
- @string = tob
78
+ @integer = toi if @integer.nil?
79
+ @string = tob if @string.nil?
111
80
  end
112
81
 
113
- attr_reader :base, :digits
114
- def initialize(counter, base: nil, digits: nil, validate: true)
115
- @base, @digits, @validate = base, digits, validate
116
- @string, @integer = nil, nil
117
- case counter
118
- when String
119
- @string = counter
120
- _integer!
121
- when Integer
122
- @integer = counter
123
- _string!
124
- else
125
- raise "Need counter String|Integer."
126
- end
82
+ def validate?
83
+ @validate
127
84
  end
128
85
 
129
86
  def to_s
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base_convert
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.191224
4
+ version: 3.1.191231
5
5
  platform: ruby
6
6
  authors:
7
7
  - carlosjhr64
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-24 00:00:00.000000000 Z
11
+ date: 2019-12-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  BaseConvert - Number base conversion.
@@ -24,6 +24,7 @@ extra_rdoc_files: []
24
24
  files:
25
25
  - README.md
26
26
  - lib/base_convert.rb
27
+ - lib/base_convert/base_convert.rb
27
28
  - lib/base_convert/configuration.rb
28
29
  - lib/base_convert/from_to.rb
29
30
  - lib/base_convert/number.rb
@@ -46,8 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
47
  - !ruby/object:Gem::Version
47
48
  version: '0'
48
49
  requirements:
49
- - 'ruby: ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]'
50
- rubygems_version: 3.0.3
50
+ - 'ruby: ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]'
51
+ rubygems_version: 3.1.2
51
52
  signing_key:
52
53
  specification_version: 4
53
54
  summary: BaseConvert - Number base conversion.