base58-alphabets 0.0.1 → 0.1.0

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: 93de3aafa549247ab62457454bfcd47c62e718314c8a7ecb6057160c0b317755
4
- data.tar.gz: 9e74c2d2b9106b54be273b22a97dff3a8055cd66ac3ce1d85f5b84a18058ba30
3
+ metadata.gz: 000b32a445c54f6eb556e6b6c3804bfa2d4df87c1caef2ff001b10a714b38403
4
+ data.tar.gz: 2984225c57d1514eb716eaddfb07d66079ba7edcfacf9f722ecfcf22e84015e0
5
5
  SHA512:
6
- metadata.gz: 4ce2677b5f3f6f7c8a4f01014cc29d2888c9bcab241576c3780c95c53b9fe70c8796f97f1fcad3acdcf8a6ee35542db4efb4919d5204688c58c25319d95011e6
7
- data.tar.gz: da0dabbb21e0c3c98bddf912cadc0a06f31cd52f2a56e06f72cb2f9bb09e8c9bbf3b11398d07a51f64f30070703a6b4ad613e19d72169d9172a376b82536f0cc
6
+ metadata.gz: 9a71c550deb538e9928a743103435b5ac7c4f544e7d806529a84a52d4e76ff9ee49ccab0d33602a5deff93511dc92dede5e954697aa9cce59eef4c9da3c118dd
7
+ data.tar.gz: 579c12f8837066b4f4265df52ff36108341a6d290a60d152a195d532171b7fa92cc0d2da58039cd1ce4babe5ab1ac90e85865619cf01ce251193d55cd5b16ead
@@ -3,4 +3,9 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/base58-alphabets.rb
6
+ lib/base58-alphabets/base.rb
7
+ lib/base58-alphabets/base58.rb
8
+ lib/base58-alphabets/bitcoin.rb
6
9
  lib/base58-alphabets/version.rb
10
+ test/helper.rb
11
+ test/test_base58_bitcoin.rb
data/README.md CHANGED
@@ -11,6 +11,67 @@ Encode / decode numbers with Bitcoin or Flickr base58 notation / alphabet
11
11
 
12
12
 
13
13
 
14
+ ## What's Base 58?
15
+
16
+
17
+ > Similar to Base64, but modified to avoid both non-alphanumeric
18
+ > characters (`+` and `/`) and letters which might look ambiguous
19
+ > when printed (`0` - zero, `I` - capital i, `O` - capital o and `l` - lower case L).
20
+ > Satoshi Nakamoto invented the base58 encoding scheme when creating bitcoin.
21
+ > Some messaging and social media systems line break on non-alphanumeric
22
+ > strings. This is avoided by not using URI reserved characters such as `+`.
23
+ >
24
+ > (Source: [Base58 @ Wikipedia](https://en.wikipedia.org/wiki/Binary-to-text_encoding#Base58))
25
+
26
+
27
+
28
+ ## Bitcoin
29
+
30
+ The bitcoin notation / alphabet (`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`)
31
+
32
+
33
+ Triva Quiz: What characters (digits/letters) are
34
+ missing in the base 56 alphabets?
35
+
36
+ - `0` (Zero), `O` (Upper-O), `I` (Upper-I), `l` (Lower-L)
37
+
38
+ Why use base56 (and not "standard" base64)?
39
+
40
+ ```
41
+ // - Don't want 0OIl characters that look the same in some fonts and
42
+ // could be used to create visually identical looking account numbers.
43
+ // - A string with non-alphanumeric characters is not as easily accepted as an account number.
44
+ // - E-mail usually won't line-break if there's no punctuation to break at.
45
+ // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
46
+ ```
47
+
48
+ (Source: `base58.h` - Bitcoin Source Code Header Comments)
49
+
50
+
51
+
52
+ ### Bitcoin (Base58) Notation
53
+
54
+ |Num |Character |Num |Character |Num |Character |Num |Character|
55
+ |----:|----------:|----:|----------:|----:|----------:|----:|--------:|
56
+ | 0 | **1** | 1 | **2** | 2 | **3** | 3 | **4** |
57
+ | 4 | **5** | 5 | **6** | 6 | **7** | 7 | **8** |
58
+ | 8 | **9** | 9 | **A** | 10 | **B** | 11 | **C** |
59
+ | 12 | **D** | 13 | **E** | 14 | **F** | 15 | **G** |
60
+ | 16 | **H** | 17 | **J** | 18 | **K** | 19 | **L** |
61
+ | 20 | **M** | 21 | **N** | 22 | **P** | 23 | **Q** |
62
+ | 24 | **R** | 25 | **S** | 26 | **T** | 27 | **U** |
63
+ | 28 | **V** | 29 | **W** | 30 | **X** | 31 | **Y** |
64
+ | 32 | **Z** | 33 | **a** | 34 | **b** | 35 | **c** |
65
+ | 36 | **d** | 37 | **e** | 38 | **f** | 39 | **g** |
66
+ | 40 | **h** | 41 | **i** | 42 | **j** | 43 | **k** |
67
+ | 44 | **m** | 45 | **n** | 46 | **o** | 47 | **p** |
68
+ | 48 | **q** | 49 | **r** | 50 | **s** | 51 | **t** |
69
+ | 52 | **u** | 53 | **v** | 54 | **w** | 55 | **x** |
70
+ | 56 | **y** | 57 | **z** |
71
+
72
+
73
+
74
+
14
75
 
15
76
  ## License
16
77
 
@@ -6,9 +6,9 @@ require 'pp'
6
6
  ## our own code
7
7
  require 'base58-alphabets/version' # note: let version always go first
8
8
 
9
-
10
-
11
-
9
+ require 'base58-alphabets/base'
10
+ require 'base58-alphabets/bitcoin'
11
+ require 'base58-alphabets/base58'
12
12
 
13
13
 
14
14
 
@@ -0,0 +1,41 @@
1
+ #########
2
+ # shared code for formats / variants with single char alphabets
3
+ # e.g. Bitcoin, Flickr, ...
4
+
5
+ module Base58
6
+ class Base
7
+
8
+ # Converts a base10 integer to a base58 string.
9
+ def self.encode( num_or_bytes )
10
+ if num_or_bytes.is_a?( Array )
11
+ bytes = num_or_bytes
12
+ else
13
+ num = num_or_bytes
14
+ bytes = Base58._bytes( num )
15
+ end
16
+
17
+ bytes.reduce( String.new ) do |buf, byte|
18
+ buf << alphabet[byte]
19
+ buf
20
+ end
21
+ end
22
+
23
+
24
+ # Converts a base58 string to a base10 integer.
25
+ def self.decode( str_or_bytes )
26
+ if str_or_bytes.is_a?( Array )
27
+ bytes = str_or_bytes
28
+ else ## assume string
29
+ str = str_or_bytes
30
+ bytes = str.each_char.reduce([]) do |bytes,char|
31
+ byte = number[char]
32
+ raise ArgumentError, "Value passed not a valid base58 string - >#{char}< not found in alphabet" if byte.nil?
33
+ bytes << byte
34
+ bytes
35
+ end
36
+ end
37
+ Base58._pack( bytes )
38
+ end
39
+
40
+ end # class Base
41
+ end # module Base58
@@ -0,0 +1,85 @@
1
+ module Base58
2
+
3
+ BASE = 58 # ALPHABET.length == 58 ## 58 chars/letters/digits
4
+
5
+ class Configuration
6
+
7
+ MAPPING = {
8
+ bitcoin: Bitcoin,
9
+ ## flickr: Flickr,
10
+ }
11
+
12
+ attr_reader :format
13
+
14
+ def initialize
15
+ @format = Bitcoin
16
+ end
17
+
18
+ def format=(value)
19
+ if value.is_a?( Symbol )
20
+ @format = MAPPING[ value ]
21
+ else ## assume class
22
+ @format = value
23
+ end
24
+ end
25
+ end # class Configuration
26
+
27
+ ## lets you use
28
+ ## Base58.configure do |config|
29
+ ## config.format = :bitcoin
30
+ ## end
31
+
32
+ def self.configuration
33
+ @configuration ||= Configuration.new
34
+ end
35
+
36
+ def self.configure
37
+ yield( configuration )
38
+ end
39
+
40
+ ## add convenience helper for format
41
+ def self.format() configuration.format; end
42
+ def self.format=(value) self.configuration.format = value; end
43
+
44
+
45
+
46
+
47
+ def self.encode( num_or_bytes, klass: configuration.format )
48
+ klass.encode( num_or_bytes )
49
+ end
50
+
51
+ def self.decode( str_or_bytes, klass: configuration.format )
52
+ klass.decode( str_or_bytes )
53
+ end
54
+
55
+
56
+
57
+
58
+ ####
59
+ # (private) helper - note: leading underscore in name e.g. _bytes
60
+ def self._bytes( num )
61
+ b = []
62
+ while num >= BASE
63
+ mod = num % BASE
64
+ b << mod
65
+ num = (num - mod) / BASE
66
+ end
67
+ b << num
68
+ b = b.reverse
69
+ b
70
+ end
71
+
72
+ def self._pack( bytes )
73
+ num = 0
74
+ bytes.reverse.each_with_index do |byte,index|
75
+ num += byte * (BASE**(index))
76
+ end
77
+ num
78
+ end
79
+
80
+ ## encoding alphabet - letter-to-number by index / array
81
+ def self.alphabet( klass: configuration.format ) klass.alphabet; end
82
+
83
+ ## decoding letter-to-number mapping / hash
84
+ def self.number( klass: configuration.format ) klass.number; end
85
+ end # module Base58
@@ -0,0 +1,85 @@
1
+
2
+
3
+ module Base58
4
+ class Bitcoin < Base
5
+
6
+ ALPHABET = %w[ 1 2 3 4 5 6 7 8 9
7
+ A B C D E F G H J K L M N P Q R S T U V W X Y Z
8
+ a b c d e f g h i j k m n o p q r s t u v w x y z ]
9
+
10
+
11
+ def self.alphabet() ALPHABET; end ## add alpha / char aliases - why? why not?
12
+
13
+ ## Note:
14
+ ## for decoding allow (misspelled) l/I for 1 - why? why not?
15
+ ## and (misspelled) 0/O for o - why? why not?
16
+
17
+
18
+ NUMBER = {
19
+ '1' => 0, ## 'l' => 0, 'I' => 0,
20
+ '2' => 1,
21
+ '3' => 2,
22
+ '4' => 3,
23
+ '5' => 4,
24
+ '6' => 5,
25
+ '7' => 6,
26
+ '8' => 7,
27
+ '9' => 8,
28
+ 'A' => 9,
29
+ 'B' => 10,
30
+ 'C' => 11,
31
+ 'D' => 12,
32
+ 'E' => 13,
33
+ 'F' => 14,
34
+ 'G' => 15,
35
+ 'H' => 16,
36
+ 'J' => 17,
37
+ 'K' => 18,
38
+ 'L' => 19,
39
+ 'M' => 20,
40
+ 'N' => 21,
41
+ 'P' => 22,
42
+ 'Q' => 23,
43
+ 'R' => 24,
44
+ 'S' => 25,
45
+ 'T' => 26,
46
+ 'U' => 27,
47
+ 'V' => 28,
48
+ 'W' => 29,
49
+ 'X' => 30,
50
+ 'Y' => 31,
51
+ 'Z' => 32,
52
+ 'a' => 33,
53
+ 'b' => 34,
54
+ 'c' => 35,
55
+ 'd' => 36,
56
+ 'e' => 37,
57
+ 'f' => 38,
58
+ 'g' => 39,
59
+ 'h' => 40,
60
+ 'i' => 41,
61
+ 'j' => 42,
62
+ 'k' => 43,
63
+ 'm' => 44,
64
+ 'n' => 45,
65
+ 'o' => 46, ## '0' => 46, 'O' => 46,
66
+ 'p' => 47,
67
+ 'q' => 48,
68
+ 'r' => 49,
69
+ 's' => 50,
70
+ 't' => 51,
71
+ 'u' => 52,
72
+ 'v' => 53,
73
+ 'w' => 54,
74
+ 'x' => 55,
75
+ 'y' => 56,
76
+ 'z' => 57,
77
+ }
78
+
79
+ def self.number() NUMBER; end ## add num alias - why? why not?
80
+
81
+ ## add shortcuts (convenience) aliases
82
+ NUM = NUMBER
83
+
84
+ end # class Bitcoin
85
+ end # module Base58
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Base58
4
4
  MAJOR = 0
5
- MINOR = 0
6
- PATCH = 1
5
+ MINOR = 1
6
+ PATCH = 0
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
@@ -0,0 +1,10 @@
1
+ ## $:.unshift(File.dirname(__FILE__))
2
+
3
+ ## minitest setup
4
+
5
+ require 'minitest/autorun'
6
+
7
+
8
+ ## our own code
9
+
10
+ require 'base58-alphabets'
@@ -0,0 +1,34 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_base58_bitcoin.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestBase58Bitcoin < MiniTest::Test
10
+
11
+
12
+ def test_bitcoin
13
+ assert_equal "2j", Base58::Bitcoin.encode( 100 )
14
+ assert_equal "4fr", Base58::Bitcoin.encode( 12345 )
15
+ assert_equal "b2pH", Base58::Bitcoin.encode( 6639914 )
16
+
17
+ assert_equal 100, Base58::Bitcoin.decode( "2j" )
18
+ assert_equal 12345, Base58::Bitcoin.decode( "4fr" )
19
+ assert_equal 6639914, Base58::Bitcoin.decode( "b2pH" )
20
+
21
+
22
+ Base58.format = :bitcoin
23
+ assert_equal "2j", Base58.encode( 100 )
24
+ assert_equal "4fr", Base58.encode( 12345 )
25
+ assert_equal "b2pH", Base58.encode( 6639914 )
26
+
27
+ assert_equal 100, Base58.decode( "2j" )
28
+ assert_equal 12345, Base58.decode( "4fr" )
29
+ assert_equal 6639914, Base58.decode( "b2pH" )
30
+ end
31
+
32
+
33
+
34
+ end # class TestBase58Bitcoin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base58-alphabets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -59,7 +59,12 @@ files:
59
59
  - README.md
60
60
  - Rakefile
61
61
  - lib/base58-alphabets.rb
62
+ - lib/base58-alphabets/base.rb
63
+ - lib/base58-alphabets/base58.rb
64
+ - lib/base58-alphabets/bitcoin.rb
62
65
  - lib/base58-alphabets/version.rb
66
+ - test/helper.rb
67
+ - test/test_base58_bitcoin.rb
63
68
  homepage: https://github.com/rubycoco/blockchain
64
69
  licenses:
65
70
  - Public Domain