oak 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/CHANGELOG.md +10 -1
- data/DESIDERATA.md +9 -4
- data/DESIGN.md +410 -0
- data/ENCRYPTION.md +893 -0
- data/README.md +2 -6
- data/bin/oak +1 -0
- data/bin/oak.rb +122 -124
- data/lib/oak.rb +13 -0
- data/lib/oak/version.rb +1 -1
- metadata +5 -3
- data/bin/oak +0 -245
data/README.md
CHANGED
@@ -18,7 +18,7 @@ like String, Symbol, Integer, Float, Hash, and Array. OAK
|
|
18
18
|
serialization supports cyclical structures and distinguishes between
|
19
19
|
String and Symbol, but does not support user-defined types.
|
20
20
|
|
21
|
-
In
|
21
|
+
In `ALI` (copper.com's primary web service), OAK has found use cases in:
|
22
22
|
|
23
23
|
- Volatile Redis cache entries, where dynamic control of time-space
|
24
24
|
tradeoffs shaves down hosting costs.
|
@@ -151,11 +151,7 @@ For more details.
|
|
151
151
|
|
152
152
|
## TODO: packaging
|
153
153
|
|
154
|
-
-
|
155
|
-
- https://docs.google.com/document/d/10HVWuQzCw1Whc-czDChwsWPEZRLfyPS7F-dkjHWsIs4
|
156
|
-
- https://docs.google.com/document/d/1J7GBEJUPI3UeftJ4C-w3pbBUzk1pU0Sr6zcXufEi7NI
|
157
|
-
- https://docs.google.com/document/d/1SeOO18uqdDtHuB8tZ4-_2sql0Yiaco5J1PWdiu6gmAY
|
158
|
-
- edit comments down
|
154
|
+
- edit comments for length, content, and format
|
159
155
|
- rdoc
|
160
156
|
|
161
157
|
## Possible Future Directions for the Format
|
data/bin/oak
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bin/oak.rb
|
data/bin/oak.rb
CHANGED
@@ -103,143 +103,141 @@ Ruby 2.1.6 on Linux I get Encoding.default_encoding is US-ASCII!
|
|
103
103
|
|
104
104
|
=end
|
105
105
|
|
106
|
-
if
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
if OPTS[:
|
112
|
-
|
113
|
-
|
106
|
+
if OPTS[:self_test]
|
107
|
+
require 'rubydoctest'
|
108
|
+
exit RubyDocTest::Runner.new(File.read(__FILE__), __FILE__).run ? 0 : 1
|
109
|
+
end
|
110
|
+
if OPTS[:key_check]
|
111
|
+
if !OPTS[:key_chain]
|
112
|
+
puts "no --key-chain specified"
|
113
|
+
else
|
114
|
+
keys = oak_opts[:key_chain].keys.keys
|
115
|
+
if 0 == keys.size
|
116
|
+
puts "#{OPTS[:key_chain]}: no keys found"
|
114
117
|
else
|
115
|
-
|
116
|
-
if 0 == keys.size
|
117
|
-
puts "#{OPTS[:key_chain]}: no keys found"
|
118
|
-
else
|
119
|
-
puts "#{OPTS[:key_chain]}: found keys: #{keys.join(' ')}"
|
120
|
-
end
|
118
|
+
puts "#{OPTS[:key_chain]}: found keys: #{keys.join(' ')}"
|
121
119
|
end
|
122
120
|
end
|
123
|
-
|
124
|
-
|
121
|
+
end
|
122
|
+
if OPTS[:key_generate]
|
123
|
+
STDOUT.puts OAK.encode(OAK.random_key)
|
124
|
+
exit 0
|
125
|
+
end
|
126
|
+
if !$stdin.tty?
|
127
|
+
if OPTS[:eigen]
|
128
|
+
prev = STDIN.read
|
129
|
+
puts "input: %d" % prev.size
|
130
|
+
OPTS[:eigen].times do |i|
|
131
|
+
oak = OAK.encode(prev,oak_opts)
|
132
|
+
psize = prev.size
|
133
|
+
wsize = oak.size
|
134
|
+
ratio = 1.0 * wsize / psize
|
135
|
+
puts " iter %3d: %4d => %4d ratio %.2f" % [i,psize,wsize,ratio]
|
136
|
+
prev = oak
|
137
|
+
end
|
125
138
|
exit 0
|
126
139
|
end
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
oak = OAK.encode(prev,oak_opts)
|
133
|
-
psize = prev.size
|
134
|
-
wsize = oak.size
|
135
|
-
ratio = 1.0 * wsize / psize
|
136
|
-
puts " iter %3d: %4d => %4d ratio %.2f" % [i,psize,wsize,ratio]
|
137
|
-
prev = oak
|
138
|
-
end
|
139
|
-
exit 0
|
140
|
+
unhappiness = 0
|
141
|
+
case OPTS[:mode]
|
142
|
+
when 'cat'
|
143
|
+
ARGF.each_line.map(&:strip).each do |line|
|
144
|
+
puts line
|
140
145
|
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
begin
|
192
|
-
dec = OAK.decode(oak,oak_opts)
|
193
|
-
if dec != obj
|
194
|
-
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
195
|
-
unhappiness += 1
|
196
|
-
puts " BAD: #{dec}"
|
197
|
-
end
|
146
|
+
when 'encode-lines'
|
147
|
+
ARGF.each_line.map(&:strip).each do |line|
|
148
|
+
puts OAK.encode(line,oak_opts)
|
149
|
+
end
|
150
|
+
when 'decode-lines'
|
151
|
+
ARGF.each_line.map(&:strip).each do |line|
|
152
|
+
puts OAK.decode(line,oak_opts)
|
153
|
+
end
|
154
|
+
when 'encode-file'
|
155
|
+
puts OAK.encode(STDIN.read,oak_opts)
|
156
|
+
when 'decode-file'
|
157
|
+
STDOUT.write OAK.decode(STDIN.read.strip,oak_opts)
|
158
|
+
when 'recode-file'
|
159
|
+
puts OAK.encode(OAK.decode(STDIN.read,oak_opts),oak_opts)
|
160
|
+
when 'crazy'
|
161
|
+
#
|
162
|
+
# --mode crazy prints out a sample of OAK strings for various
|
163
|
+
# challenging cases.
|
164
|
+
#
|
165
|
+
cycle_a = ['cycle_a','TBD']
|
166
|
+
cycle_b = ['cycle_b',cycle_a]
|
167
|
+
cycle_a[1] = cycle_b
|
168
|
+
dag_c = ['dag_c']
|
169
|
+
dag_b = ['dag_b',dag_c]
|
170
|
+
dag_a = ['dag_a',dag_b,dag_c]
|
171
|
+
[
|
172
|
+
'hello',
|
173
|
+
['hello'] + ['hello',:hello] * 2,
|
174
|
+
{1=>'a','b'=>2,[]=>3,''=>4,{}=>5,nil=>6},
|
175
|
+
['x','x','x','x','x','x','x','x','x','x','x','x','x'],
|
176
|
+
['x'] * 13,
|
177
|
+
cycle_a,
|
178
|
+
dag_a,
|
179
|
+
[1,-123,0.12,-0.123,Float::NAN,-Float::INFINITY,3.14159265358979],
|
180
|
+
].each do |obj|
|
181
|
+
oak = OAK.encode(
|
182
|
+
obj,
|
183
|
+
redundancy: :crc32,
|
184
|
+
format: :none,
|
185
|
+
compression: :none,
|
186
|
+
)
|
187
|
+
puts ""
|
188
|
+
puts "obj: #{obj}"
|
189
|
+
puts " oak: #{oak}"
|
190
|
+
begin
|
191
|
+
dec = OAK.decode(oak,oak_opts)
|
192
|
+
if dec != obj
|
193
|
+
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
194
|
+
unhappiness += 1
|
195
|
+
puts " BAD: #{dec}"
|
198
196
|
end
|
199
|
-
rescue OAK::CantTouchThisStringError => ex
|
200
|
-
puts " BAD: #{ex.message}: #{ex.backtrace_locations[0]}"
|
201
|
-
unhappiness += 1
|
202
197
|
end
|
198
|
+
rescue OAK::CantTouchThisStringError => ex
|
199
|
+
puts " BAD: #{ex.message}: #{ex.backtrace_locations[0]}"
|
200
|
+
unhappiness += 1
|
203
201
|
end
|
204
|
-
|
202
|
+
end
|
203
|
+
when 'tests'
|
204
|
+
[
|
205
|
+
[1,2,3],
|
206
|
+
{:foo=>'foo','foo'=>['x']*10},
|
207
|
+
-1,
|
208
|
+
Float::NAN,
|
209
|
+
nil,
|
210
|
+
].each do |obj|
|
211
|
+
puts " #{obj} => ["
|
212
|
+
key_chain = OAK::KeyChain.new(
|
213
|
+
{ 'l0ng3r' => OAK::Key.new('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') }
|
214
|
+
)
|
205
215
|
[
|
206
|
-
|
207
|
-
{:
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
key_chain
|
214
|
-
|
215
|
-
)
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
{redundancy: :sha1, format: :base64,compression: :lzma, force: true},
|
222
|
-
{key_chain: key_chain,force_oak_4: true,format: :none, },
|
223
|
-
{key_chain: key_chain,force_oak_4: true, },
|
224
|
-
{key_chain: key_chain,key: 'l0ng3r', },
|
225
|
-
].each do |opts|
|
226
|
-
oak = OAK.encode(obj,opts)
|
227
|
-
puts " '#{oak}',"
|
228
|
-
dec = OAK.decode(oak,opts)
|
229
|
-
if dec != obj
|
230
|
-
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
231
|
-
unhappiness += 1
|
232
|
-
end
|
216
|
+
{redundancy: :none, format: :none, compression: :none },
|
217
|
+
{redundancy: :none, format: :base64,compression: :lz4, force: true},
|
218
|
+
{redundancy: :crc32,format: :base64,compression: :zlib, force: true},
|
219
|
+
{redundancy: :crc32,format: :base64,compression: :bzip2,force: true},
|
220
|
+
{redundancy: :sha1, format: :base64,compression: :lzma, force: true},
|
221
|
+
{key_chain: key_chain,force_oak_4: true,format: :none, },
|
222
|
+
{key_chain: key_chain,force_oak_4: true, },
|
223
|
+
{key_chain: key_chain,key: 'l0ng3r', },
|
224
|
+
].each do |opts|
|
225
|
+
oak = OAK.encode(obj,opts)
|
226
|
+
puts " '#{oak}',"
|
227
|
+
dec = OAK.decode(oak,opts)
|
228
|
+
if dec != obj
|
229
|
+
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
230
|
+
unhappiness += 1
|
233
231
|
end
|
234
232
|
end
|
235
|
-
puts " ],"
|
236
233
|
end
|
237
|
-
|
238
|
-
Optimist::die :mode, "bogus mode #{OPTS[:mode]}"
|
234
|
+
puts " ],"
|
239
235
|
end
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
236
|
+
else
|
237
|
+
Optimist::die :mode, "bogus mode #{OPTS[:mode]}"
|
238
|
+
end
|
239
|
+
if unhappiness > 0
|
240
|
+
puts "unhappiness: #{unhappiness}"
|
244
241
|
end
|
242
|
+
exit unhappiness
|
245
243
|
end
|
data/lib/oak.rb
CHANGED
@@ -960,6 +960,19 @@ module OAK
|
|
960
960
|
cipher.auth_tag = auth_tag
|
961
961
|
cipher.auth_data = auth_data
|
962
962
|
cipher.update(ciphertext) + cipher.final
|
963
|
+
rescue ArgumentError => ex
|
964
|
+
#
|
965
|
+
# Some of our tests of corrupting OAK strings lead to incorrect
|
966
|
+
# parses which cause the data passed to this method to be
|
967
|
+
# shorter than ENCRYPTION_ALGO_IV_BYTES.
|
968
|
+
#
|
969
|
+
# In ruby <= 2.2.7 (w/ openssl 1.1.0), these truncated IVs
|
970
|
+
# result in OpenSSL::Cipher::CipherError from cipher.update().
|
971
|
+
#
|
972
|
+
# In ruby >= 2.4.3 (w/ openssl 2.0.5), truncated IVs result in
|
973
|
+
# ArgumentError in cipher.iv=().
|
974
|
+
#
|
975
|
+
raise CantTouchThisStringError, "#{ex.class}: #{ex.message}"
|
963
976
|
rescue OpenSSL::Cipher::CipherError => ex
|
964
977
|
raise CantTouchThisStringError, "#{ex.class}: #{ex.message}"
|
965
978
|
end
|
data/lib/oak/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jhwillett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bzip2-ffi
|
@@ -150,6 +150,8 @@ files:
|
|
150
150
|
- ".travis.yml"
|
151
151
|
- CHANGELOG.md
|
152
152
|
- DESIDERATA.md
|
153
|
+
- DESIGN.md
|
154
|
+
- ENCRYPTION.md
|
153
155
|
- Gemfile
|
154
156
|
- LICENSE
|
155
157
|
- Makefile
|
@@ -179,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
181
|
version: '0'
|
180
182
|
requirements: []
|
181
183
|
rubyforge_project:
|
182
|
-
rubygems_version: 2.
|
184
|
+
rubygems_version: 2.6.14
|
183
185
|
signing_key:
|
184
186
|
specification_version: 4
|
185
187
|
summary: Envelope format offering perf and encryption tradeoffs.
|
data/bin/oak
DELETED
@@ -1,245 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# oak.rb: cli driver for encoding strings in the OAK format.
|
4
|
-
#
|
5
|
-
# author: jhw@prosperworks.com
|
6
|
-
# incept: 2016-03-05
|
7
|
-
#
|
8
|
-
|
9
|
-
require_relative '../lib/oak.rb'
|
10
|
-
require 'optimist'
|
11
|
-
|
12
|
-
OLD_ARGV = ARGV.dup # ARGV is consumed by Optimist but we use later.
|
13
|
-
OPTS = Optimist.options do
|
14
|
-
banner "#{$0} cli driver for OAK"
|
15
|
-
banner <<-OPTIMIST_EXAMPLES
|
16
|
-
Examples:
|
17
|
-
$ echo hello | bin/oak.rb
|
18
|
-
oak_3CNB_1944283675_15_RjFTVTVfaGVsbG8_ok
|
19
|
-
$ (echo hello ; echo world) | bin/oak.rb
|
20
|
-
oak_3CNB_1944283675_15_RjFTVTVfaGVsbG8_ok
|
21
|
-
oak_3CNB_2139413982_15_RjFTVTVfd29ybGQ_ok
|
22
|
-
$ (echo hello ; echo world) | bin/oak.rb --compression zlib --force
|
23
|
-
oak_3CZB_1944283675_26_eJxzMwwONY3PSM3JyQcAFF4DyA_ok
|
24
|
-
oak_3CZB_2139413982_26_eJxzMwwONY0vzy_KSQEAFNgD3A_ok
|
25
|
-
$ (echo hello ; echo world) | bin/oak.rb --format none
|
26
|
-
oak_3CNN_1944283675_11_F1SU5_hello_ok
|
27
|
-
oak_3CNN_2139413982_11_F1SU5_world_ok
|
28
|
-
$ (echo hello ; echo world) | bin/oak.rb | bin/oak.rb --mode decode-lines
|
29
|
-
hello
|
30
|
-
world
|
31
|
-
OPTIMIST_EXAMPLES
|
32
|
-
banner "Options:"
|
33
|
-
version "#{$0} #{OAK::VERSION}"
|
34
|
-
opt :redundancy, 'redundancy', :default => 'crc32'
|
35
|
-
opt :format, 'format', :default => 'base64'
|
36
|
-
opt :compression, 'compression', :default => 'none'
|
37
|
-
opt :force, 'compress even if bigger', :default => false
|
38
|
-
opt :mode, 'mode', :default => 'encode-lines'
|
39
|
-
opt :key_chain, 'key chain env name', :type => :string
|
40
|
-
opt :key, 'encrypt key name', :type => :string
|
41
|
-
opt :key_check, 'check available keys', :default => false
|
42
|
-
opt :key_generate, 'generate new key', :default => false
|
43
|
-
opt :force_oak_4, 'force OAK_4 even unencrypted', :default => false
|
44
|
-
opt :eigen, 'calc eigenratio', :type => :int
|
45
|
-
opt :self_test, 'self-test only', :default => false
|
46
|
-
opt :help, 'show this help'
|
47
|
-
end
|
48
|
-
Optimist::die :eigen, "must be non-negative" if OPTS[:eigen] && OPTS[:eigen] < 0
|
49
|
-
|
50
|
-
oak_opts = {}
|
51
|
-
oak_opts[:redundancy] = OPTS[:redundancy]
|
52
|
-
oak_opts[:compression] = OPTS[:compression]
|
53
|
-
oak_opts[:force] = OPTS[:force]
|
54
|
-
oak_opts[:format] = OPTS[:format]
|
55
|
-
oak_opts[:key_chain] = OAK.parse_env_chain(ENV,OPTS[:key_chain])
|
56
|
-
oak_opts[:key] = OPTS[:key]
|
57
|
-
oak_opts[:force_oak_4] = OPTS[:force_oak_4]
|
58
|
-
|
59
|
-
if !OAK::REDUNDANCY_2_CODE.keys.include?(oak_opts[:redundancy])
|
60
|
-
Optimist::die :redundancy, "bogus #{OPTS[:redundancy]}"
|
61
|
-
end
|
62
|
-
if !OAK::COMPRESSION_2_CODE.keys.include?(oak_opts[:compression])
|
63
|
-
Optimist::die :compression, "bogus #{OPTS[:compression]}"
|
64
|
-
end
|
65
|
-
cool_formats = OAK::FORMAT_2_CODE.keys
|
66
|
-
if !cool_formats.include?(oak_opts[:format])
|
67
|
-
Optimist::die :format, "bogus #{OPTS[:format]} not in #{cool_formats}"
|
68
|
-
end
|
69
|
-
|
70
|
-
=begin
|
71
|
-
|
72
|
-
doctest: simple transcoding
|
73
|
-
>> OAK::decode(OAK::encode([1,"2",3.000001]))
|
74
|
-
=> [1,"2",3.000001]
|
75
|
-
>> OAK::decode(OAK::encode({foo: "bar"}))
|
76
|
-
=> {foo: "bar"}
|
77
|
-
>> OAK::decode(OAK::encode({foo: :bar}))
|
78
|
-
=> {foo: :bar}
|
79
|
-
>> OAK::decode(OAK::encode("Hello, World!"))
|
80
|
-
=> "Hello, World!"
|
81
|
-
>> OAK::decode(OAK::encode("Hello, World!", format: :none, redundancy: :none))
|
82
|
-
=> "Hello, World!"
|
83
|
-
|
84
|
-
doctest: stability of encoding
|
85
|
-
>> OAK::decode("oak_3NNB_0_30_RjNIMV8xXzJZQTNfZm9vU1UzX2Jhcg_ok")
|
86
|
-
=> {:foo=>"bar"}
|
87
|
-
>> OAK::encode(1, format: :base64, redundancy: :none)
|
88
|
-
=> "oak_3NNB_0_6_RjFJMQ_ok"
|
89
|
-
>> OAK::encode(1, format: :base64, redundancy: :crc32)
|
90
|
-
=> "oak_3CNB_3405226796_6_RjFJMQ_ok"
|
91
|
-
>> OAK::encode(1, format: :none, redundancy: :crc32)
|
92
|
-
=> "oak_3CNN_3405226796_4_F1I1_ok"
|
93
|
-
>> hello_utf8 = "Hello, World!".force_encoding('UTF-8')
|
94
|
-
=> "Hello, World!"
|
95
|
-
>> OAK::encode(hello_utf8, format: :base64, redundancy: :none)
|
96
|
-
=> "oak_3NNB_0_27_RjFTVTEzX0hlbGxvLCBXb3JsZCE_ok"
|
97
|
-
>> OAK::encode(hello_utf8, format: :none, redundancy: :crc32)
|
98
|
-
=> "oak_3CNN_2351984628_20_F1SU13_Hello, World!_ok"
|
99
|
-
|
100
|
-
Note above I used force_encoding('UTF-8') after discovering that with
|
101
|
-
Ruby 2.1.6 on Mac I get Encoding.default_encoding is UTF-8, but with
|
102
|
-
Ruby 2.1.6 on Linux I get Encoding.default_encoding is US-ASCII!
|
103
|
-
|
104
|
-
=end
|
105
|
-
|
106
|
-
if __FILE__ == $0
|
107
|
-
if OPTS[:self_test]
|
108
|
-
require 'rubydoctest'
|
109
|
-
exit RubyDocTest::Runner.new(File.read(__FILE__), __FILE__).run ? 0 : 1
|
110
|
-
end
|
111
|
-
if OPTS[:key_check]
|
112
|
-
if !OPTS[:key_chain]
|
113
|
-
puts "no --key-chain specified"
|
114
|
-
else
|
115
|
-
keys = oak_opts[:key_chain].keys.keys
|
116
|
-
if 0 == keys.size
|
117
|
-
puts "#{OPTS[:key_chain]}: no keys found"
|
118
|
-
else
|
119
|
-
puts "#{OPTS[:key_chain]}: found keys: #{keys.join(' ')}"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
if OPTS[:key_generate]
|
124
|
-
STDOUT.puts OAK.encode(OAK.random_key)
|
125
|
-
exit 0
|
126
|
-
end
|
127
|
-
if !$stdin.tty?
|
128
|
-
if OPTS[:eigen]
|
129
|
-
prev = STDIN.read
|
130
|
-
puts "input: %d" % prev.size
|
131
|
-
OPTS[:eigen].times do |i|
|
132
|
-
oak = OAK.encode(prev,oak_opts)
|
133
|
-
psize = prev.size
|
134
|
-
wsize = oak.size
|
135
|
-
ratio = 1.0 * wsize / psize
|
136
|
-
puts " iter %3d: %4d => %4d ratio %.2f" % [i,psize,wsize,ratio]
|
137
|
-
prev = oak
|
138
|
-
end
|
139
|
-
exit 0
|
140
|
-
end
|
141
|
-
unhappiness = 0
|
142
|
-
case OPTS[:mode]
|
143
|
-
when 'cat'
|
144
|
-
ARGF.each_line.map(&:strip).each do |line|
|
145
|
-
puts line
|
146
|
-
end
|
147
|
-
when 'encode-lines'
|
148
|
-
ARGF.each_line.map(&:strip).each do |line|
|
149
|
-
puts OAK.encode(line,oak_opts)
|
150
|
-
end
|
151
|
-
when 'decode-lines'
|
152
|
-
ARGF.each_line.map(&:strip).each do |line|
|
153
|
-
puts OAK.decode(line,oak_opts)
|
154
|
-
end
|
155
|
-
when 'encode-file'
|
156
|
-
puts OAK.encode(STDIN.read,oak_opts)
|
157
|
-
when 'decode-file'
|
158
|
-
STDOUT.write OAK.decode(STDIN.read.strip,oak_opts)
|
159
|
-
when 'recode-file'
|
160
|
-
puts OAK.encode(OAK.decode(STDIN.read,oak_opts),oak_opts)
|
161
|
-
when 'crazy'
|
162
|
-
#
|
163
|
-
# --mode crazy prints out a sample of OAK strings for various
|
164
|
-
# challenging cases.
|
165
|
-
#
|
166
|
-
cycle_a = ['cycle_a','TBD']
|
167
|
-
cycle_b = ['cycle_b',cycle_a]
|
168
|
-
cycle_a[1] = cycle_b
|
169
|
-
dag_c = ['dag_c']
|
170
|
-
dag_b = ['dag_b',dag_c]
|
171
|
-
dag_a = ['dag_a',dag_b,dag_c]
|
172
|
-
[
|
173
|
-
'hello',
|
174
|
-
['hello'] + ['hello',:hello] * 2,
|
175
|
-
{1=>'a','b'=>2,[]=>3,''=>4,{}=>5,nil=>6},
|
176
|
-
['x','x','x','x','x','x','x','x','x','x','x','x','x'],
|
177
|
-
['x'] * 13,
|
178
|
-
cycle_a,
|
179
|
-
dag_a,
|
180
|
-
[1,-123,0.12,-0.123,Float::NAN,-Float::INFINITY,3.14159265358979],
|
181
|
-
].each do |obj|
|
182
|
-
oak = OAK.encode(
|
183
|
-
obj,
|
184
|
-
redundancy: :crc32,
|
185
|
-
format: :none,
|
186
|
-
compression: :none,
|
187
|
-
)
|
188
|
-
puts ""
|
189
|
-
puts "obj: #{obj}"
|
190
|
-
puts " oak: #{oak}"
|
191
|
-
begin
|
192
|
-
dec = OAK.decode(oak,oak_opts)
|
193
|
-
if dec != obj
|
194
|
-
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
195
|
-
unhappiness += 1
|
196
|
-
puts " BAD: #{dec}"
|
197
|
-
end
|
198
|
-
end
|
199
|
-
rescue OAK::CantTouchThisStringError => ex
|
200
|
-
puts " BAD: #{ex.message}: #{ex.backtrace_locations[0]}"
|
201
|
-
unhappiness += 1
|
202
|
-
end
|
203
|
-
end
|
204
|
-
when 'tests'
|
205
|
-
[
|
206
|
-
[1,2,3],
|
207
|
-
{:foo=>'foo','foo'=>['x']*10},
|
208
|
-
-1,
|
209
|
-
Float::NAN,
|
210
|
-
nil,
|
211
|
-
].each do |obj|
|
212
|
-
puts " #{obj} => ["
|
213
|
-
key_chain = OAK::KeyChain.new(
|
214
|
-
{ 'l0ng3r' => OAK::Key.new('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') }
|
215
|
-
)
|
216
|
-
[
|
217
|
-
{redundancy: :none, format: :none, compression: :none },
|
218
|
-
{redundancy: :none, format: :base64,compression: :lz4, force: true},
|
219
|
-
{redundancy: :crc32,format: :base64,compression: :zlib, force: true},
|
220
|
-
{redundancy: :crc32,format: :base64,compression: :bzip2,force: true},
|
221
|
-
{redundancy: :sha1, format: :base64,compression: :lzma, force: true},
|
222
|
-
{key_chain: key_chain,force_oak_4: true,format: :none, },
|
223
|
-
{key_chain: key_chain,force_oak_4: true, },
|
224
|
-
{key_chain: key_chain,key: 'l0ng3r', },
|
225
|
-
].each do |opts|
|
226
|
-
oak = OAK.encode(obj,opts)
|
227
|
-
puts " '#{oak}',"
|
228
|
-
dec = OAK.decode(oak,opts)
|
229
|
-
if dec != obj
|
230
|
-
if !dec.is_a?(Float) && !enc.is_a?(Float) && !dec.nan? && !enc.nan?
|
231
|
-
unhappiness += 1
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
235
|
-
puts " ],"
|
236
|
-
end
|
237
|
-
else
|
238
|
-
Optimist::die :mode, "bogus mode #{OPTS[:mode]}"
|
239
|
-
end
|
240
|
-
if unhappiness > 0
|
241
|
-
puts "unhappiness: #{unhappiness}"
|
242
|
-
end
|
243
|
-
exit unhappiness
|
244
|
-
end
|
245
|
-
end
|