b85 0.1.0

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/base85.rb +173 -0
  3. metadata +39 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e10be63f2323e78941ef9559027cf15f58fd99848e2e671b81e0f08060d8db9b
4
+ data.tar.gz: 56d5d0c13f3de2458b1050b8293a0f9d273390a5774f5ae588d5efb2fb8055c7
5
+ SHA512:
6
+ metadata.gz: 5a8e9f77d8b4dfa4e489b8a4b4ae6a2e3835073e90a1552c5365ff93555dc35173797708c815418db68abc3632c6e1dbfc9622dec17bf15b571f22745660fee6
7
+ data.tar.gz: b76986e07c53d341803aeccfe348022b4bedb64665fc0174c73c4433ba8082bf8d7c102ee8409e4ad3d6e6f48a04b79bf992c31f7974279eedce9e4041f30574
data/lib/base85.rb ADDED
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Base85
4
+ P, P2, P3, P4 = 85, 85 ** 2, 85 ** 3, 85 ** 4
5
+ B, B4 = 256, 256 ** 4
6
+
7
+ attr_reader :chars
8
+
9
+ def initialize(chars, &block)
10
+ @chars = chars.dup.freeze
11
+
12
+ f = chars.unpack('C*')
13
+ if f.size != 85 || f.uniq.size != f.size
14
+ raise ArgumentError
15
+ end
16
+ f.freeze
17
+ @forward_table = f
18
+
19
+ g = Array.new(256)
20
+ f.each_with_index do |v, i|
21
+ g[v] = i
22
+ end
23
+ g.freeze
24
+ @backward_table = g
25
+
26
+ if block
27
+ singleton_class.class_eval(&block)
28
+ end
29
+ end
30
+
31
+ def encode(str)
32
+ enc = str.encoding
33
+ t = str.b
34
+
35
+ l = t.size
36
+ if l % 4 != 0
37
+ t += "\0" * (4 - l % 4)
38
+ end
39
+
40
+ f = @forward_table
41
+ s = ''.b
42
+ t.unpack('N*') do |v|
43
+ s << f[v / P4] \
44
+ << f[v / P3 % P] \
45
+ << f[v / P2 % P] \
46
+ << f[v / P % P] \
47
+ << f[v % P]
48
+ end
49
+ s[s.size - (t.size - l)..-1] = ''
50
+
51
+ if enc.ascii_compatible?
52
+ s.force_encoding(enc)
53
+ end
54
+ s
55
+ end
56
+
57
+ def decode(str)
58
+ enc = str.encoding
59
+ s = str.b
60
+
61
+ l = s.size
62
+ if l % 5 == 1
63
+ raise ArgumentError, 'illegal length'
64
+ end
65
+ if l % 5 != 0
66
+ s += @forward_table[84].chr * (5 - l % 5)
67
+ end
68
+ s = s.bytes
69
+ if !(Array === s)
70
+ s = s.unpack('C*')
71
+ end
72
+
73
+ g = @backward_table
74
+ r = []
75
+ 0.step(s.size - 1, 5) do |i|
76
+ begin
77
+ v = g[s[i]] * P4 \
78
+ + g[s[i + 1]] * P3 \
79
+ + g[s[i + 2]] * P2 \
80
+ + g[s[i + 3]] * P \
81
+ + g[s[i + 4]]
82
+ rescue NoMethodError
83
+ raise ArgumentError, 'invalid char'
84
+ end
85
+ if v >= B4
86
+ raise ArgumentError, 'invalid value'
87
+ end
88
+ r << v
89
+ end
90
+
91
+ m = s.size - l
92
+ if m != 0 && r[-1] % B ** m >= P ** m
93
+ raise ArgumentError, 'bad representation'
94
+ end
95
+ t = r.pack('N*')
96
+ t[t.size - m..-1] = ''
97
+
98
+ t.force_encoding(enc)
99
+ if !t.valid_encoding?
100
+ t.force_encoding(Encoding::ASCII_8BIT)
101
+ end
102
+ t
103
+ end
104
+
105
+ def to_s
106
+ sym = self.class.constants.find { |sym|
107
+ self.class.const_get(sym).equal?(self)
108
+ }
109
+ sym ? "#{self.class}::#{sym}" : super
110
+ end
111
+
112
+ alias inspect to_s
113
+ alias name to_s
114
+
115
+ Z85 = new(%w[
116
+ 0123456789
117
+ abcdefghij
118
+ klmnopqrst
119
+ uvwxyzABCD
120
+ EFGHIJKLMN
121
+ OPQRSTUVWX
122
+ YZ.-:+=^!/
123
+ *?&<>()[]{
124
+ }@%$#
125
+ ].join)
126
+
127
+ Rfc1924 = new(%w[
128
+ 0123456789
129
+ ABCDEFGHIJ
130
+ KLMNOPQRST
131
+ UVWXYZabcd
132
+ efghijklmn
133
+ opqrstuvwx
134
+ yz!#$%&()*
135
+ +-;<=>?@^_
136
+ `{|}~
137
+ ].join)
138
+
139
+ Ascii85 = new([*'!'..'u'].join) do
140
+ def encode(str)
141
+ t = super(str)
142
+ enc = t.encoding
143
+ t = t.b
144
+ s = ''.b
145
+ k = 0
146
+ while k < t.size
147
+ i = k
148
+ loop do
149
+ i = t.index('!!!!!', i)
150
+ if i.nil? || i % 5 == 0
151
+ break
152
+ end
153
+ i += 5 - i % 5
154
+ end
155
+ if i.nil?
156
+ s << t[k..-1]
157
+ break
158
+ end
159
+ s << t[k...i] << 'z'
160
+ k = i + 5
161
+ end
162
+ s.force_encoding(enc)
163
+ end
164
+
165
+ def decode(str, ignore_spaces = true)
166
+ if ignore_spaces
167
+ str = str.delete("\0\t\n\v\f\r ")
168
+ end
169
+ str = str.gsub('z', '!!!!!')
170
+ super(str)
171
+ end
172
+ end
173
+ end
metadata ADDED
@@ -0,0 +1,39 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: b85
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - flosacca
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ email: flosacca@gmail.com
13
+ executables: []
14
+ extensions: []
15
+ extra_rdoc_files: []
16
+ files:
17
+ - lib/base85.rb
18
+ homepage: https://github.com/flosacca/base85
19
+ licenses:
20
+ - MIT
21
+ metadata: {}
22
+ rdoc_options: []
23
+ require_paths:
24
+ - lib
25
+ required_ruby_version: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.0
30
+ required_rubygems_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ requirements: []
36
+ rubygems_version: 3.7.2
37
+ specification_version: 4
38
+ summary: Define your own Base85
39
+ test_files: []