pool_of_entropy 0.0.3 → 0.0.5

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.
@@ -1,543 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe PoolOfEntropy::CorePRNG do
4
- describe "class methods" do
5
-
6
- describe "#new" do
7
- it "should instantiate a default object" do
8
- prng = PoolOfEntropy::CorePRNG.new
9
- prng.should be_a PoolOfEntropy::CorePRNG
10
- prng.size.should == 1
11
- end
12
-
13
- it "should allow setting number of blocks in pool" do
14
- prng = PoolOfEntropy::CorePRNG.new( 10 )
15
- prng.should be_a PoolOfEntropy::CorePRNG
16
- prng.size.should == 10
17
- end
18
-
19
- it "should fail with incorrect block number" do
20
- expect { PoolOfEntropy::CorePRNG.new( -43 ) }.to raise_error ArgumentError
21
- expect { PoolOfEntropy::CorePRNG.new( -1 ) }.to raise_error ArgumentError
22
- expect { PoolOfEntropy::CorePRNG.new( 0 ) }.to raise_error ArgumentError
23
- expect { PoolOfEntropy::CorePRNG.new( 257 ) }.to raise_error ArgumentError
24
- expect { PoolOfEntropy::CorePRNG.new( 1000) }.to raise_error ArgumentError
25
- expect { PoolOfEntropy::CorePRNG.new( nil ) }.to raise_error TypeError
26
- expect { PoolOfEntropy::CorePRNG.new( '' ) }.to raise_error ArgumentError
27
- expect { PoolOfEntropy::CorePRNG.new( :foo => 2 ) }.to raise_error TypeError
28
- end
29
-
30
- it "should allow setting internal state" do
31
- prng = PoolOfEntropy::CorePRNG.new( 1, "\x0" * 64 )
32
- prng.should be_a PoolOfEntropy::CorePRNG
33
- prng.size.should == 1
34
- prng.state.should == "\x0" * 64
35
- end
36
-
37
- it "should fail with bad state data" do
38
- expect { PoolOfEntropy::CorePRNG.new( 1, :boo ) }.to raise_error TypeError
39
- expect { PoolOfEntropy::CorePRNG.new( 1, [] ) }.to raise_error TypeError
40
- expect { PoolOfEntropy::CorePRNG.new( 1, '' ) }.to raise_error ArgumentError
41
- expect { PoolOfEntropy::CorePRNG.new( 1, "\x0" * 63 ) }.to raise_error ArgumentError
42
- expect { PoolOfEntropy::CorePRNG.new( 1, "\x0" * 200 ) }.to raise_error ArgumentError
43
- expect { PoolOfEntropy::CorePRNG.new( 2, "\x0" * 64 ) }.to raise_error ArgumentError
44
- end
45
-
46
- it "should allow setting mix_block_id" do
47
- prng = PoolOfEntropy::CorePRNG.new( 3, "\x12" * 192, 1 )
48
- prng.should be_a PoolOfEntropy::CorePRNG
49
- prng.size.should == 3
50
- prng.state.should == "\x12" * 192
51
- prng.mix_block_id.should == 1
52
- end
53
- end
54
- end
55
-
56
- describe "instance methods" do
57
-
58
- describe "#clone" do
59
- it "should copy all attributes" do
60
- prng_orig = PoolOfEntropy::CorePRNG.new
61
- prng_copy = prng_orig.clone
62
-
63
- prng_copy.size.should == prng_orig.size
64
- prng_copy.state.should == prng_orig.state
65
- prng_copy.mix_block_id.should == prng_orig.mix_block_id
66
- end
67
-
68
- it "should deep clone the internal state string" do
69
- prng_orig = PoolOfEntropy::CorePRNG.new
70
- prng_copy = prng_orig.clone
71
- prng_copy.state.should_not be prng_orig.state
72
- end
73
- end
74
-
75
- describe "#update" do
76
- it "should change the internal state" do
77
- prng = PoolOfEntropy::CorePRNG.new
78
- init_state = prng.state.clone
79
- prng.update( 'boo' )
80
- prng.state.should_not == init_state
81
- end
82
-
83
- it "should not change the length of the internal state" do
84
- prng = PoolOfEntropy::CorePRNG.new
85
- prng.update( 'boo' )
86
- prng.state.length.should == 64
87
- prng.update( 'boowgkjwrhqgioueqrhgiue2hguirhqwiughreuioghreuifhqwoifhr3iufghfwrgrwgetdfwd' )
88
- prng.state.length.should == 64
89
-
90
- prng = PoolOfEntropy::CorePRNG.new( 5 )
91
- prng.update( 'boo' )
92
- prng.state.length.should == 5 * 64
93
- prng.update( 'getdfwd' * 1000 )
94
- prng.state.length.should == 5 * 64
95
- prng.update( 'boefewfweo' )
96
- prng.state.length.should == 5 * 64
97
- prng.update( 'geefewftdfwd' * 1000 )
98
- prng.state.length.should == 5 * 64
99
- end
100
-
101
- it "should only change 64 bytes of state at a time" do
102
- prng = PoolOfEntropy::CorePRNG.new( 5 )
103
- init_state = prng.state.clone
104
-
105
- prng.update( 'boo' )
106
- prng.state[64,4*64].should == init_state[64,4*64]
107
- next_state = prng.state.clone
108
-
109
- prng.update( 'getdfwd' * 1000 )
110
- prng.state[128,3*64].should == init_state[128,3*64]
111
- prng.state[0,1*64].should == next_state[0,1*64]
112
- next_state = prng.state.clone
113
-
114
- prng.update( 'boefewfweo' )
115
- prng.state[192,2*64].should == init_state[192,2*64]
116
- prng.state[0,2*64].should == next_state[0,2*64]
117
- next_state = prng.state.clone
118
-
119
- prng.update( 'geefewftdfwd' * 1000 )
120
- prng.state[256,1*64].should == init_state[256,1*64]
121
- prng.state[0,3*64].should == next_state[0,3*64]
122
- end
123
- end
124
-
125
- instance01 = PoolOfEntropy::CorePRNG.new
126
- instance01.update( 'QWertyuiopp' )
127
- instance01.update( 'Asdfghjkjl' )
128
- instance01.update( 'Zxcvbnm' )
129
-
130
- pool_types = [
131
- [
132
- 'default instance',
133
- PoolOfEntropy::CorePRNG.new
134
- ],
135
- [
136
- 'instance with 2KB pool size',
137
- PoolOfEntropy::CorePRNG.new( 32 )
138
- ],
139
- [
140
- 'instance with initial state all 0',
141
- PoolOfEntropy::CorePRNG.new( 1, "\x0" * 64 )
142
- ],
143
- [
144
- 'instance with fixed initial state',
145
- PoolOfEntropy::CorePRNG.new( 5, "fiver" * 64, 3 )
146
- ],
147
- [
148
- 'instance cloned from 2KB instance',
149
- PoolOfEntropy::CorePRNG.new( 32 ).clone
150
- ],
151
- [
152
- 'instance that has been updated with user data',
153
- instance01
154
- ],
155
- ]
156
-
157
- # NB "probability" and "randomness" tests in the following block are very light, just
158
- # intended to capture high-level failures in logic. See DIEHARDER_TEST.md for thorough
159
- # checks on statistical randomness of PoolOfEntropy::CorePRNG
160
- pool_types.each do |prng_name, prng|
161
-
162
- context "using #{prng_name}" do
163
-
164
- describe "#read_bytes" do
165
- it "always returns a 16 byte string" do
166
- 100.times { prng.read_bytes.length.should == 16 }
167
- end
168
-
169
- it "has a high probability of returning a different string each time" do
170
- Set[ *(1..100).map {prng.read_bytes} ].size.should == 100
171
- end
172
-
173
- describe "with adjustments" do
174
- it "always returns a 16 byte string" do
175
- 100.times { prng.read_bytes('654321').length.should == 16 }
176
- end
177
-
178
- it "has a high probability of returning a different string each time" do
179
- Set[ *(1..100).map {prng.read_bytes('654321')} ].size.should == 100
180
- end
181
-
182
- it "changes output, but does not include adjustments in changes to state" do
183
- prng_copy = prng.clone
184
- 10.times do
185
- prng.read_bytes('Hello!').should == prng_copy.read_bytes('Hello!')
186
- prng.state.should == prng_copy.state
187
- prng.read_bytes('Hello!').should_not == prng_copy.read_bytes('Goodbye!')
188
- prng.state.should == prng_copy.state
189
- prng.read_bytes.should_not == prng_copy.read_bytes('Goodbye!')
190
- prng.state.should == prng_copy.state
191
- prng.read_bytes('Hello!').should_not == prng_copy.read_bytes
192
- prng.state.should == prng_copy.state
193
- prng.read_bytes('Hello','Goodbye').should_not == prng_copy.read_bytes
194
- prng.state.should == prng_copy.state
195
- # Verify that output remains same for next rolls
196
- prng.read_bytes('Foobar','Wibble').should == prng_copy.read_bytes('Foobar','Wibble')
197
- prng.state.should == prng_copy.state
198
- prng.read_bytes.should == prng_copy.read_bytes
199
- prng.state.should == prng_copy.state
200
- end
201
- end
202
- end
203
- end
204
-
205
- describe "#read_hex" do
206
- it "always returns a 32 digit hex string" do
207
- 100.times do
208
- hex = prng.read_hex
209
- hex.length.should == 32
210
- hex.should match /\A[0-9a-f]{32}\z/
211
- end
212
- end
213
-
214
- it "has a high probability of returning a different string each time" do
215
- Set[ *(1..100).map {prng.read_hex} ].size.should == 100
216
- end
217
-
218
- describe "with adjustments" do
219
- it "always returns a 32 digit hex string" do
220
- 100.times do
221
- hex = prng.read_hex('QWertyeu')
222
- hex.length.should == 32
223
- hex.should match /\A[0-9a-f]{32}\z/
224
- end
225
- end
226
-
227
- it "has a high probability of returning a different string each time" do
228
- Set[ *(1..100).map {prng.read_hex('654321')} ].size.should == 100
229
- end
230
-
231
- it "changes output, but does not include adjustments in changes to state" do
232
- prng_copy = prng.clone
233
- 10.times do
234
- prng.read_hex('Hello!').should == prng_copy.read_hex('Hello!')
235
- prng.state.should == prng_copy.state
236
- prng.read_hex('Hello!').should_not == prng_copy.read_hex('Goodbye!')
237
- prng.state.should == prng_copy.state
238
- prng.read_hex.should_not == prng_copy.read_hex('Goodbye!')
239
- prng.state.should == prng_copy.state
240
- prng.read_hex('Hello!').should_not == prng_copy.read_hex
241
- prng.state.should == prng_copy.state
242
- prng.read_hex('Hello','Goodbye').should_not == prng_copy.read_hex
243
- prng.state.should == prng_copy.state
244
- # Verify that output remains same for next rolls
245
- prng.read_hex('Foobar','Wibble').should == prng_copy.read_hex('Foobar','Wibble')
246
- prng.state.should == prng_copy.state
247
- prng.read_hex.should == prng_copy.read_hex
248
- prng.state.should == prng_copy.state
249
- end
250
- end
251
- end
252
- end
253
-
254
- describe "#read_bignum" do
255
- it "always returns a 128-bit unsigned integer" do
256
- 100.times do
257
- num = prng.read_bignum
258
- num.should >= 0
259
- num.should < 2**128
260
- end
261
- end
262
-
263
- it "has a high probability of returning a different number each time" do
264
- Set[ *(1..100).map {prng.read_bignum} ].size.should == 100
265
- end
266
-
267
- describe "with adjustments" do
268
- it "always returns a 128-bit unsigned integer" do
269
- 100.times do
270
- num = prng.read_bignum( 'Biggest' )
271
- num.should >= 0
272
- num.should < 2**128
273
- end
274
- end
275
-
276
- it "has a high probability of returning a different number each time" do
277
- Set[ *(1..100).map {prng.read_bignum('654321')} ].size.should == 100
278
- end
279
-
280
- it "changes output, but does not include adjustments in changes to state" do
281
- prng_copy = prng.clone
282
- 10.times do
283
- prng.read_bignum('Hello!').should == prng_copy.read_bignum('Hello!')
284
- prng.state.should == prng_copy.state
285
- prng.read_bignum('Hello!').should_not == prng_copy.read_bignum('Goodbye!')
286
- prng.state.should == prng_copy.state
287
- prng.read_bignum.should_not == prng_copy.read_bignum('Goodbye!')
288
- prng.state.should == prng_copy.state
289
- prng.read_bignum('Hello!').should_not == prng_copy.read_bignum
290
- prng.state.should == prng_copy.state
291
- prng.read_bignum('Hello','Goodbye').should_not == prng_copy.read_bignum
292
- prng.state.should == prng_copy.state
293
- # Verify that output remains same for next rolls
294
- prng.read_bignum('Foobar','Wibble').should == prng_copy.read_bignum('Foobar','Wibble')
295
- prng.state.should == prng_copy.state
296
- prng.read_bignum.should == prng_copy.read_bignum
297
- prng.state.should == prng_copy.state
298
- end
299
- end
300
- end
301
- end
302
-
303
- describe "#read_float" do
304
- it "always returns a Float between 0.0 (inclusive) and 1.0 (exclusive)" do
305
- 100.times do
306
- num = prng.read_float
307
- num.should be_a Float
308
- num.should >= 0.0
309
- num.should < 1.0
310
- end
311
- end
312
-
313
- it "has a high probability of returning a different Float each time" do
314
- Set[ *(1..100).map {prng.read_float} ].size.should == 100
315
- end
316
-
317
- describe "with adjustments" do
318
- it "always returns a Float between 0.0 (inclusive) and 1.0 (exclusive)" do
319
- 100.times do
320
- num = prng.read_float('Boom')
321
- num.should be_a Float
322
- num.should >= 0.0
323
- num.should < 1.0
324
- end
325
- end
326
-
327
- it "has a high probability of returning a different Float each time" do
328
- Set[ *(1..100).map {prng.read_float('654321')} ].size.should == 100
329
- end
330
-
331
- it "changes output, but does not include adjustments in changes to state" do
332
- prng_copy = prng.clone
333
- 10.times do
334
- prng.read_float('Hello!').should == prng_copy.read_float('Hello!')
335
- prng.state.should == prng_copy.state
336
- prng.read_float('Hello!').should_not == prng_copy.read_float('Goodbye!')
337
- prng.state.should == prng_copy.state
338
- prng.read_float.should_not == prng_copy.read_float('Goodbye!')
339
- prng.state.should == prng_copy.state
340
- prng.read_float('Hello!').should_not == prng_copy.read_float
341
- prng.state.should == prng_copy.state
342
- prng.read_float('Hello','Goodbye').should_not == prng_copy.read_float
343
- prng.state.should == prng_copy.state
344
- # Verify that output remains same for next rolls
345
- prng.read_float('Foobar','Wibble').should == prng_copy.read_float('Foobar','Wibble')
346
- prng.state.should == prng_copy.state
347
- prng.read_float.should == prng_copy.read_float
348
- prng.state.should == prng_copy.state
349
- end
350
- end
351
- end
352
- end
353
-
354
- describe "#generate_integer" do
355
- it "always returns an integer between 0 (inclusive) and supplied top (exclusive)" do
356
- 100.times do
357
- num = prng.generate_integer( 10 )
358
- num.should be_a Fixnum
359
- num.should >= 0
360
- num.should < 10
361
- end
362
-
363
- 100.times do
364
- num = prng.generate_integer( 100 )
365
- num.should be_a Fixnum
366
- num.should >= 0
367
- num.should < 100
368
- end
369
-
370
- 100.times do
371
- num = prng.generate_integer( 1000 )
372
- num.should be_a Fixnum
373
- num.should >= 0
374
- num.should < 1000
375
- end
376
-
377
- 100.times do
378
- num = prng.generate_integer( 647218456 )
379
- num.should be_a Fixnum
380
- num.should >= 0
381
- num.should < 647218456
382
- end
383
- end
384
-
385
- it "can generate integers larger than 2**128" do
386
- results = (0..100).map do
387
- num = prng.generate_integer( 2 ** 1024 )
388
- num.should >= 0
389
- num.should < 2 ** 1024
390
- num
391
- end
392
- results.select { |n| n > 2 ** 1020 }.count.should > 50
393
- end
394
-
395
- it "with a large enough value for top, has a high probability of returning a different integer each time" do
396
- Set[ *(1..100).map {prng.generate_integer( 2**75 - 7 )} ].size.should == 100
397
- end
398
-
399
- it "covers a distribution 0...top" do
400
- Set[ *(1..100).map {prng.generate_integer(10)} ].size.should == 10
401
- end
402
-
403
- describe "with adjustments" do
404
- it "always returns an integer between 0 (inclusive) and supplied top (exclusive)" do
405
- 100.times do
406
- num = prng.generate_integer( 10, 'jkffwe' )
407
- num.should be_a Fixnum
408
- num.should >= 0
409
- num.should < 10
410
- end
411
-
412
- 100.times do
413
- num = prng.generate_integer( 100, 'jkffweefewg' )
414
- num.should be_a Fixnum
415
- num.should >= 0
416
- num.should < 100
417
- end
418
-
419
- 100.times do
420
- num = prng.generate_integer( 1000, 'jkffweefewg', 'efhwjkfgw' )
421
- num.should be_a Fixnum
422
- num.should >= 0
423
- num.should < 1000
424
- end
425
-
426
- 100.times do
427
- num = prng.generate_integer( 647218456, 'j*****g', 'efhwjkfgw' )
428
- num.should be_a Fixnum
429
- num.should >= 0
430
- num.should < 647218456
431
- end
432
- end
433
-
434
- it "with a large enough value for top, has a high probability of returning a different integer each time" do
435
- Set[ *(1..100).map {prng.generate_integer( 2**80 - 5, '654321')} ].size.should == 100
436
- end
437
-
438
- it "changes output, but does not include adjustments in changes to state" do
439
- prng_copy = prng.clone
440
- big = 2 ** 64 - 3
441
- small = 20
442
- 10.times do
443
- prng.generate_integer( small, 'Hello!').should == prng_copy.generate_integer( small, 'Hello!')
444
- prng.state.should == prng_copy.state
445
- prng.generate_integer( big, 'Hello!').should_not == prng_copy.generate_integer( big, 'Goodbye!')
446
- prng.state.should == prng_copy.state
447
- prng.generate_integer( big ).should_not == prng_copy.generate_integer( big, 'Goodbye!')
448
- prng.state.should == prng_copy.state
449
- prng.generate_integer( big, 'Hello!').should_not == prng_copy.generate_integer( big )
450
- prng.state.should == prng_copy.state
451
- prng.generate_integer( big, 'Hello','Goodbye').should_not == prng_copy.generate_integer( big )
452
- prng.state.should == prng_copy.state
453
- # Verify that output remains same for next rolls
454
- prng.generate_integer( small, 'Foobar','Wibble').should == prng_copy.generate_integer( small, 'Foobar','Wibble')
455
- prng.state.should == prng_copy.state
456
- prng.generate_integer( big ).should == prng_copy.generate_integer( big )
457
- prng.state.should == prng_copy.state
458
- end
459
- end
460
- end
461
- end
462
-
463
-
464
- describe "all read methods" do
465
-
466
- it "generate higher and lower values in sync" do
467
- prngs = (0..4).map { prng.clone }
468
- results = (1..20).map do
469
- Hash[
470
- :bytes => prngs[0].read_bytes,
471
- :hex => prngs[1].read_hex,
472
- :float => prngs[2].read_float,
473
- :num => prngs[3].read_bignum,
474
- :int => prngs[4].generate_integer( 1_000_000_000 ),
475
- ]
476
- end
477
- results.sort_by { |h| h[:int] }.should == results.sort_by { |h| h[:hex] }
478
- results.sort_by { |h| h[:float] }.should == results.sort_by { |h| h[:hex] }
479
- results.sort_by { |h| h[:num] }.should == results.sort_by { |h| h[:bytes] }
480
- results.sort_by { |h| h[:float] }.should == results.sort_by { |h| h[:int] }
481
- end
482
- end
483
-
484
- end
485
- end
486
-
487
- describe "using predictable sequences" do
488
- it "generates expected hex strings from simple zeroed pool" do
489
- prng = PoolOfEntropy::CorePRNG.new( 1, "\x0" * 64 )
490
- (0..24).map { prng.read_hex }.should == [ "da0cd77eb1c84458ddcc91e36b9dcb35",
491
- "498ec24d1126440047eed396d836b5e1", "0b90df55c5e7c1513b072367eae4a4ce",
492
- "f12b5b54b5594e785bbb9a4ac50ccec8", "d506bd4e201a00dc30499bd8e59a30d8",
493
- "2557893cf995fe43bd00721fce6ab16a", "41ee50244cdd02334bafc3e9d8f564d9",
494
- "8156c7c7bcfd856cb9d1012243cfc662", "1116f840e2aee924bd2c7d722c602635",
495
- "96cf31967465b83f5ef3476c60afe20a", "f041f6df72aa2eab7394f08e83d52a0c",
496
- "5ccbb30077f2433bd765ddc86840a880", "6a4339fd5d445024048ea8f91a3e02fd",
497
- "707e9499b9f0e9e906a0c0ddd0530803", "553704d95703284df323f0aa4244cf81",
498
- "cb1522ce0bdf2504fdd62df7416be73e", "05c4932cb9d3a7c0675b0228826e661a",
499
- "59606f23e34e726a7912dacfde533d97", "188cf17dde6947264ce05f8274874ffa",
500
- "24c184b56453891657953f557635b742", "a5f969e50228b2ee0f38cc37c5033541",
501
- "f1de0e5d149cc5a7f0e38c0ee501d7bc", "5ca3a6beb0b810568be83ab2179eb550",
502
- "756fb9c58277eb8c6092142224caecf4", "0ed9505eadb3def60ec42051f0bf15ef" ]
503
- end
504
-
505
- it "generates expected hex strings from simple zeroed pool and an adjustment" do
506
- prng = PoolOfEntropy::CorePRNG.new( 1, "\x0" * 64 )
507
- (0..24).map { prng.read_hex( 'bananas' ) }.should == [
508
- "fed9de9a612f4157ebb49582ca557a50", "a7adc2374a4df2ed67846ac09a3b6645",
509
- "cbdf8bbbe6145751fe14004719915160", "8cd84be95376f72918c305bdea43e36d",
510
- "9e08e80ff40c942f0cf4d479b5378fa0", "54d80c5330873f9733a0adef0197220f",
511
- "2abe07bd85d2066a624dd3630e59730a", "88b6a697fe74aeb8ec83845e103b7b63",
512
- "9c6c9d613855f6535adb419cc564fd10", "23f9b778b254035a0e4219423a52da77",
513
- "4cd50c14ee17fa29c8b1f209432a36b3", "2b5646b164d863de716f67adef653859",
514
- "fd81d0bbbd2828ecdfcba0b486ef786c", "08e6594fc277ff7fafbf37475ecadbf6",
515
- "5e2333ecc800eb9a06e347924ed42e94", "8a14e48013028b2c9f174a07ddd5ef49",
516
- "e9a5c331f54b155f570c2cf2bcd37209", "1ce84279195a5b23ffeb3063edbfab21",
517
- "7422e19e58f2fcf20805f601266bf676", "8df0226465b74d830360ea8609d181bf",
518
- "3e5d5e8cf8ad032fb4005826bdf7bb94", "65e3f9ab28c26bead6647c21bcc6245e",
519
- "8ed5d8892d464ebeaa8dcbcef0968936", "2f000bc1ab14d914196cc1d5055db189",
520
- "8e9c4b8152f14e47ac31f25a80765ebf" ]
521
- end
522
-
523
- it "generates expected hex strings from simple zeroed pool and alternating adjustments" do
524
- prng = PoolOfEntropy::CorePRNG.new( 1, "\x0" * 64 )
525
- (0..24).map { |x| x.odd? ? prng.read_hex( 'bananas', x.to_s ) : prng.read_hex }.should == [
526
- "da0cd77eb1c84458ddcc91e36b9dcb35", "de4b20a0560263090c6fe11ebba6256e",
527
- "0b90df55c5e7c1513b072367eae4a4ce", "0c92d534160cb268cb3282a9dd3f1efe",
528
- "d506bd4e201a00dc30499bd8e59a30d8", "089f799236a9cf64f22f1deafbe28214",
529
- "41ee50244cdd02334bafc3e9d8f564d9", "84477b9a3d51bb72868ccb85bea71cad",
530
- "1116f840e2aee924bd2c7d722c602635", "469e4bb2f38719c7f85d79c8900a8fa8",
531
- "f041f6df72aa2eab7394f08e83d52a0c", "e21bf2508b8e1755ae70c74c0d36ec2e",
532
- "6a4339fd5d445024048ea8f91a3e02fd", "a94a80c80c9edd95808a67775c2b42d4",
533
- "553704d95703284df323f0aa4244cf81", "edd6aea5bda7b2d9c494067c5cdbe410",
534
- "05c4932cb9d3a7c0675b0228826e661a", "cf81635ca2fa910fd11cf45508dc658b",
535
- "188cf17dde6947264ce05f8274874ffa", "bb4aaeb98e13400c1216c674a872ba93",
536
- "a5f969e50228b2ee0f38cc37c5033541", "1a795355f979575247b3fa9c92d97917",
537
- "5ca3a6beb0b810568be83ab2179eb550", "1a98419cca1dd1b370ce8a4a2ab721b7",
538
- "0ed9505eadb3def60ec42051f0bf15ef" ]
539
- end
540
- end
541
- end
542
-
543
- end