Module: Philiprehberger::BaseConvert
- Defined in:
- lib/philiprehberger/base_convert.rb,
lib/philiprehberger/base_convert/base32.rb,
lib/philiprehberger/base_convert/base58.rb,
lib/philiprehberger/base_convert/base62.rb,
lib/philiprehberger/base_convert/base85.rb,
lib/philiprehberger/base_convert/version.rb
Defined Under Namespace
Modules: Base32, Base58, Base62, Base85 Classes: Error
Constant Summary collapse
- GENERIC_ALPHABET =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'- HEX_ALPHABET =
'0123456789abcdefABCDEF'- BASE64_ALPHABET =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-_'- BASE85_ALPHABET =
"#{(33..117).map(&:chr).join}z".freeze
- DETECTION_ORDER =
[ [:hex, HEX_ALPHABET], [:base32, Base32::DECODE_MAP.keys.join], [:base58, Base58::ALPHABET], [:base62, Base62::ALPHABET], [:base64, BASE64_ALPHABET], [:base85, BASE85_ALPHABET] ].map { |name, chars| [name, chars.each_char.to_a.to_set] }.freeze
- VERSION =
'0.6.0'
Class Method Summary collapse
-
.base32_decode(string) ⇒ String
Decode a Crockford Base32 string.
-
.base32_encode(string) ⇒ String
Encode a string to Crockford Base32.
-
.base36_decode(string) ⇒ Integer
Decode a Base36 string to an integer.
-
.base36_encode(integer) ⇒ String
Encode an integer to Base36.
-
.base58_decode(string) ⇒ String
Decode a Base58 string.
-
.base58_decode_int(string) ⇒ Integer
Decode a Base58 string to an integer.
-
.base58_encode(string) ⇒ String
Encode a string to Base58 (Bitcoin alphabet).
-
.base58_encode_int(integer) ⇒ String
Encode a non-negative integer to Base58 (Bitcoin alphabet).
-
.base62_decode(string) ⇒ Integer
Decode a Base62 string to an integer.
-
.base62_encode(integer) ⇒ String
Encode an integer to Base62.
-
.base85_decode(string) ⇒ String
Decode an ASCII85 string.
-
.base85_encode(string) ⇒ String
Encode a string to ASCII85.
-
.decode(string, base:) ⇒ Integer
Decode a string from an arbitrary base (2-62) to an integer.
-
.detect(string) ⇒ Symbol?
Detect the encoding of a string based on its character set.
-
.encode(integer, base:) ⇒ String
Encode an integer in an arbitrary base (2-62).
-
.hex_decode(string) ⇒ String
Decode a hexadecimal string.
-
.hex_encode(string) ⇒ String
Encode a string to hexadecimal.
-
.valid?(string, base) ⇒ Boolean
Check whether a string is syntactically valid for the given base.
Class Method Details
.base32_decode(string) ⇒ String
Decode a Crockford Base32 string
130 131 132 |
# File 'lib/philiprehberger/base_convert.rb', line 130 def self.base32_decode(string) Base32.decode(string) end |
.base32_encode(string) ⇒ String
Encode a string to Crockford Base32
121 122 123 |
# File 'lib/philiprehberger/base_convert.rb', line 121 def self.base32_encode(string) Base32.encode(string) end |
.base36_decode(string) ⇒ Integer
Decode a Base36 string to an integer
165 166 167 |
# File 'lib/philiprehberger/base_convert.rb', line 165 def self.base36_decode(string) decode(string, base: 36) end |
.base36_encode(integer) ⇒ String
Encode an integer to Base36
156 157 158 |
# File 'lib/philiprehberger/base_convert.rb', line 156 def self.base36_encode(integer) encode(integer, base: 36) end |
.base58_decode(string) ⇒ String
Decode a Base58 string
77 78 79 |
# File 'lib/philiprehberger/base_convert.rb', line 77 def self.base58_decode(string) Base58.decode(string) end |
.base58_decode_int(string) ⇒ Integer
Decode a Base58 string to an integer
95 96 97 |
# File 'lib/philiprehberger/base_convert.rb', line 95 def self.base58_decode_int(string) Base58.decode_int(string) end |
.base58_encode(string) ⇒ String
Encode a string to Base58 (Bitcoin alphabet)
68 69 70 |
# File 'lib/philiprehberger/base_convert.rb', line 68 def self.base58_encode(string) Base58.encode(string) end |
.base58_encode_int(integer) ⇒ String
Encode a non-negative integer to Base58 (Bitcoin alphabet)
86 87 88 |
# File 'lib/philiprehberger/base_convert.rb', line 86 def self.base58_encode_int(integer) Base58.encode_int(integer) end |
.base62_decode(string) ⇒ Integer
Decode a Base62 string to an integer
113 114 115 |
# File 'lib/philiprehberger/base_convert.rb', line 113 def self.base62_decode(string) Base62.decode(string) end |
.base62_encode(integer) ⇒ String
Encode an integer to Base62
104 105 106 |
# File 'lib/philiprehberger/base_convert.rb', line 104 def self.base62_encode(integer) Base62.encode(integer) end |
.base85_decode(string) ⇒ String
Decode an ASCII85 string
147 148 149 |
# File 'lib/philiprehberger/base_convert.rb', line 147 def self.base85_decode(string) Base85.decode(string) end |
.base85_encode(string) ⇒ String
Encode a string to ASCII85
138 139 140 |
# File 'lib/philiprehberger/base_convert.rb', line 138 def self.base85_encode(string) Base85.encode(string) end |
.decode(string, base:) ⇒ Integer
Decode a string from an arbitrary base (2-62) to an integer
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/philiprehberger/base_convert.rb', line 224 def self.decode(string, base:) raise Error, 'base must be between 2 and 62' unless base.between?(2, 62) raise Error, 'input must be a non-empty string' if string.nil? || string.empty? alphabet = GENERIC_ALPHABET[0, base] num = 0 string.each_char do |char| value = alphabet.index(char) raise Error, "invalid character for base #{base}: #{char}" if value.nil? num = (num * base) + value end num end |
.detect(string) ⇒ Symbol?
Detect the encoding of a string based on its character set
Returns the narrowest base whose alphabet fully covers the input. Empty strings and strings that match no known base return nil.
37 38 39 40 41 42 43 |
# File 'lib/philiprehberger/base_convert.rb', line 37 def self.detect(string) return nil if string.nil? || string.empty? unique_chars = string.each_char.to_a.to_set match = DETECTION_ORDER.find { |(_name, alphabet)| unique_chars.subset?(alphabet) } match&.first end |
.encode(integer, base:) ⇒ String
Encode an integer in an arbitrary base (2-62)
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/philiprehberger/base_convert.rb', line 200 def self.encode(integer, base:) raise Error, 'base must be between 2 and 62' unless base.between?(2, 62) raise Error, 'input must be a non-negative integer' unless integer.is_a?(Integer) && integer >= 0 return GENERIC_ALPHABET[0] if integer.zero? alphabet = GENERIC_ALPHABET[0, base] result = [] num = integer while num.positive? num, remainder = num.divmod(base) result << alphabet[remainder] end result.reverse.join end |
.hex_decode(string) ⇒ String
Decode a hexadecimal string
185 186 187 188 189 190 191 192 |
# File 'lib/philiprehberger/base_convert.rb', line 185 def self.hex_decode(string) raise Error, 'input cannot be nil' if string.nil? raise Error, 'input cannot be empty' if string.empty? raise Error, 'invalid hex string: odd length' if string.length.odd? raise Error, "invalid hex character in: #{string}" unless string.match?(/\A[0-9a-fA-F]+\z/) [string].pack('H*') end |
.hex_encode(string) ⇒ String
Encode a string to hexadecimal
174 175 176 177 178 |
# File 'lib/philiprehberger/base_convert.rb', line 174 def self.hex_encode(string) raise Error, 'input cannot be nil' if string.nil? string.unpack1('H*') end |
.valid?(string, base) ⇒ Boolean
Check whether a string is syntactically valid for the given base
Returns true when every character in the string is part of the given base’s alphabet. Empty/nil input and unknown bases return false. Does not perform a decode — purely a character-set check.
54 55 56 57 58 59 60 61 62 |
# File 'lib/philiprehberger/base_convert.rb', line 54 def self.valid?(string, base) return false if string.nil? || !string.is_a?(String) || string.empty? entry = DETECTION_ORDER.find { |(name, _)| name == base } return false unless entry alphabet = entry.last string.each_char.to_a.to_set.subset?(alphabet) end |