Module: KSUID::Base62

Defined in:
lib/ksuid/base62.rb

Overview

Converts between numbers and an alphanumeric encoding

We store and report KSUIDs as base 62-encoded numbers to make them lexicographically sortable and compact to transmit. The base 62 alphabet consists of the Arabic numerals, followed by the English capital letters and the English lowercase letters.

Constant Summary collapse

CHARSET =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The character set used to encode numbers into base 62

'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
BASE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The base (62) that this module encodes numbers into

CHARSET.size
MATCHER =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A matcher that checks whether a String has a character outside the charset

/[^#{CHARSET}]/.freeze

Class Method Summary collapse

Class Method Details

.compatible?(string) ⇒ Boolean

Checks whether a string is a base 62-compatible string

Examples:

Checks a KSUID for base 62 compatibility

KSUID::Base62.compatible?("15Ew2nYeRDscBipuJicYjl970D1") #=> true

Parameters:

  • string (String)

    the string to check for compatibility

Returns:

  • (Boolean)


37
38
39
# File 'lib/ksuid/base62.rb', line 37

def self.compatible?(string)
  !MATCHER.match?(string)
end

.decode(ksuid) ⇒ Integer

Decodes a base 62-encoded string into an integer

Examples:

Decode a string into a number

KSUID::Base62.decode('0000000000000000000001LY7VK')
#=> 1234567890

Parameters:

  • ksuid (String)

    the base 62-encoded number

Returns:

  • (Integer)

    the decoded number as an integer



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ksuid/base62.rb', line 51

def self.decode(ksuid)
  result = 0

  ksuid.chars.each_with_index do |char, position|
    unless (digit = CHARSET.index(char))
      raise(ArgumentError, "#{ksuid} is not a base 62 number")
    end

    result += digit * (BASE**(ksuid.length - (position + 1)))
  end

  result
end

.encode(number) ⇒ String

Encodes a number (integer) as a base 62 string

Examples:

Encode a number as a base 62 string

KSUID::Base62.encode(1_234_567_890)
#=> "0000000000000000000001LY7VK"

Parameters:

  • number (Integer)

    the number to encode into base 62

Returns:

  • (String)

    the base 62-encoded number



75
76
77
78
79
80
# File 'lib/ksuid/base62.rb', line 75

def self.encode(number)
  chars = encode_without_padding(number)

  chars << padding if chars.empty?
  chars.reverse.join.rjust(STRING_LENGTH, padding)
end

.encode_bytes(bytes) ⇒ String

Encodes a byte string or byte array into base 62

Examples:

Encode a maximal KSUID as a string

KSUID::Base62.encode_bytes(
  [255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
   255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
)

Parameters:

  • bytes (String, Array<Integer>)

    the bytes to encode

Returns:

  • (String)

    the encoded bytes as a base 62 string



94
95
96
# File 'lib/ksuid/base62.rb', line 94

def self.encode_bytes(bytes)
  encode(Utils.int_from_bytes(bytes))
end