base_convert 3.0.191224 → 3.1.191231

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.