From nobody at rubyforge.org Tue Jan 9 06:53:31 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Tue, 9 Jan 2007 06:53:31 -0500 (EST) Subject: [Archipelago-submits] [164] trunk/archipelago/lib/archipelago/disco.rb: improved the efficiency and elegance of disco.rb greatly by realizing that ServiceDescription has to be seen as its content by hashes Message-ID: <20070109115331.226435240BBF@rubyforge.org> Revision: 164 Author: zond Date: 2007-01-09 06:53:30 -0500 (Tue, 09 Jan 2007) Log Message: ----------- improved the efficiency and elegance of disco.rb greatly by realizing that ServiceDescription has to be seen as its content by hashes Modified Paths: -------------- trunk/archipelago/lib/archipelago/disco.rb Modified: trunk/archipelago/lib/archipelago/disco.rb =================================================================== --- trunk/archipelago/lib/archipelago/disco.rb 2006-12-28 15:38:55 UTC (rev 163) +++ trunk/archipelago/lib/archipelago/disco.rb 2007-01-09 11:53:30 UTC (rev 164) @@ -216,6 +216,18 @@ end end # + # Returns the hash of our @attributes. + # + def hash + @attributes.hash + end + # + # Returns whether our @attributes are equal to that of +o+. + # + def eql?(o) + ServiceDescription === o && @attributes == o.attributes + end + # # Returns whether this ServiceDescription matches the given +match+. # def matches?(match) From nobody at rubyforge.org Fri Jan 12 05:54:36 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 12 Jan 2007 05:54:36 -0500 (EST) Subject: [Archipelago-submits] [165] trunk/archipelago/lib/archipelago/treasure.rb: added better return values in treasure Message-ID: <20070112105436.73E0B5240A61@rubyforge.org> Revision: 165 Author: zond Date: 2007-01-12 05:54:36 -0500 (Fri, 12 Jan 2007) Log Message: ----------- added better return values in treasure Modified Paths: -------------- trunk/archipelago/lib/archipelago/treasure.rb Modified: trunk/archipelago/lib/archipelago/treasure.rb =================================================================== --- trunk/archipelago/lib/archipelago/treasure.rb 2007-01-09 11:53:30 UTC (rev 164) +++ trunk/archipelago/lib/archipelago/treasure.rb 2007-01-12 10:54:36 UTC (rev 165) @@ -656,6 +656,7 @@ instance.with_transaction(transaction) do return_value = instance.send(method, *arguments, &block) end + return_value = Dubloon.new(key, self, transaction, service_id) if return_value == instance return return_value else return instance.send(method, *arguments, &block) @@ -681,7 +682,9 @@ raise UnknownObjectException(self, key) unless instance begin - return instance.send(method, *arguments, &block) + return_value = instance.send(method, *arguments, &block) + return_value = Dubloon.new(key, self, nil, service_id) if return_value == instance + return return_value ensure @db.store_if_changed(key) end From nobody at rubyforge.org Mon Jan 15 08:57:35 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Mon, 15 Jan 2007 08:57:35 -0500 (EST) Subject: [Archipelago-submits] [166] trunk/archipelago/lib/archipelago/treasure.rb: fixed a bug when raising exceptions in treasure. Message-ID: <20070115135735.A67D75241306@rubyforge.org> Revision: 166 Author: zond Date: 2007-01-15 08:57:35 -0500 (Mon, 15 Jan 2007) Log Message: ----------- fixed a bug when raising exceptions in treasure. made treasure more idiot-friendly :) Modified Paths: -------------- trunk/archipelago/lib/archipelago/treasure.rb Modified: trunk/archipelago/lib/archipelago/treasure.rb =================================================================== --- trunk/archipelago/lib/archipelago/treasure.rb 2007-01-12 10:54:36 UTC (rev 165) +++ trunk/archipelago/lib/archipelago/treasure.rb 2007-01-15 13:57:35 UTC (rev 166) @@ -679,7 +679,7 @@ def call_without_transaction(key, method, *arguments, &block) instance = @db[key] - raise UnknownObjectException(self, key) unless instance + raise UnknownObjectException.new(self, key) unless instance begin return_value = instance.send(method, *arguments, &block) @@ -753,7 +753,13 @@ # def set(key, value, transaction) join!(transaction) - value.assert_transaction(transaction) if Dubloon === value + if Dubloon === value + value.assert_transaction(transaction) + # + # Return the value if the value is in fact a proxy to what we are trying overwrite. + # + return value if value.object_id == Dubloon.new(key, self, transaction, self.service_id).object_id + end if transaction snapshot = @snapshot_by_transaction[transaction] From nobody at rubyforge.org Wed Jan 17 11:46:36 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Wed, 17 Jan 2007 11:46:36 -0500 (EST) Subject: [Archipelago-submits] [167] trunk/oneliner: new start with 1 bit block size Message-ID: <20070117164636.DF1815241286@rubyforge.org> Revision: 167 Author: zond Date: 2007-01-17 11:46:36 -0500 (Wed, 17 Jan 2007) Log Message: ----------- new start with 1 bit block size Modified Paths: -------------- trunk/oneliner/ext/superstring_ext.c trunk/oneliner/lib/oneliner/superstring.rb trunk/oneliner/tests/superstring_benchmark.rb Modified: trunk/oneliner/ext/superstring_ext.c =================================================================== --- trunk/oneliner/ext/superstring_ext.c 2007-01-15 13:57:35 UTC (rev 166) +++ trunk/oneliner/ext/superstring_ext.c 2007-01-17 16:46:36 UTC (rev 167) @@ -27,55 +27,51 @@ double P[] = {0.0,0.00943264209782069,0.49551807459988,0.165172691533293,0.0825863457666466,0.049551807459988,0.0330345383066586,0.0235960987904705,0.0176970740928528,0.0137643909611078,0.0110115127688862,0.00900941953817963,0.00750784961514969,0.00635279582820358,0.00544525356703164,0.00471921975809409,0.00412931728833233,0.00364351525441088,0.003238680226143,0.00289776651812795,0.00260798986631516,0.00235960987904705,0.00214509989004277,0.00195856946482166,0.00179535534275319,0.00165172691533293,0.00152467099876886,0.00141173240626746,0.00131089437724836,0.00122048786847261,0.00113912201057444,0.00106563026795673,0.000999028376209435,0.000938481201893711,0.000883276425311728,0.000832803486722487,0.000786536626349015,0.000744021133032852,0.000704862126031123,0.000668715350337219,0.000635279582820358,0.000604290334877902,0.000575514604645621,0.000548746483499313,0.000523803461522071,0.000500523307676646,0.000478761424734183,0.00045838859814975,0.000439289073226844,0.000421358906972687,0.000404504550693779,0.00038864162713716,0.00037369387224727,0.000359592216690769,0.000346273986442963,0.000333682205117764,0.000321764983506415,0.000310474984085138,0.000299768950151167,0.000289607290824009,0.000279953714463209,0.00027077490415294,0.000262040229825425,0.00025372149237065,0.000245792695734067,0.000238229843557634,0.000231010757389221,0.000224114913885065,0.000217523298770799,0.000211218275618022,0.000205183467743221,0.000199403651750455,0.000193864661424053,0.000188553300837093,0.000183457265679333,0.000178565071927885,0.000173865991087677,0.000169349991319166,0.000165007683849444,0.000160830274131736,0.000156809517278443,0.000152937677345642,0.000149207490093309,0.000145612128886241,0.000142145173436569,0.000138800581120414,0.000135572660629242,0.000132456047741213,0.000129445683019822,0.000126536791266568,0.000123724862571755,0.000121005634822925,0.000118375077544166,0.000115829376951819,0.000113364922123056,0.000110978292183624,0.000108666244429798,0.000106425703307534,0.000104253750178809,0.00010214761381156,0.000100104661535329,9.81223910098771e-05,9.61984225587031e-05,9.43304920235826e-05,9.25164441000522e-05,9.07542261171941e-05,8.90418822281904e-05,8.73775479809345e-05,8.57594452405468e-05,8.4185877437968e-05,8.2655225120914e-05,8.11659417854021e-05,7.97165499678056e-05,7.83056375789949e-05,7.69318544635739e-05,7.55939091685552e-05,7.42905659070284e-05,7.30206417034895e-05,7.17830037085151e-05,7.05765666713972e-05,6.94002905602072e-05,6.82531783195426e-05,6.71342737569272e-05,6.60426595494975e-05,6.49774553632153e-05,6.39378160774038e-05,6.29229301079212e-05,6.19320178227571e-05,6.09643300442765e-05,6.00191466327373e-05,5.90957751460799e-05,5.81935495713305e-05,5.73118291232801e-05,5.64499971063886e-05,5.5607459836144e-05,5.47836456163493e-05,5.39780037690501e-05,5.31900037140274e-05,5.24191340949836e-05,5.1664901949732e-05,5.09268319218787e-05,5.02044655116393e-05,4.9497360363588e-05,4.88050895892721e-05,4.81272411227544e-05,4.74634171072682e-05,4.68132333112782e-05,4.61763185723492e-05,4.55523142673175e-05,4.49408738073535e-05,4.43416621565888e-05,4.37543553730578e-05,4.31786401707807e-05,4.26142135018816e-05,4.20607821577013e-05,4.15180623879246e-05,4.09857795367973e-05,4.04636676955642e-05,3.99514693703039e-05,3.94489351643882e-05,3.89558234748333e-05,3.8471900201854e-05,3.79969384709669e-05,3.75307183670287e-05,3.70730266796259e-05,3.66236566592668e-05,3.61824077838539e-05,3.57490855349455e-05,3.5323501183339e-05,3.49054715835362e-05,3.4494818976671e-05,3.40913708015053e-05,3.36949595131157e-05,3.33054224089178e-05,3.29226014616889e-05,3.25463431592696e-05,3.21764983506415e-05,3.18129220980919e-05,3.1455473535192e-05,3.11040157303295e-05,3.07584155555481e-05,3.04185435604592e-05,3.00842738510036e-05,2.97554839728505e-05,2.94320547992326e-05,2.91138704230246e-05,2.88008180528846e-05,2.84927879132816e-05,2.81896731482467e-05,2.78913697286885e-05,2.75977763631233e-05,2.7308794411677e-05,2.70243278032221e-05,2.67442829555203e-05,2.64685686982469e-05,2.61970961987777e-05,2.59297788906269e-05,2.56665324044276e-05,2.54072745013526e-05,2.51519250088767e-05,2.49004057587879e-05,2.46526405273572e-05,2.44085549775814e-05,2.4168076603418e-05,2.39311346759335e-05,2.36976601912903e-05,2.3467585820501e-05,2.32408458608827e-05,2.30173761891434e-05,2.27971142160416e-05,2.25799988425555e-05,2.23659704175075e-05,2.21549706965877e-05,2.1946942802723e-05,2.17418311877443e-05,2.15395815953001e-05,2.13401410249733e-05,2.11434576975542e-05,2.09494810214298e-05,2.07581615600469e-05,2.05694510004101e-05,2.03833021225783e-05,2.01996687701227e-05,2.00185058215117e-05,1.98397691623911e-05,1.96634156587254e-05,1.94894031307721e-05,1.93176903278578e-05,1.91482369039292e-05,1.89810033938512e-05,1.88159511904264e-05,1.8653042522111e-05,1.84922404314032e-05,1.83335087538804e-05,1.81768120978643e-05,1.8022115824691e-05,1.78693860295665e-05,1.77185895229879e-05,1.75696938127107e-05,1.74226670862445e-05,1.72774781938591e-05,1.71340966320844e-05,1.6992492527687e-05,1.68526366221093e-05,1.67145002563543e-05,1.65780553563024e-05,1.64432744184463e-05,1.63101304960297e-05,1.61785971855779e-05,1.60486486138062e-05,1.59202594248957e-05,1.57934047681237e-05,1.5668060285837e-05,1.55442021017592e-05,1.54218068096194e-05,1.53008514620929e-05,1.51813135600453e-05,1.50631710420683e-05,1.49464022743003e-05,1.4830986040522e-05,1.4716901532518e-05,1.46041283406979e-05,1.44926464449674e-05,1.43824362058421e-05,1.42734783557979e-05,1.41657539908485e-05,1.40592445623459e-05,1.39539318689949e-05,1.38497980490771e-05,1.37468255728758e-05,1.36449972352989e-05,1.35442961486915e-05,1.34447057358335e-05,1.33462097231168e-05,1.32487921338969e-05,1.31524372820141e-05,1.30571297654777e-05,1.29628544603118e-05,1.28695965145542e-05,1.27773413424068e-05,1.26860746185325e-05,1.25957822724931e-05,1.25064504833265e-05,1.24180656742571e-05,1.23306145075369e-05,1.22440838794139e-05,1.21584609152222e-05,1.20737329645934e-05,1.19898875967838e-05,1.1906912596114e-05,1.18247959575201e-05,1.17435258822107e-05,1.16630907734284e-05,1.15834792323129e-05,1.15046800538618e-05,1.14266822229881e-05,1.13494749106706e-05,1.12730474701947e-05,1.1197389433482e-05,1.11224905075055e-05,1.10483405707888e-05,1.09749296699863e-05,1.09022480165426e-05,1.08302859834301e-05,1.07590341019602e-05,1.06884830586687e-05,1.06186236922721e-05,1.05494469906938e-05,1.04809440881568e-05,1.04131062623435e-05,1.03459249316187e-05,1.02793916523157e-05,1.02134981160829e-05,1.01482361472901e-05,1.0083597700492e-05,1.00195748579492e-05,9.95615982720272e-06,9.89334493870302e-06,9.83112264349106e-06,9.76948551092998e-06,9.70842622648667e-06,9.64793758956152e-06,9.58801251136548e-06,9.5286440128431e-06,9.46982522264036e-06,9.41154937511642e-06,9.35380980839792e-06,9.29659996247499e-06,9.23991337733795e-06,9.18374369115352e-06,9.12808463847987e-06,9.07293004851926e-06,9.0182738434077e-06,8.96411003654039e-06,8.91043273093236e-06,8.85723611761336e-06,8.80451447405614e-06,8.75226216263741e-06,8.70047362913068e-06,8.6491434012302e-06,8.59826608710532e-06,8.54783637398447e-06,8.49784902676818e-06,8.44829888667041e-06,8.39918086988744e-06,8.35048996629389e-06,8.30222123816503e-06,8.25436981892488e-06,8.20693091191957e-06,8.15989978921516e-06,8.11327179041964e-06,8.06704232152836e-06,8.02120685379241e-06,7.97576092260944e-06,7.93070012643651e-06,7.88602012572419e-06,7.84171664187181e-06,7.79778545620306e-06,7.7542224089617e-06,7.71102339832682e-06,7.66818437944722e-06,7.62570136349461e-06,7.58357041673497e-06,7.54178765961797e-06,7.50034926588381e-06,7.45925146168718e-06,7.41849052473807e-06,7.37806278345885e-06,7.33796461615744e-06,7.29819245021621e-06,7.25874276129612e-06,7.21961207255598e-06,7.18079695388632e-06,7.14229402115771e-06,7.10409993548307e-06,7.06621140249383e-06,7.0286251716295e-06,6.99133803544048e-06,6.95434682890376e-06,6.91764842875123e-06,6.88123975281044e-06,6.84511775935736e-06,6.80927944648115e-06,6.77372185146036e-06,6.73844205015067e-06,6.70343715638365e-06,6.66870432137648e-06,6.63424073315232e-06,6.60004361597112e-06,6.56611022977075e-06,6.53243786961808e-06,6.49902386516991e-06,6.46586558014353e-06,6.43296041179674e-06,6.40030579041707e-06,6.36789917882002e-06,6.33573807185628e-06,6.30381999592753e-06,6.27214250851081e-06,6.24070319769121e-06,6.20949968170275e-06,6.1785296084773e-06,6.1477906552013e-06,6.1172805278802e-06,6.08699696091049e-06,6.05693771665908e-06,6.02710058504993e-06,5.99748338315779e-06,5.96808395480898e-06,5.93890017018888e-06,5.90992992545625e-06,5.88117114236401e-06,5.85262176788651e-06,5.82427977385317e-06,5.79614315658817e-06,5.76820993655642e-06,5.74047815801529e-06,5.71294588867229e-06,5.6856112193485e-06,5.65847226364755e-06,5.63152715763018e-06,5.60477405949417e-06,5.5782111492596e-06,5.55183662845932e-06,5.52564871983451e-06,5.49964566703529e-06,5.4738257343262e-06,5.44818720629657e-06,5.42272838757556e-06,5.3974476025519e-06,5.37234319509817e-06,5.34741352829957e-06,5.32265698418707e-06,5.29807196347489e-06,5.2736568853022e-06,5.24941018697897e-06,5.22533032373594e-06,5.20141576847857e-06,5.17766501154488e-06,5.15407656046723e-06,5.13064893973783e-06,5.10738069057802e-06,5.08427037071115e-06,5.06131655413909e-06,5.03851783092225e-06,5.01587280696305e-06,4.99338010379281e-06,4.97103835836197e-06,4.94884622283357e-06,4.92680236437997e-06,4.90490546498272e-06,4.88315422123557e-06,4.86154734415046e-06,4.84008355896657e-06,4.81876160496231e-06,4.79758023527017e-06,4.77653821669442e-06,4.75563432953165e-06,4.73486736739396e-06,4.71423613703494e-06,4.69373945817827e-06,4.67337616334886e-06,4.65314509770666e-06,4.63304511888287e-06,4.61307509681872e-06,4.5932339136066e-06,4.57352046333361e-06,4.55393365192747e-06,4.5344723970047e-06,4.5151356277211e-06,4.49592228462441e-06,4.47683131950923e-06,4.45786169527403e-06,4.43901238578027e-06,4.42028237571368e-06,4.40167066044752e-06,4.38317624590782e-06,4.36479814844071e-06,4.34653539468154e-06,4.32838702142608e-06,4.31035207550348e-06,4.29242961365107e-06,4.27461870239111e-06,4.25691841790916e-06,4.23932784593433e-06,4.22184608162119e-06,4.20447222943345e-06,4.18720540302921e-06,4.17004472514794e-06,4.15298932749907e-06,4.13603835065214e-06,4.11919094392851e-06,4.10244626529465e-06,4.08580348125694e-06,4.06926176675793e-06,4.05282030507406e-06,4.03647828771489e-06,4.02023491432368e-06,4.00408939257941e-06,3.98804093810013e-06,3.97208877434773e-06,3.95623213253397e-06,3.94047025152786e-06,3.92480237776433e-06,3.90922776515415e-06,3.89374567499512e-06,3.87835537588447e-06,3.86305614363246e-06,3.84784726117722e-06,3.83272801850069e-06,3.81769771254578e-06,3.80275564713464e-06,3.78790113288802e-06,3.77313348714577e-06,3.75845203388839e-06,3.7438561036597e-06,3.72934503349048e-06,3.7149181668232e-06,3.70057485343778e-06,3.68631444937829e-06,3.67213631688068e-06,3.65803982430149e-06,3.64402434604746e-06,3.63008926250617e-06,3.61623395997752e-06,3.60245783060618e-06,3.5887602723149e-06,3.57514068873875e-06,3.56159848916019e-06,3.54813308844503e-06,3.5347439069792e-06,3.5214303706064e-06,3.50819191056653e-06,3.49502796343494e-06,3.48193797106253e-06,3.4689213805165e-06,3.45597764402204e-06,3.44310621890464e-06,3.43030656753324e-06,3.4175781572641e-06,3.40492046038535e-06,3.3923329540623e-06,3.37981512028347e-06,3.36736644580729e-06,3.35498642210947e-06,3.34267454533108e-06,3.33043031622731e-06,3.31825324011678e-06,3.30614282683169e-06,3.29409859066837e-06,3.28212005033866e-06,3.27020672892183e-06,3.25835815381704e-06,3.24657385669654e-06,3.23485337345937e-06,3.22319624418564e-06,3.21160201309145e-06,3.2000702284843e-06,3.18860044271912e-06,3.17719221215483e-06,3.16584509711142e-06,3.1545586618276e-06,3.14333247441896e-06,3.13216610683666e-06,3.1210591348266e-06,3.11001113788916e-06,3.09902169923937e-06,3.08809040576763e-06,3.07721684800084e-06,3.06640062006411e-06,3.05564131964283e-06,3.04493854794531e-06,3.03429190966578e-06,3.02370101294792e-06,3.0131654693488e-06,3.00268489380324e-06,2.99225890458865e-06,2.98188712329024e-06,2.97156917476675e-06,2.96130468711643e-06,2.95109329164362e-06,2.94093462282557e-06,2.93082831827977e-06,2.92077401873164e-06,2.91077136798256e-06,2.90082001287835e-06,2.89091960327808e-06,2.8810697920233e-06,2.87127023490758e-06,2.86152059064643e-06,2.85182052084763e-06,2.84216968998182e-06,2.8325677653535e-06,2.82301441707237e-06,2.81350931802499e-06,2.80405214384676e-06,2.79464257289425e-06,2.78528028621789e-06,2.77596496753489e-06,2.76669630320255e-06,2.75747398219187e-06,2.74829769606145e-06,2.73916713893168e-06,2.73008200745927e-06,2.72104200081205e-06,2.71204682064408e-06,2.703096171071e-06,2.69418975864572e-06,2.68532729233439e-06,2.67650848349257e-06,2.66773304584177e-06,2.65900069544622e-06,2.65031115068986e-06,2.64166413225367e-06,2.63305936309324e-06,2.62449656841651e-06,2.61597547566191e-06,2.60749581447662e-06,2.59905731669515e-06,2.5906597163181e-06,2.58230274949127e-06,2.57398615448486e-06,2.56570967167301e-06,2.55747304351354e-06,2.54927601452792e-06,2.54111833128143e-06,2.5329997423636e-06,2.52491999836882e-06,2.5168788518772e-06,2.50887605743562e-06,2.500911371539e-06,2.49298455261178e-06,2.48509536098959e-06,2.47724355890115e-06,2.46942891045036e-06,2.46165118159855e-06,2.45391014014698e-06,2.44620555571952e-06,2.43853719974547e-06,2.43090484544267e-06,2.42330826780066e-06,2.41574724356416e-06,2.4082215512166e-06,2.40073097096399e-06,2.39327528471876e-06,2.38585427608397e-06,2.37846773033758e-06,2.37111543441691e-06,2.36379717690327e-06,2.35651274800681e-06,2.3492619395514e-06,2.34204454495985e-06,2.33486035923911e-06,2.32770917896579e-06,2.32059080227171e-06,2.31350502882965e-06,2.30645165983932e-06,2.29943049801333e-06,2.29244134756344e-06,2.28548401418692e-06,2.27855830505302e-06,2.27166402878962e-06,2.26480099547001e-06,2.25796901659982e-06,2.25116790510403e-06,2.24439747531425e-06,2.23765754295595e-06,2.23094792513599e-06,2.22426844033019e-06,2.21761890837106e-06,2.21099915043562e-06,2.20440898903343e-06,2.19784824799464e-06,2.19131675245825e-06,2.18481432886045e-06,2.17834080492309e-06,2.17189600964225e-06,2.16547977327699e-06,2.15909192733812e-06,2.15273230457718e-06,2.14640073897548e-06,2.14009706573326e-06,2.13382112125897e-06,2.12757274315865e-06,2.12135177022544e-06,2.11515804242916e-06,2.10899140090604e-06,2.10285168794853e-06,2.09673874699519e-06,2.09065242262075e-06,2.0845925605262e-06,2.07855900752902e-06,2.0725516115535e-06,2.06657022162116e-06,2.06061468784128e-06,2.05468486140145e-06,2.04878059455834e-06,2.04290174062847e-06,2.03704815397911e-06,2.03121969001922e-06,2.0254162051906e-06,2.01963755695895e-06,2.01388360380523e-06,2.00815420521688e-06,2.00244922167933e-06,1.99676851466747e-06,1.99111194663725e-06,1.98547938101734e-06,1.97987068220091e-06,1.97428571553744e-06,1.96872434732466e-06,1.96318644480054e-06,1.95767187613537e-06,1.95218051042391e-06,1.94671221767762e-06,1.94126686881699e-06,1.93584433566387e-06,1.93044449093398e-06,1.92506720822943e-06,1.91971236203129e-06,1.91437982769232e-06,1.90906948142965e-06,1.90378120031766e-06,1.89851486228082e-06,1.89327034608667e-06,1.88804753133884e-06,1.88284629847014e-06,1.8776665287357e-06,1.8725081042062e-06,1.86737090776119e-06,1.8622548230824e-06,1.85715973464715e-06,1.85208552772189e-06,1.84703208835566e-06,1.84199930337376e-06,1.83698706037139e-06,1.83199524770733e-06,1.82702375449782e-06,1.82207247061029e-06,1.81714128665735e-06,1.81223009399071e-06,1.80733878469519e-06,1.8024672515828e-06,1.79761538818689e-06,1.79278308875628e-06,1.78797024824955e-06,1.78317676232931e-06,1.77840252735654e-06,1.773647440385e-06,1.76891139915566e-06,1.76419430209125e-06,1.75949604829074e-06,1.75481653752401e-06,1.75015567022647e-06,1.74551334749377e-06,1.74088947107657e-06,1.73628394337531e-06,1.73169666743508e-06,1.72712754694053e-06,1.72257648621078e-06,1.71804339019444e-06,1.71352816446462e-06,1.70903071521406e-06,1.7045509492502e-06,1.70008877399038e-06,1.69564409745707e-06,1.69121682827311e-06,1.68680687565701e-06,1.68241414941832e-06,1.67803855995299e-06,1.67368001823883e-06,1.66933843583095e-06,1.66501372485729e-06,1.6607057980142e-06,1.65641456856196e-06,1.65213995032051e-06,1.64788185766505e-06,1.64364020552176e-06,1.63941490936361e-06,1.63520588520607e-06,1.63101304960297e-06,1.6268363196424e-06,1.62267561294255e-06,1.61853084764768e-06,1.61440194242409e-06,1.61028881645613e-06,1.60619138944224e-06,1.60210958159106e-06,1.59804331361748e-06,1.59399250673885e-06,1.58995708267116e-06,1.58593696362521e-06,1.58193207230293e-06,1.57794233189359e-06,1.57396766607018e-06,1.57000799898572e-06,1.56606325526968e-06,1.56213336002434e-06,1.55821823882127e-06,1.55431781769781e-06,1.55043202315357e-06,1.54656078214694e-06,1.54270402209171e-06,1.53886167085362e-06,1.53503365674702e-06,1.5312199085315e-06,1.5274203554086e-06,1.52363492701849e-06,1.51986355343676e-06,1.51610616517115e-06,1.51236269315839e-06,1.50863306876096e-06,1.50491722376401e-06,1.50121509037221e-06,1.49752660120668e-06,1.49385168930188e-06,1.49019028810261e-06,1.48654233146099e-06,1.48290775363345e-06,1.47928648927782e-06,1.47567847345031e-06,1.47208364160268e-06,1.46850192957932e-06,1.46493327361436e-06,1.46137761032889e-06,1.4578348767281e-06,1.45430501019849e-06,1.45078794850514e-06,1.44728362978895e-06,1.44379199256388e-06,1.44031297571433e-06,1.43684651849239e-06,1.43339256051525e-06,1.42995104176251e-06,1.42652190257363e-06,1.42310508364531e-06,1.41970052602894e-06,1.41630817112803e-06,1.41292796069574e-06,1.40955983683235e-06,1.40620374198274e-06,1.40285961893403e-06,1.39952741081305e-06,1.39620706108396e-06,1.39289851354584e-06,1.38960171233035e-06,1.38631660189931e-06,1.3830431270424e-06,1.37978123287485e-06,1.3765308648351e-06,1.37329196868255e-06,1.37006449049528e-06,1.36684837666782e-06,1.36364357390893e-06,1.36045002923936e-06,1.35726768998967e-06,1.35409650379811e-06,1.35093641860838e-06,1.34778738266757e-06,1.34464934452399e-06,1.3415222530251e-06,1.3384060573154e-06,1.33530070683439e-06,1.33220615131449e-06,1.32912234077904e-06,1.32604922554025e-06,1.3229867561972e-06,1.31993488363388e-06,1.31689355901721e-06,1.31386273379508e-06,1.3108423596944e-06,1.30783238871921e-06,1.30483277314876e-06,1.30184346553559e-06,1.2988644187037e-06,1.29589558574666e-06,1.29293692002578e-06,1.28998837516825e-06,1.28704990506536e-06,1.28412146387067e-06,1.28120300599824e-06,1.27829448612083e-06,1.27539585916818e-06,1.27250708032521e-06,1.26962810503036e-06,1.2667588889738e-06,1.26389938809575e-06,1.26104955858482e-06,1.2582093568763e-06,1.25537873965048e-06,1.25255766383104e-06,1.24974608658339e-06,1.24694396531302e-06,1.24415125766394e-06,1.24136792151704e-06,1.23859391498851e-06,1.23582919642827e-06,1.2330737244184e-06,1.23032745777159e-06,1.2275903555296e-06,1.22486237696176e-06,1.2221434815634e-06,1.21943362905439e-06,1.21673277937763e-06,1.21404089269759e-06,1.21135792939882e-06,1.20868385008447e-06,1.20601861557491e-06,1.20336218690624e-06,1.20071452532889e-06,1.19807559230619e-06,1.19544534951298e-06,1.19282375883423e-06,1.19021078236362e-06,1.18760638240221e-06,1.18501052145707e-06,1.18242316223991e-06,1.17984426766578e-06,1.17727380085169e-06,1.17471172511534e-06,1.17215800397379e-06,1.16961260114214e-06,1.16707548053229e-06,1.16454660625161e-06,1.16202594260172e-06,1.15951345407717e-06,1.15700910536426e-06,1.15451286133974e-06,1.15202468706962e-06,1.14954454780789e-06,1.1470724089954e-06,1.14460823625857e-06,1.14215199540823e-06,1.13970365243844e-06,1.13726317352529e-06,1.13483052502578e-06,1.13240567347657e-06,1.12998858559295e-06,1.1275792282676e-06,1.12517756856947e-06,1.12278357374273e-06,1.12039721120555e-06,1.11801844854906e-06,1.11564725353624e-06,1.11328359410078e-06,1.11092743834607e-06,1.10857875454407e-06,1.10623751113426e-06,1.10390367672258e-06,1.10157722008039e-06,1.09925811014337e-06,1.09694631601058e-06,1.09464180694333e-06,1.09234455236423e-06,1.09005452185613e-06,1.08777168516114e-06,1.08549601217963e-06,1.08322747296922e-06,1.08096603774382e-06,1.07871167687261e-06,1.07646436087913e-06,1.07422406044025e-06,1.07199074638528e-06,1.06976438969497e-06,1.06754496150058e-06,1.06533243308297e-06,1.06312677587161e-06,1.06092796144375e-06,1.05873596152341e-06,1.05655074798054e-06,1.05437229283006e-06,1.05220056823103e-06,1.0500355464857e-06,1.04787720003866e-06,1.04572550147595e-06,1.0435804235242e-06,1.04144193904977e-06,1.03931002105785e-06,1.03718464269168e-06,1.03506577723164e-06,1.03295339809443e-06,1.03084747883226e-06,1.02874799313199e-06,1.02665491481433e-06,1.024568217833e-06,1.02248787627395e-06,1.02041386435453e-06,1.0183461564227e-06,1.01628472695626e-06,1.01422955056201e-06,1.01218060197502e-06,1.01013785605781e-06,1.00810128779963e-06,1.00607087231564e-06,1.0040465848462e-06,1.00202840075605e-06,1.00001629553365e-06,9.98010244790354e-07,9.96010224259712e-07,9.9401620979673e-07,9.92028177377136e-07,9.90046103096662e-07,9.88069963170322e-07,9.86099733931697e-07,9.84135391832232e-07,9.82176913440526e-07,9.80224275441638e-07,9.78277454636391e-07,9.76336427940684e-07,9.74401172384806e-07,9.72471665112757e-07,9.70547883381574e-07,9.68629804560662e-07,9.66717406131125e-07,9.64810665685107e-07,9.62909560925136e-07,9.61014069663472e-07,9.5912416982146e-07,9.57239839428883e-07,9.55361056623331e-07,9.5348779964956e-07,9.51620046858865e-07,9.49757776708456e-07,9.47900967760835e-07,9.46049598683177e-07,9.44203648246722e-07,9.42363095326163e-07,9.40527918899043e-07,9.38698098045154e-07,9.36873611945941e-07,9.35054439883909e-07,9.3324056124204e-07,9.31431955503199e-07,9.29628602249562e-07,9.27830481162039e-07,9.26037572019697e-07,9.24249854699195e-07,9.22467309174221e-07,9.20689915514926e-07,9.18917653887371e-07,9.17150504552972e-07,9.15388447867951e-07,9.13631464282792e-07,9.11879534341694e-07,9.10132638682036e-07,9.0839075803384e-07,9.06653873219244e-07,9.04921965151968e-07,9.03195014836792e-07,9.01473003369039e-07,8.9975591193405e-07,8.98043721806678e-07,8.96336414350771e-07,8.94633971018671e-07,8.92936373350704e-07,8.91243602974684e-07,8.89555641605414e-07,8.87872471044192e-07,8.86194073178324e-07,8.84520429980632e-07,8.8285152350897e-07,8.81187335905748e-07,8.79527849397451e-07,8.77873046294164e-07,8.76222908989099e-07,8.74577419958134e-07,8.72936561759338e-07,8.71300317032517e-07,8.69668668498748e-07,8.68041598959929e-07,8.66419091298322e-07,8.64801128476103e-07,8.63187693534916e-07,8.61578769595428e-07,8.59974339856889e-07,8.58374387596691e-07,8.56778896169931e-07,8.55187849008984e-07,8.53601229623068e-07,8.52019021597816e-07,8.50441208594857e-07,8.48867774351389e-07,8.4729870267976e-07,8.45733977467054e-07,8.4417358267468e-07,8.42617502337952e-07,8.41065720565691e-07,8.39518221539811e-07,8.37974989514922e-07,8.36436008817925e-07,8.34901263847616e-07,8.33370739074294e-07,8.31844419039359e-07,8.30322288354932e-07,8.2880433170346e-07,8.27290533837335e-07,8.25780879578508e-07,8.2427535381811e-07,8.22773941516073e-07,8.21276627700757e-07,8.19783397468574e-07,8.18294235983618e-07,8.16809128477295e-07,8.15328060247962e-07,8.13851016660556e-07,8.12377983146238e-07,8.10908945202032e-07,8.09443888390465e-07,8.07982798339219e-07,8.06525660740771e-07,8.05072461352049e-07,8.0362318599408e-07,8.02177820551645e-07,8.00736350972935e-07,7.99298763269214e-07,7.97865043514471e-07,7.9643517784509e-07,7.95009152459512e-07,7.93586953617903e-07,7.92168567641821e-07,7.90753980913889e-07,7.89343179877468e-07,7.87936151036332e-07,7.86532880954344e-07,7.85133356255137e-07,7.83737563621794e-07,7.82345489796534e-07,7.80957121580391e-07,7.79572445832908e-07,7.78191449471822e-07,7.76814119472757e-07,7.75440442868915e-07,7.74070406750772e-07,7.72703998265775e-07,7.7134120461804e-07,7.69982013068052e-07,7.68626410932369e-07,7.67274385583323e-07,7.6592592444873e-07,7.64581015011595e-07,7.6323964480982e-07,7.6190180143592e-07,7.60567472536733e-07,7.59236645813134e-07,7.57909309019755e-07,7.56585449964698e-07,7.55265056509263e-07,7.5394811656766e-07,7.5263461810674e-07,7.51324549145719e-07,7.500178977559e-07,7.48714652060408e-07,7.47414800233914e-07,7.46118330502372e-07,7.4482523114275e-07,7.43535490482762e-07,7.42249096900612e-07,7.40966038824725e-07,7.39686304733491e-07,7.38409883155003e-07,7.37136762666805e-07,7.3586693189563e-07,7.34600379517153e-07,7.3333709425573e-07,7.32077064884157e-07,7.30820280223411e-07,7.29566729142411e-07,7.28316400557762e-07,7.27069283433519e-07,7.25825366780938e-07,7.24584639658236e-07,7.23347091170348e-07,7.22112710468693e-07,7.20881486750928e-07,7.19653409260722e-07,7.18428467287513e-07,7.17206650166275e-07,7.15987947277293e-07,7.14772348045922e-07,7.13559841942367e-07,7.12350418481447e-07,7.11144067222376e-07,7.09940777768531e-07,7.08740539767232e-07,7.07543342909517e-07,7.06349176929923e-07,7.05158031606264e-07,7.03969896759412e-07,7.02784762253083e-07,7.01602617993616e-07,7.00423453929762e-07,6.99247260052466e-07,6.98074026394659e-07,6.96903743031047e-07,6.95736400077897e-07,6.94571987692829e-07,6.93410496074614e-07,6.9225191546296e-07,6.91096236138314e-07,6.89943448421653e-07,6.88793542674283e-07,6.8764650929764e-07,6.86502338733085e-07,6.85361021461708e-07,6.84222548004131e-07,6.83086908920307e-07,6.81954094809328e-07,6.80824096309229e-07,6.79696904096797e-07,6.78572508887373e-07,6.77450901434666e-07,6.76332072530563e-07,6.75216013004935e-07,6.74102713725454e-07,6.72992165597406e-07,6.71884359563501e-07,6.70779286603692e-07,6.69676937734993e-07,6.6857730401129e-07,6.67480376523166e-07,6.66386146397719e-07,6.65294604798377e-07,6.6420574292473e-07,6.63119552012343e-07,6.62036023332585e-07,6.6095514819245e-07,6.59876917934387e-07,6.58801323936124e-07,6.57728357610495e-07,6.56658010405271e-07,6.55590273802985e-07,6.54525139320771e-07,6.53462598510185e-07,6.52402642957046e-07,6.51345264281265e-07,6.5029045413668e-07,6.49238204210893e-07,6.48188506225103e-07,6.47141351933948e-07,6.46096733125338e-07,6.45054641620297e-07,6.44015069272802e-07,6.42978007969625e-07,6.41943449630173e-07,6.4091138620633e-07,6.39881809682304e-07,6.38854712074468e-07,6.37830085431205e-07,6.36807921832757e-07,6.35788213391071e-07,6.34770952249646e-07,6.33756130583379e-07,6.32743740598422e-07,6.31733774532024e-07,6.30726224652387e-07,6.29721083258519e-07,6.28718342680082e-07,6.27717995277249e-07,6.26720033440561e-07,6.25724449590774e-07,6.24731236178725e-07,6.23740385685183e-07,6.22751890620705e-07,6.21765743525502e-07,6.20781936969291e-07,6.19800463551158e-07,6.18821315899418e-07,6.17844486671479e-07,6.16869968553701e-07,6.1589775426126e-07,6.14927836538014e-07,6.13960208156365e-07,6.12994861917125e-07,6.12031790649384e-07,6.11070987210374e-07,6.10112444485338e-07,6.09156155387399e-07,6.08202112857426e-07,6.07250309863909e-07,6.06300739402824e-07,6.05353394497507e-07,6.04408268198526e-07,6.03465353583552e-07,6.02524643757233e-07,6.01586131851069e-07,6.00649811023285e-07,5.99715674458708e-07,5.9878371536864e-07,5.97853926990738e-07,5.96926302588891e-07,5.96000835453094e-07,5.95077518899332e-07,5.94156346269457e-07,5.93237310931067e-07,5.92320406277387e-07,5.91405625727151e-07,5.90492962724486e-07,5.89582410738789e-07,5.88673963264615e-07,5.8776761382156e-07,5.86863355954142e-07,5.85961183231691e-07,5.85061089248232e-07,5.84163067622372e-07,5.83267111997184e-07,5.823732160401e-07,5.81481373442795e-07,5.80591577921077e-07,5.79703823214776e-07,5.78818103087633e-07,5.77934411327194e-07,5.77052741744696e-07,5.76173088174964e-07,5.75295444476297e-07,5.74419804530366e-07,5.73546162242107e-07,5.72674511539611e-07,5.71804846374023e-07,5.70937160719435e-07,5.70071448572779e-07,5.69207703953729e-07,5.68345920904594e-07,5.67486093490215e-07,5.66628215797864e-07,5.65772281937142e-07,5.64918286039879e-07,5.6406622226003e-07,5.63216084773579e-07,5.62367867778438e-07,5.61521565494347e-07,5.60677172162777e-07,5.5983468204683e-07,5.58994089431144e-07,5.58155388621795e-07,5.573185739462e-07,5.56483639753022e-07,5.55650580412074e-07,5.54819390314225e-07,5.53990063871304e-07,5.53162595516007e-07,5.52336979701804e-07,5.51513210902845e-07,5.5069128361387e-07,5.49871192350111e-07,5.49052931647209e-07,5.48236496061117e-07,5.47421880168009e-07,5.46609078564196e-07,5.4579808586603e-07,5.44988896709816e-07,5.44181505751728e-07,5.43375907667713e-07,5.42572097153412e-07,5.41770068924065e-07,5.40969817714428e-07,5.40171338278687e-07,5.39374625390371e-07,5.38579673842264e-07,5.37786478446325e-07,5.36995034033601e-07,5.3620533545414e-07,5.35417377576911e-07,5.3463115528972e-07,5.33846663499126e-07,5.33063897130359e-07,5.32282851127238e-07,5.31503520452088e-07,5.30725900085662e-07,5.29949985027058e-07,5.29175770293636e-07,5.28403250920945e-07,5.27632421962635e-07,5.26863278490387e-07,5.26095815593824e-07,5.25330028380441e-07,5.24565911975524e-07,5.23803461522071e-07,5.23042672180718e-07,5.22283539129657e-07,5.21526057564567e-07,5.20770222698531e-07,5.20016029761966e-07,5.19263474002542e-07,5.18512550685112e-07,5.17763255091637e-07,5.17015582521107e-07,5.16269528289475e-07,5.15525087729577e-07,5.14782256191062e-07,5.14041029040318e-07,5.13301401660404e-07,5.12563369450972e-07,5.11826927828197e-07,5.11092072224711e-07,5.10358798089525e-07,5.09627100887963e-07,5.0889697610159e-07,5.08168419228145e-07,5.07441425781467e-07,5.06715991291429e-07,5.0599211130387e-07,5.05269781380524e-07,5.04548997098954e-07,5.03829754052483e-07,5.03112047850129e-07,5.02395874116535e-07,5.01681228491903e-07,5.00968106631928e-07,5.00256504207735e-07,4.99546416905808e-07,4.98837840427927e-07,4.98130770491105e-07,4.9742520282752e-07,4.96721133184452e-07,4.9601855732422e-07,4.95317471024115e-07,4.94617870076341e-07,4.93919750287948e-07,4.93223107480772e-07,4.92527937491369e-07,4.91834236170959e-07,4.91141999385356e-07,4.90451223014913e-07,4.89761902954456e-07,4.89074035113228e-07,4.88387615414823e-07,4.87702639797131e-07,4.87019104212271e-07,4.8633700462654e-07,4.85656337020345e-07,4.84977097388148e-07,4.84299281738409e-07,4.83622886093523e-07,4.82947906489764e-07,4.82274338977226e-07,4.81602179619766e-07,4.80931424494948e-07,4.80262069693981e-07,4.79594111321666e-07,4.78927545496341e-07,4.78262368349818e-07,4.77598576027334e-07,4.7693616468749e-07,4.76275130502199e-07,4.75615469656628e-07,4.74957178349145e-07,4.74300252791263e-07,4.73644689207584e-07,4.72990483835751e-07,4.72337632926384e-07,4.71686132743038e-07,4.71035979562137e-07,4.70387169672933e-07,4.69739699377444e-07,4.69093564990405e-07,4.68448762839215e-07,4.67805289263887e-07,4.67163140616991e-07,4.66522313263607e-07,4.65882803581271e-07,4.65244607959927e-07,4.64607722801871e-07,4.63972144521704e-07,4.63337869546282e-07,4.62704894314661e-07,4.62073215278054e-07,4.61442828899776e-07,4.60813731655195e-07,4.60185920031687e-07,4.5955939052858e-07,4.58934139657113e-07,4.5831016394038e-07,4.57687459913287e-07,4.57066024122502e-07,4.56445853126406e-07,4.55826943495048e-07,4.55209291810096e-07,4.54592894664787e-07,4.53977748663888e-07,4.53363850423639e-07,4.52751196571715e-07,4.52139783747176e-07,4.51529608600418e-07,4.50920667793135e-07,4.50312957998266e-07,4.49706475899951e-07,4.49101218193491e-07,4.48497181585296e-07,4.47894362792842e-07,4.47292758544632e-07,4.46692365580142e-07,4.46093180649786e-07,4.45495200514867e-07,4.44898421947533e-07,4.44302841730736e-07,4.43708456658186e-07,4.43115263534312e-07,4.42523259174213e-07,4.41932440403619e-07,4.41342804058852e-07,4.40754346986773e-07,4.40167066044752e-07,4.39580958100618e-07,4.3899602003262e-07,4.38412248729385e-07,4.37829641089877e-07,4.37248194023357e-07,4.36667904449338e-07,4.36088769297548e-07,4.35510785507889e-07,4.34933950030396e-07,4.34358259825193e-07,4.33783711862462e-07,4.33210303122392e-07,4.3263803059515e-07,4.32066891280833e-07,4.31496882189433e-07,4.30928000340799e-07,4.30360242764592e-07,4.29793606500254e-07,4.29228088596964e-07,4.28663686113602e-07,4.28100396118709e-07,4.27538215690451e-07,4.26977141916579e-07,4.26417171894393e-07,4.25858302730705e-07,4.25300531541797e-07,4.24743855453392e-07,4.24188271600608e-07,4.23633777127927e-07,4.23080369189158e-07,4.22528044947397e-07,4.21976801574993e-07,4.21426636253513e-07,4.20877546173704e-07,4.20329528535457e-07,4.19782580547773e-07,4.19236699428725e-07,4.18691882405426e-07,4.1814812671399e-07,4.17605429599501e-07,4.17063788315973e-07,4.16523200126322e-07,4.15983662302324e-07,4.15445172124587e-07,4.14907726882511e-07,4.1437132387426e-07,4.13835960406722e-07,4.1330163379548e-07,4.12768341364776e-07,4.12236080447478e-07,4.11704848385046e-07,4.11174642527499e-07,4.10645460233384e-07,4.10117298869739e-07,4.09590155812066e-07,4.09064028444292e-07,4.08538914158741e-07,4.080148103561e-07,4.07491714445387e-07,4.0696962384392e-07,4.06448535977282e-07,4.05928448279294e-07,4.05409358191981e-07,4.04891263165537e-07,4.04374160658302e-07,4.03858048136721e-07,4.03342923075322e-07,4.02828782956679e-07,4.02315625271384e-07,4.01803447518015e-07,4.01292247203107e-07,4.00782021841119e-07,4.00272768954409e-07,3.99764486073197e-07,3.99257170735541e-07,3.98750820487303e-07,3.98245432882123e-07,3.97741005481385e-07,3.97237535854194e-07,3.96735021577338e-07,3.96233460235268e-07,3.95732849420063e-07,3.95233186731401e-07,3.94734469776535e-07,3.94236696170259e-07,3.93739863534884e-07,3.93243969500205e-07,3.92749011703477e-07,3.92254987789385e-07,3.91761895410014e-07,3.91269732224826e-07,3.90778495900626e-07,3.90288184111542e-07,3.89798794538988e-07,3.89310324871646e-07,3.88822772805432e-07,3.88336136043473e-07,3.87850412296076e-07,3.87365599280706e-07,3.86881694721955e-07,3.86398696351515e-07,3.85916601908157e-07,3.85435409137698e-07,3.84955115792978e-07,3.84475719633834e-07,3.83997218427071e-07,3.8351960994644e-07,3.8304289197261e-07,3.82567062293141e-07,3.82092118702461e-07,3.81618059001837e-07,3.81144880999355e-07,3.80672582509889e-07,3.80201161355078e-07,3.79730615363302e-07,3.79260942369655e-07,3.78792140215922e-07,3.78324206750554e-07,3.7785713982864e-07,3.77390937311886e-07,3.76925597068592e-07,3.76461116973621e-07,3.75997494908383e-07,3.75534728760803e-07,3.75072816425304e-07,3.74611755802777e-07,3.74151544800563e-07,3.73692181332422e-07,3.73233663318517e-07,3.72775988685386e-07,3.72319155365919e-07,3.71863161299334e-07,3.71408004431159e-07,3.709536827132e-07,3.70500194103527e-07,3.70047536566442e-07,3.69595708072466e-07,3.69144706598308e-07,3.68694530126847e-07,3.68245176647107e-07,3.67796644154236e-07,3.67348930649483e-07,3.66902034140177e-07,3.66455952639703e-07,3.66010684167479e-07,3.6556622674894e-07,3.65122578415507e-07,3.64679737204572e-07,3.64237701159476e-07,3.63796468329482e-07,3.63356036769761e-07,3.62916404541365e-07,3.62477569711206e-07,3.62039530352038e-07,3.61602284542434e-07,3.61165830366765e-07,3.60730165915176e-07,3.60295289283573e-07,3.59861198573592e-07,3.59427891892589e-07,3.58995367353608e-07,3.58563623075372e-07,3.58132657182253e-07,3.57702467804256e-07,3.57273053077e-07,3.56844411141695e-07,3.56416540145122e-07,3.55989438239615e-07,3.55563103583041e-07,3.55137534338776e-07,3.54712728675692e-07,3.5428868476813e-07,3.53865400795886e-07,3.53442874944189e-07,3.53021105403683e-07,3.52600090370405e-07,3.52179828045768e-07,3.51760316636541e-07,3.51341554354831e-07,3.50923539418062e-07,3.50506270048956e-07,3.50089744475517e-07,3.49673960931009e-07,3.49258917653939e-07,3.48844612888039e-07,3.48431044882244e-07,3.48018211890678e-07,3.47606112172631e-07,3.47194743992545e-07,3.46784105619993e-07,3.46374195329662e-07,3.45965011401334e-07,3.45556552119868e-07,3.45148815775184e-07,3.44741800662242e-07,3.44335505081025e-07,3.43929927336524e-07,3.43525065738718e-07,3.43120918602555e-07,3.42717484247937e-07,3.42314760999702e-07,3.41912747187606e-07,3.41511441146306e-07,3.41110841215343e-07,3.40710945739123e-07,3.40311753066904e-07,3.39913261552774e-07,3.39515469555638e-07,3.39118375439198e-07,3.3872197757194e-07,3.38326274327113e-07,3.37931264082715e-07,3.37536945221475e-07,3.37143316130838e-07,3.36750375202946e-07,3.36358120834626e-07,3.35966551427368e-07,3.35575665387313e-07,3.35185461125235e-07,3.34795937056524e-07,3.34407091601174e-07,3.34018923183761e-07,3.33631430233432e-07,3.33244611183886e-07,3.3285846447336e-07,3.32472988544613e-07,3.32088181844908e-07,3.31704042826002e-07,3.31320569944122e-07,3.30937761659958e-07,3.30555616438641e-07,3.30174132749734e-07,3.29793309067208e-07,3.29413143869436e-07,3.29033635639172e-07,3.28654782863536e-07,3.28276584034004e-07,3.27899037646386e-07,3.27522142200815e-07,3.27145896201733e-07,3.26770298157874e-07,3.26395346582248e-07,3.26021039992131e-07,3.25647376909045e-07,3.25274355858748e-07,3.24901975371217e-07,3.24530233980632e-07,3.24159130225366e-07,3.23788662647965e-07,3.2341882979514e-07,3.23049630217749e-07,3.2268106247078e-07,3.22313125113345e-07,3.21945816708658e-07,3.21579135824024e-07,3.21213081030826e-07,3.20847650904511e-07,3.20482844024574e-07,3.20118658974546e-07,3.1975509434198e-07,3.19392148718436e-07,3.1902982069947e-07,3.18668108884618e-07,3.18307011877384e-07,3.17946528285224e-07,3.17586656719536e-07,3.17227395795645e-07,3.16868744132789e-07,3.16510700354108e-07,3.16153263086628e-07,3.15796430961248e-07,3.1544020261273e-07,3.15084576679683e-07,3.14729551804551e-07,3.143751266336e-07,3.14021299816904e-07,3.13668070008337e-07,3.1331543586555e-07,3.12963396049971e-07,3.12611949226782e-07,3.12261094064911e-07,3.1191082923702e-07,3.1156115341949e-07,3.11212065292409e-07,3.10863563539562e-07,3.10515646848415e-07,3.10168313910106e-07,3.0982156341943e-07,3.09475394074827e-07,3.09129804578373e-07,3.08784793635763e-07,3.08440359956303e-07,3.08096502252896e-07,3.07753219242029e-07,3.07410509643764e-07,3.07068372181723e-07,3.06726805583078e-07,3.06385808578539e-07,3.06045379902341e-07,3.05705518292232e-07,3.05366222489466e-07,3.05027491238785e-07,3.04689323288409e-07,3.04351717390029e-07,3.04014672298788e-07,3.03678186773278e-07,3.0334225957552e-07,3.03006889470959e-07,3.02672075228449e-07,3.02337815620246e-07,3.02004109421989e-07,3.01670955412699e-07,3.01338352374757e-07,3.01006299093904e-07,3.00674794359219e-07,3.00343836963116e-07,3.00013425701331e-07,2.99683559372907e-07,2.99354236780189e-07,2.99025456728811e-07,2.98697218027681e-07,2.98369519488979e-07,2.98042359928135e-07,2.97715738163831e-07,2.97389653017978e-07,2.97064103315714e-07,2.9673908788539e-07,2.96414605558561e-07,2.96090655169972e-07,2.95767235557553e-07,2.95444345562403e-07,2.95121984028783e-07,2.94800149804106e-07,2.94478841738924e-07,2.94158058686921e-07,2.938377995049e-07,2.93518063052772e-07,2.93198848193552e-07,2.92880153793342e-07,2.92561978721323e-07,2.92244321849747e-07,2.91927182053926e-07,2.91610558212219e-07,2.91294449206026e-07,2.90978853919779e-07,2.90663771240928e-07,2.90349200059931e-07,2.9003513927025e-07,2.89721587768336e-07,2.89408544453622e-07,2.8909600822851e-07,2.88783977998366e-07,2.88472452671506e-07,2.88161431159192e-07,2.87850912375615e-07,2.87540895237893e-07,2.87231378666054e-07,2.86922361583035e-07,2.86613842914667e-07,2.86305821589664e-07,2.85998296539622e-07,2.85691266698999e-07,2.85384731005116e-07,2.8507868839814e-07,2.84773137821079e-07,2.84468078219771e-07,2.84163508542876e-07,2.83859427741867e-07,2.8355583477102e-07,2.83252728587406e-07,2.82950108150881e-07,2.82647972424078e-07,2.82346320372398e-07,2.82045150964001e-07,2.81744463169796e-07,2.81444255963435e-07,2.81144528321302e-07,2.80845279222503e-07,2.80546507648862e-07,2.80248212584908e-07,2.79950393017868e-07,2.79653047937658e-07,2.79356176336875e-07,2.79059777210788e-07,2.7876384955733e-07,2.78468392377089e-07,2.781734046733e-07,2.77878885451835e-07,2.77584833721198e-07,2.77291248492514e-07,2.7699812877952e-07,2.76705473598559e-07,2.76413281968571e-07,2.76121552911084e-07,2.75830285450207e-07,2.75539478612622e-07,2.75249131427571e-07,2.74959242926858e-07,2.74669812144829e-07,2.74380838118375e-07,2.74092319886915e-07,2.73804256492394e-07,2.73516646979272e-07,2.73229490394517e-07,2.72942785787597e-07,2.72656532210473e-07,2.7237072871759e-07,2.72085374365869e-07,2.71800468214701e-07,2.71516009325936e-07,2.71231996763879e-07,2.70948429595282e-07,2.7066530688933e-07,2.70382627717644e-07,2.70100391154265e-07,2.69818596275648e-07,2.69537242160658e-07,2.69256327890558e-07,2.68975852549005e-07,2.68695815222041e-07,2.68416214998085e-07,2.68137050967926e-07,2.67858322224716e-07,2.67580027863963e-07,2.67302166983523e-07,2.67024738683592e-07,2.667477420667e-07,2.66471176237704e-07,2.66195040303779e-07,2.65919333374412e-07,2.65644054561395e-07,2.65369202978817e-07,2.65094777743058e-07,2.64820777972781e-07,2.64547202788925e-07,2.64274051314698e-07,2.6400132267557e-07,2.63729015999267e-07,2.63457130415763e-07,2.63185665057272e-07,2.62914619058243e-07,2.62643991555352e-07,2.62373781687497e-07,2.62103988595787e-07,2.61834611423541e-07,2.61565649316275e-07,2.61297101421699e-07,2.61028966889712e-07,2.60761244872389e-07,2.60493934523981e-07,2.60227035000903e-07,2.59960545461732e-07,2.59694465067196e-07,2.5942879298017e-07,2.59163528365671e-07,2.58898670390847e-07,2.58634218224973e-07,2.58370171039444e-07,2.58106528007771e-07,2.57843288305571e-07,2.5758045111056e-07,2.57318015602551e-07,2.57055980963445e-07,2.56794346377222e-07,2.56533111029941e-07,2.56272274109728e-07,2.56011834806771e-07,2.55751792313316e-07,2.55492145823657e-07,2.55232894534136e-07,2.54974037643127e-07,2.54715574351041e-07,2.54457503860311e-07,2.54199825375389e-07,2.53942538102742e-07,2.53685641250842e-07,2.53429134030164e-07,2.53173015653175e-07,2.52917285334334e-07,2.52661942290079e-07,2.52406985738827e-07,2.52152414900967e-07,2.51898228998849e-07,2.51644427256785e-07,2.51391008901038e-07,2.51137973159819e-07,2.50885319263279e-07,2.50633046443508e-07,2.50381153934519e-07,2.50129640972254e-07,2.49878506794571e-07,2.4962775064124e-07,2.49377371753937e-07,2.49127369376239e-07,2.48877742753617e-07,2.48628491133433e-07,2.48379613764931e-07,2.48131109899234e-07,2.47882978789334e-07,2.47635219690095e-07,2.47387831858237e-07,2.47140814552337e-07,2.46894167032824e-07,2.46647888561968e-07,2.4640197840388e-07,2.46156435824504e-07,2.45911260091611e-07,2.45666450474795e-07,2.45422006245467e-07,2.45177926676849e-07,2.4493421104397e-07,2.44690858623658e-07,2.44447868694538e-07,2.44205240537025e-07,2.43962973433317e-07,2.43721066667394e-07,2.43479519525008e-07,2.43238331293681e-07,2.42997501262697e-07,2.427570287231e-07,2.42516912967687e-07,2.42277153291001e-07,2.4203774898933e-07,2.41798699360699e-07,2.41560003704864e-07,2.4132166132331e-07,2.41083671519243e-07,2.40846033597588e-07,2.4060874686498e-07,2.40371810629761e-07,2.40135224201976e-07,2.39898986893366e-07,2.39663098017364e-07,2.39427556889092e-07,2.3919236282535e-07,2.38957515144618e-07,2.38723013167047e-07,2.38488856214456e-07,2.38255043610324e-07,2.3802157467979e-07,2.37788448749643e-07,2.37555665148322e-07,2.37323223205906e-07,2.37091122254116e-07,2.36859361626301e-07,2.36627940657443e-07,2.36396858684145e-07,2.36166115044629e-07,2.35935709078732e-07,2.35705640127899e-07,2.35475907535182e-07,2.35246510645231e-07,2.35017448804291e-07,2.34788721360199e-07,2.34560327662378e-07,2.34332267061831e-07,2.34104538911139e-07,2.33877142564455e-07,2.33650077377499e-07,2.33423342707555e-07,2.33196937913465e-07,2.32970862355623e-07,2.32745115395976e-07,2.32519696398014e-07,2.32294604726767e-07,2.32069839748802e-07,2.31845400832217e-07,2.31621287346638e-07,2.31397498663211e-07,2.31174034154603e-07,2.30950893194994e-07,2.30728075160074e-07,2.30505579427036e-07,2.30283405374577e-07,2.30061552382886e-07,2.29840019833649e-07,2.29618807110036e-07,2.29397913596703e-07,2.29177338679783e-07,2.28957081746886e-07,2.2873714218709e-07,2.28517519390943e-07,2.28298212750453e-07,2.28079221659086e-07,2.27860545511761e-07,2.2764218370485e-07,2.27424135636167e-07,2.2720640070497e-07,2.26988978311951e-07,2.26771867859237e-07,2.26555068750385e-07,2.26338580390375e-07,2.26122402185609e-07,2.25906533543904e-07,2.25690973874492e-07,2.25475722588012e-07,2.25260779096507e-07,2.25046142813424e-07,2.24831813153601e-07,2.24617789533274e-07,2.24404071370065e-07,2.24190658082979e-07,2.23977549092406e-07,2.23764743820109e-07,2.23552241689226e-07,2.23340042124262e-07,2.2312814455109e-07,2.2291654839694e-07,2.22705253090402e-07,2.2249425806142e-07,2.22283562741286e-07,2.22073166562639e-07,2.21863068959457e-07}; // -// The number of bytes that are in the randomized buffer. -// AES 128 bit uses 16 byte blocks. -// -#define RANDOMNESS_BUFFER_SIZE 16 -#define RANDOMNESS_AES_KEY "0123456789012345" - -// // Encrypt the buffer of ctx and set its counter to 0 // static void aes_randomize_context(char *ctx) { AES_KEY key; + int tmp; - AES_set_encrypt_key((unsigned char *) RANDOMNESS_AES_KEY, 128, &key); + AES_set_encrypt_key((unsigned char *) "0123456789012345", 128, &key); - AES_encrypt((unsigned char *) ctx + 4, (unsigned char *) ctx + 4, &key); - ( (unsigned int *) ctx )[0] = 0; + ( (int *) ctx )[1]++; + for (tmp = 2; tmp < 6; tmp++) + ( (int *) ctx )[tmp] = ( (int *) ctx )[1]; + + AES_encrypt((unsigned char *) ctx + 8, (unsigned char *) ctx + 8, &key); + ( (int *) ctx )[0] = 0; } // // Get the int at the counter of ctx in the buffer of ctx. // -static unsigned int +static int aes_random(char *ctx) { - unsigned int *int_ctx = (unsigned int *) ctx; - if (int_ctx[0] < (RANDOMNESS_BUFFER_SIZE / 4)) { - unsigned int return_value = int_ctx[int_ctx[0] + 1]; + int *int_ctx = (int *) ctx; + if (int_ctx[0] < 4) { + int return_value = int_ctx[int_ctx[0] + 2]; int_ctx[0]++; return return_value; } else { aes_randomize_context(ctx); return aes_random(ctx); } - } // // Fill the buffer of ctx with seed and randomize it. // static void -aes_seed_context(char *ctx, unsigned int seed) +aes_seed_context(char *ctx, int seed) { - unsigned int tmp; + int tmp; - for (tmp = 1; tmp < ( (RANDOMNESS_BUFFER_SIZE / 4) + 1 ); tmp++) { - ( (unsigned int *) ctx )[tmp] = seed; - } + ( (int *) ctx )[1] = seed; + aes_randomize_context(ctx); } @@ -85,7 +81,7 @@ static VALUE get_aes_context() { - return rb_str_new(0, RANDOMNESS_BUFFER_SIZE + 4); + return rb_str_new(0, 16 + 4 + 16); } // @@ -93,20 +89,21 @@ // #define SEED(ctx, s) aes_seed_context(ctx, s) #define RAND(ctx) (((double) ((unsigned int) aes_random(ctx)))/((double)UINT_MAX)) -#define RANDOM(ctx, n) (( (unsigned int) aes_random(ctx) ) % n) +#define RANDOM(ctx, n) (( (unsigned int) aes_random(ctx)) % (n)) #define N_DATA_BLOCKS(self, block_size) (RSTRING(self)->len / block_size) #define N_AUX_BLOCKS(aux_blocks, block_size) (RSTRING(aux_blocks)->len / block_size) #define N_BLOCKS(self, aux_blocks, block_size) ((RSTRING(self)->len + RSTRING(aux_blocks)->len) / block_size) + // // Make dest into source1 ^ source2. // static void xor_string(char *dest, char *source1, char *source2, int len) { - unsigned int tmp; + int tmp; for (tmp = 0; tmp < (len / 4); tmp++) { - ( (unsigned int *) dest )[tmp] = ( (unsigned int *) source1 )[tmp] ^ ( (unsigned int *) source2 )[tmp]; + ( (int *) dest )[tmp] = ( (int *) source1 )[tmp] ^ ( (int *) source2 )[tmp]; } for (tmp = 0; tmp < (len % 4); tmp++) { dest[len - tmp - 1] = source1[len - tmp - 1] ^ source2[len - tmp - 1]; @@ -116,10 +113,10 @@ // // Get a random degree for a check block. // -static unsigned int -get_degree(unsigned int size, VALUE rnd_ctx) +static int +get_degree(int size, VALUE rnd_ctx) { - unsigned int rval = 1; + int rval = 1; double d = RAND(RSTRING(rnd_ctx)->ptr) - P[rval]; while (d > 0.0) { rval ++; @@ -135,21 +132,20 @@ // Return whether the block_number is known according to the decode_status. // static char -get_is_known(VALUE decode_status, unsigned int block_number) +get_is_known(VALUE decode_status, int block_number) { - unsigned int byte_in_status = block_number / 8; + int byte_in_status = block_number / 8; char bit_in_byte = 1 << (block_number % 8); - char rval = ((RSTRING(decode_status)->ptr[byte_in_status]) & bit_in_byte) == bit_in_byte; - return rval; + return ((RSTRING(decode_status)->ptr[byte_in_status]) & bit_in_byte) == bit_in_byte; } // // Set that the block_number is known according to the decode_status. // static void -set_is_known(VALUE decode_status, unsigned int block_number) +set_is_known(VALUE decode_status, int block_number) { - unsigned int byte_in_status = block_number / 8; + int byte_in_status = block_number / 8; char bit_in_byte = 1 << (block_number % 8); rb_str_modify(decode_status); RSTRING(decode_status)->ptr[byte_in_status] = RSTRING(decode_status)->ptr[byte_in_status] | bit_in_byte; @@ -159,7 +155,7 @@ // Set the data or aux block with index to be value, and set it as known. // static void -set_value(VALUE aux_blocks, unsigned int index, char *value, VALUE self, VALUE decode_status, unsigned int block_size) +set_value(VALUE aux_blocks, int index, char *value, VALUE self, VALUE decode_status, int block_size) { if ((index * block_size) < RSTRING(self)->len) { rb_str_modify(self); @@ -176,7 +172,7 @@ // Get the value at index from data or aux blocks. // static char* -get_value(VALUE aux_blocks, unsigned int index, VALUE self, unsigned int block_size) +get_value(VALUE aux_blocks, int index, VALUE self, int block_size) { if ((index * block_size) < RSTRING(self)->len) { return RSTRING(self)->ptr + (index * block_size); @@ -189,37 +185,26 @@ // Get a random check block of block_size from our data and aux blocks and append it to chunk at index. // static void -append_check_block(VALUE self, - unsigned int index, - VALUE aux_blocks, - VALUE rnd_ctx, - char *chunk, - unsigned int block_size) +append_check_block(VALUE self, int seed, int index, VALUE aux_blocks, VALUE rnd_ctx, char *chunk, int block_size) { - unsigned int degree; - unsigned int empty_block = 1; - unsigned int tmp; + int degree; + int empty_block = 1; + int tmp; - //DEBUGprintf("creating check block at %u:", index); - //DEBUGfflush(NULL); + // Find [degree] blocks. for (degree = get_degree(RSTRING(self)->len, rnd_ctx); degree > 0; degree--) { - unsigned int block_number = RANDOM(RSTRING(rnd_ctx)->ptr, N_BLOCKS(self, aux_blocks, block_size)); + int block_number = RANDOM(RSTRING(rnd_ctx)->ptr, N_BLOCKS(self, aux_blocks, block_size)); char *found_block = get_value(aux_blocks, block_number, self, block_size); - //DEBUGprintf(" %u(%hhu %hhu)", block_number, found_block[0], found_block[1]); - //DEBUGfflush(NULL); - // Create the block by xoring. if (empty_block) { - memcpy(chunk + index, found_block, block_size); + memcpy(chunk + (index * block_size), found_block, block_size); empty_block = 0; } else { xor_string(chunk + index, chunk + index, found_block, block_size); } } - //DEBUGprintf(" => (%hhu %hhu)\n", chunk[index], chunk[index + 1]); - //DEBUGfflush(NULL); } // @@ -238,21 +223,21 @@ _aes_seed_context(VALUE self, VALUE _ctx, VALUE _s) { char * ctx = STR2CSTR(_ctx); - unsigned int s = FIX2INT(_s); + int s = NUM2INT(_s); aes_seed_context(ctx, s); return Qnil; } // -// Get a random unsigned int from the context, mainly for testing purposes. +// Get a random int from the context, mainly for testing purposes. // static VALUE _aes_random(VALUE self, VALUE _ctx) { char * ctx = STR2CSTR(_ctx); - return INT2FIX(aes_random(ctx)); + return INT2NUM(aes_random(ctx)); } // @@ -273,9 +258,9 @@ _macro_random(VALUE self, VALUE _ctx, VALUE _lim) { char * ctx = STR2CSTR(_ctx); - unsigned int lim = FIX2INT(_lim); + int lim = NUM2INT(_lim); - return INT2FIX(RANDOM(ctx, lim)); + return INT2NUM(RANDOM(ctx, lim)); } // @@ -284,65 +269,56 @@ // Returns whether the decoding produced any new blocks. // static VALUE -_decode_chunk(VALUE self, VALUE _chunk, VALUE _decode_status, VALUE _aux_blocks, VALUE block_size_value, VALUE rnd_ctx) +_decode_chunk(VALUE self, VALUE _chunk, VALUE _decode_status, VALUE _aux_blocks, VALUE block_size_value) { VALUE chunk = (_chunk); VALUE decode_status = (_decode_status); VALUE aux_blocks = (_aux_blocks); - unsigned int seed = ( (unsigned int *) RSTRING(chunk)->ptr )[0]; - unsigned int tmp; + int seed = ( (int *) RSTRING(chunk)->ptr )[0]; + int size = ( (int *) RSTRING(chunk)->ptr )[1]; + int tmp; char got_new_block = 0; - unsigned int block_size = FIX2INT(block_size_value); - + VALUE rnd_ctx = get_aes_context(); + int block_size = NUM2INT(block_size_value); + SEED(RSTRING(rnd_ctx)->ptr, seed); for (tmp = 8; tmp < RSTRING(chunk)->len; tmp = tmp + block_size) { - unsigned int degree; - - //DEBUGprintf("looking at block at %u(%hhu %hhu):", tmp, RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); + int degree; - degree = get_degree(RSTRING(self)->len, rnd_ctx); + degree = get_degree(size, rnd_ctx); if (degree == 1) { - unsigned int block_nr; - block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, N_BLOCKS(self, aux_blocks, block_size)); - //DEBUGprintf(" [%u]", block_nr); + int block_nr; + block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, (size + RSTRING(aux_blocks)->len) / block_size); if (!get_is_known(decode_status, block_nr)) { set_value(aux_blocks, block_nr, RSTRING(chunk)->ptr + tmp, self, decode_status, block_size); got_new_block = 1; - //DEBUGprintf(" => (%hhu %hhu)", RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); - } else { - //DEBUGprintf(" = (%hhu %hhu)", RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); } } else { - unsigned int missing_blocks; - unsigned int missing_block = 0; - unsigned int tmp2; + int missing_blocks; + int missing_block = 0; + int tmp2; char xor_sum[block_size]; memcpy(xor_sum, RSTRING(chunk)->ptr + tmp, block_size); + for (missing_blocks = tmp2 = degree; tmp2 > 0; tmp2--) { - unsigned int block_nr; - block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, N_BLOCKS(self, aux_blocks, block_size)); - //DEBUGprintf(" [%u]", block_nr); + int block_nr; + block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, (size + RSTRING(aux_blocks)->len) / block_size); if (get_is_known(decode_status, block_nr)) { - unsigned int tmp3; + int tmp3; char *this_value = get_value(aux_blocks, block_nr, self, block_size); missing_blocks--; xor_string(xor_sum, xor_sum, this_value, block_size); - //DEBUGprintf("!(%hhu %hhu)", xor_sum[0], xor_sum[1]); } else { - //DEBUGprintf("?"); missing_block = block_nr; } } if (missing_blocks == 1) { set_value(aux_blocks, missing_block, xor_sum, self, decode_status, block_size); got_new_block = 1; - //DEBUGprintf(" => [%u](%hhu %hhu)", missing_block, xor_sum[0], xor_sum[1]); } } - //DEBUGprintf("\n"); - //DEBUGfflush(NULL); } return (got_new_block ? Qtrue : Qfalse); @@ -352,35 +328,31 @@ // Create the @_aux_blocks instance attribute with _size blocks and the given _q value. // static VALUE -_fill_aux_blocks(VALUE self, VALUE _size, VALUE _q, VALUE block_size_value, VALUE rnd_ctx) +_fill_aux_blocks(VALUE self, VALUE _size, VALUE _q, VALUE block_size_value) { - unsigned int size = FIX2INT(_size); - unsigned int q = FIX2INT(_q); - unsigned int block_size = FIX2INT(block_size_value); + int size = NUM2INT(_size); + int q = NUM2INT(_q); + int block_size = NUM2INT(block_size_value); char aux_blocks[size * block_size]; char initialized_aux_blocks[size]; - unsigned int tmp, tmp2, tmp3; + int tmp, tmp2, tmp3; + VALUE rnd_ctx = get_aes_context(); - for (tmp = 0; tmp < (size * block_size); tmp++) + for (tmp = 0; tmp < size; tmp++) initialized_aux_blocks[tmp] = 0; SEED(RSTRING(rnd_ctx)->ptr, RSTRING(self)->len); for (tmp = 0; tmp < RSTRING(self)->len; tmp = tmp + block_size) { - //DEBUGprintf("creating aux block for block at %u(%hhu %hhu):", tmp, RSTRING(self)->ptr[tmp], RSTRING(self)->ptr[tmp + 1]); for (tmp2 = 0; tmp2 < q; tmp2++) { - unsigned int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); - //DEBUGprintf(" %u", aux_block_nr); + int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); if (initialized_aux_blocks[aux_block_nr]) { xor_string(aux_blocks + (aux_block_nr * block_size), aux_blocks + (aux_block_nr * block_size), RSTRING(self)->ptr + tmp, block_size); } else { memcpy(aux_blocks + (aux_block_nr * block_size), RSTRING(self)->ptr + tmp, block_size); initialized_aux_blocks[aux_block_nr] = 1; } - //DEBUGprintf("=>(%hhu %hhu)", aux_blocks[aux_block_nr * block_size], aux_blocks[aux_block_nr * block_size + 1]); } - //DEBUGprintf("\n"); - //DEBUGfflush(NULL); } rb_ivar_set(self, rb_intern("@_aux_blocks"), rb_str_new(aux_blocks, size * block_size)); return Qnil; @@ -390,25 +362,26 @@ // Return a chunk of check blocks that is _chunk_size big. // static VALUE -_get_chunk(VALUE self, VALUE _chunk_size, VALUE _aux_blocks, VALUE block_size_value, VALUE rnd_ctx) +_get_chunk(VALUE self, VALUE _chunk_size, VALUE _aux_blocks, VALUE block_size_value) { - unsigned int chunk_size = FIX2INT(_chunk_size); + int chunk_size = NUM2INT(_chunk_size); VALUE aux_blocks = (_aux_blocks); - unsigned int block_size = FIX2INT(block_size_value); + int block_size = NUM2INT(block_size_value); unsigned int tmp; - unsigned int seed; + int seed; struct timeval tmp_timeval; char chunk[chunk_size]; + VALUE rnd_ctx = get_aes_context(); gettimeofday(&tmp_timeval, NULL); srandom(tmp_timeval.tv_usec); seed = random(); - ( (unsigned int *) chunk) [0] = seed; - ( (unsigned int *) chunk) [1] = RSTRING(self)->len; + ( (int *) chunk) [0] = seed; + ( (int *) chunk) [1] = RSTRING(self)->len; SEED(RSTRING(rnd_ctx)->ptr, seed); for (tmp = 8; tmp < chunk_size; tmp = tmp + block_size) { - append_check_block(self, tmp, aux_blocks, rnd_ctx, chunk, block_size); + append_check_block(self, seed, tmp, aux_blocks, rnd_ctx, chunk, block_size); } return (rb_str_new(chunk, chunk_size)); @@ -418,40 +391,42 @@ // Create the instance attribute @_aux_hash containing the structure of our aux blocks. // static VALUE -_fill_aux_hash(VALUE self, VALUE _q, VALUE _size, VALUE block_size_value, VALUE rnd_ctx) +_fill_aux_hash(VALUE self, VALUE _q, VALUE _size, VALUE block_size_value) { - unsigned int q = FIX2INT(_q); - unsigned int size = FIX2INT(_size); - unsigned int block_size = FIX2INT(block_size_value); - unsigned int tmp, tmp2; + int q = NUM2INT(_q); + int size = NUM2INT(_size); + int block_size = NUM2INT(block_size_value); + + int tmp, tmp2; VALUE aux_ary = rb_ary_new(); VALUE set_func = rb_intern("[]="); VALUE get_func = rb_intern("[]"); VALUE push_func = rb_intern("<<"); + VALUE size_func = rb_intern("size"); + VALUE rnd_ctx = get_aes_context(); SEED(RSTRING(rnd_ctx)->ptr, RSTRING(self)->len); - - for (tmp = 0; tmp < (RSTRING(self)->len / block_size); tmp++) { + for (tmp = 0; tmp < RSTRING(self)->len; tmp++) { for (tmp2 = 0; tmp2 < q; tmp2++) { - unsigned int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); + int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); VALUE data_blocks_for_this_aux_block; - if ((data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2FIX(aux_block_nr))) == Qnil) - rb_funcall(aux_ary, set_func, 2, INT2FIX(aux_block_nr), (data_blocks_for_this_aux_block = rb_ary_new())); - rb_funcall(data_blocks_for_this_aux_block, push_func, 1, INT2FIX(tmp)); + if ((data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2NUM(aux_block_nr))) == Qnil) + rb_funcall(aux_ary, set_func, 2, INT2NUM(aux_block_nr), (data_blocks_for_this_aux_block = rb_ary_new())); + rb_funcall(data_blocks_for_this_aux_block, push_func, 1, INT2NUM(tmp)); } } for (tmp = 0; tmp < size; tmp++) { - VALUE data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2FIX(tmp)); - unsigned int number_of_data_blocks = RARRAY(data_blocks_for_this_aux_block)->len; + VALUE data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2NUM(tmp)); + int number_of_data_blocks = NUM2INT(rb_funcall(data_blocks_for_this_aux_block, size_func, 0)); VALUE data_block_string = rb_str_new(0, number_of_data_blocks * 4); for (tmp2 = 0; tmp2 < number_of_data_blocks; tmp2++) { rb_str_modify(data_block_string); - ( (unsigned int *) RSTRING(data_block_string)->ptr )[tmp2] = (unsigned int) FIX2INT(rb_funcall(data_blocks_for_this_aux_block, - get_func, - 1, - INT2FIX(tmp2))); + ( (int *) RSTRING(data_block_string)->ptr )[tmp2] = (int) NUM2INT(rb_funcall(data_blocks_for_this_aux_block, + get_func, + 1, + INT2NUM(tmp2))); } - rb_funcall(aux_ary, set_func, 2, INT2FIX(tmp), data_block_string); + rb_funcall(aux_ary, set_func, 2, INT2NUM(tmp), data_block_string); } rb_ivar_set(self, rb_intern("@_aux_hash"), aux_ary); return Qnil; @@ -463,11 +438,10 @@ static VALUE _oneline_done(VALUE self, VALUE decode_status, VALUE block_size_value) { - unsigned int block_size = FIX2INT(block_size_value); - unsigned int tmp; - unsigned int number_of_ints = (RSTRING(self)->len / block_size) / 32; - unsigned int number_of_chars = (RSTRING(self)->len / block_size) / 8; - unsigned int number_of_bits = (RSTRING(self)->len / block_size); + int block_size = NUM2INT(block_size_value); + int tmp; + int number_of_ints = RSTRING(self)->len / 32; + int number_of_chars = RSTRING(self)->len / 8; if (decode_status == Qnil) return (Qfalse); @@ -477,7 +451,7 @@ for (tmp = (number_of_ints * 4); tmp < number_of_chars; tmp++) if (( (unsigned char) RSTRING(decode_status)->ptr[tmp] ) != UCHAR_MAX) return (Qfalse); - for (tmp = 0; tmp < (number_of_bits % 8); tmp++) + for (tmp = 0; tmp < ((RSTRING(self)->len / block_size) % 8); tmp++) if (! (( (unsigned char) RSTRING(decode_status)->ptr[RSTRING(decode_status)->len - 1] ) & (1 << tmp))) return (Qfalse); return (Qtrue); @@ -492,56 +466,46 @@ VALUE decode_status = (_decode_status); VALUE aux_blocks = (_aux_blocks); VALUE aux_hash = (_aux_hash); - unsigned int block_size = FIX2INT(block_size_value); + int block_size = NUM2INT(block_size_value); - unsigned int tmp; + int tmp; char got_new_block = 0; VALUE get_func = rb_intern("[]"); for (tmp = 0; tmp < RSTRING(aux_blocks)->len; tmp = tmp + block_size) { if (get_is_known(decode_status, (RSTRING(self)->len + tmp) / block_size)) { - //DEBUGprintf("looking at aux block at %u(%hhu %hhu):", tmp, RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); - VALUE data_block_string = rb_funcall(aux_hash, get_func, 1, INT2FIX(tmp / block_size)); + VALUE data_block_string = rb_funcall(aux_hash, get_func, 1, INT2NUM(tmp)); if (RSTRING(data_block_string)->len == 4) { - unsigned int block_nr = ( (unsigned int *) RSTRING(data_block_string)->ptr )[0]; - //DEBUGprintf(" [%u]", block_nr); + int block_nr = ( (int *) RSTRING(data_block_string)->ptr )[0]; if (!get_is_known(decode_status, block_nr)) { set_value(aux_blocks, block_nr, RSTRING(aux_blocks)->ptr + tmp, self, decode_status, block_size); got_new_block = 1; - //DEBUGprintf(" => (%hhu %hhu)", RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); } else { - //DEBUGprintf(" = (%hhu %hhu)", RSTRING(aux_blocks)->ptr[tmp], RSTRING(aux_blocks)->ptr[tmp + 1]); } } else { - unsigned int missing_blocks; - unsigned int missing_block = 0; - unsigned int tmp2; + int missing_blocks; + int missing_block = 0; + int tmp2; char xor_sum[block_size]; memcpy(xor_sum, RSTRING(aux_blocks)->ptr + tmp, block_size); for (missing_blocks = (tmp2 = ((RSTRING(data_block_string)->len / 4) - 1)) + 1; tmp2 > -1; tmp2--) { - unsigned int block_nr = ( (unsigned int *) RSTRING(data_block_string)->ptr )[tmp2]; - //DEBUGprintf(" [%u]", block_nr); + int block_nr = ( (int *) RSTRING(data_block_string)->ptr )[tmp2]; if (get_is_known(decode_status, block_nr)) { - unsigned int tmp3; + int tmp3; char *this_value = get_value(aux_blocks, block_nr, self, block_size); missing_blocks--; xor_string(xor_sum, xor_sum, this_value, block_size); - //DEBUGprintf("!(%hhu %hhu)", this_value[0], this_value[1]); } else { missing_block = block_nr; - //DEBUGprintf("?"); - } + } } if (missing_blocks == 1) { set_value(aux_blocks, missing_block, xor_sum, self, decode_status, block_size); got_new_block = 1; - //DEBUGprintf(" => [%u](%hhu %hhu)", xor_sum[0], xor_sum[1]); } } - //DEBUGprintf("\n"); - //DEBUGfflush(NULL); } } @@ -559,11 +523,11 @@ rb_define_method(c, "_aes_random", (VALUE(*)(ANYARGS))_aes_random, 1); rb_define_method(c, "_aes_seed_context", (VALUE(*)(ANYARGS))_aes_seed_context, 2); rb_define_method(c, "_aux_decode", (VALUE(*)(ANYARGS))_aux_decode, 4); - rb_define_method(c, "_decode_chunk", (VALUE(*)(ANYARGS))_decode_chunk, 5); - rb_define_method(c, "_fill_aux_blocks", (VALUE(*)(ANYARGS))_fill_aux_blocks, 4); - rb_define_method(c, "_fill_aux_hash", (VALUE(*)(ANYARGS))_fill_aux_hash, 4); + rb_define_method(c, "_decode_chunk", (VALUE(*)(ANYARGS))_decode_chunk, 4); + rb_define_method(c, "_fill_aux_blocks", (VALUE(*)(ANYARGS))_fill_aux_blocks, 3); + rb_define_method(c, "_fill_aux_hash", (VALUE(*)(ANYARGS))_fill_aux_hash, 3); rb_define_method(c, "_get_aes_context", (VALUE(*)(ANYARGS))_get_aes_context, 0); - rb_define_method(c, "_get_chunk", (VALUE(*)(ANYARGS))_get_chunk, 4); + rb_define_method(c, "_get_chunk", (VALUE(*)(ANYARGS))_get_chunk, 3); rb_define_method(c, "_macro_rand", (VALUE(*)(ANYARGS))_macro_rand, 1); rb_define_method(c, "_macro_random", (VALUE(*)(ANYARGS))_macro_random, 2); rb_define_method(c, "_oneline_done", (VALUE(*)(ANYARGS))_oneline_done, 2); Modified: trunk/oneliner/lib/oneliner/superstring.rb =================================================================== --- trunk/oneliner/lib/oneliner/superstring.rb 2007-01-15 13:57:35 UTC (rev 166) +++ trunk/oneliner/lib/oneliner/superstring.rb 2007-01-17 16:46:36 UTC (rev 167) @@ -15,146 +15,349 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'set' +require 'digest/sha2' + module Oneliner # # A String subclass providing Online Code functionality. # class SuperString < String - + + MAXLONG = "\377\377\377\377".unpack("L*")[0] E = 0.01 Q = 3 + F = (Math.log((E ** 2) / 4) / Math.log(1 - (E / 2))).abs.to_i + P = [0, (1 - ((1 + (1 / F)) / (1 + E)))] + 2.upto(F) do |i| + P << (((1 - P[1]) * F) / ((F - 1) * i * (i - 1))) + end - # - # Will return a chunk of check blocks for this SuperString. - # - # The chunk will have size +chunk_size+. Be aware that the first - # 8 bytes are used for metadata, so smaller chunks than that will - # result in errors. - # - def oneline_encode!(chunk_size) - ctx = _get_aes_context - block_size = get_block_size - ensure_aux_blocks(ctx, block_size) - ensure_encode_size(block_size) - return _get_chunk(chunk_size, @_aux_blocks, block_size, ctx) + class Context + def initialize(s = (Kernel.srand && Kernel.rand(MAXLONG))) + self.seed = s + end + def seed=(s) + @seed = s + randomize(s) + end + def seed + @seed + end + def rand(max = false) + randomize(@source) if @index << 2 >= @source.size + if max + rval = @source.unpack("@#{@index * 4}L").first % max + @index += 1 + return rval + else + rval = @source.unpack("@#{@index * 4}f").first.abs + @index += 1 + return rval + end + end + private + def randomize(s) + @index = 0 + @source = Digest::SHA512.hexdigest("#{s}") + end end - # - # Will try to restore this SuperString from the given +chunk+. - # - # Will also remember the chunk for future reference if it was not - # enough to decode the entire SuperString. - # - # Will return whether the given data + any previouly given data - # is enough. - # - def oneline_decode!(chunk) + def encode(requested_size) + raise "requested size is too small for metadata (8 bytes)" unless requested_size > 7 + + rval = "" - ensure_decode_size(chunk) - block_size = get_block_size - ensure_encode_size(block_size) + block_size = get_block_size(self.size) + ensure_encode_format(block_size) + context = Context.new - @_decode_status ||= "\000" * ((((size + get_aux_blocks) / block_size) / 8) + 1) - @_known_chunks ||= [] - @_aux_blocks ||= "\000" * (get_aux_blocks * block_size) + rval << [self.size].pack("L*") + rval << [context.seed].pack("L*") - ctx = _get_aes_context - found_new_block = _decode_chunk(chunk, @_decode_status, @_aux_blocks, block_size, ctx) + blocks = [] + while (blocks.size * block_size) / 8 < (requested_size - 8) + blocks << generate_check_block(context) + end - @_known_chunks.unshift(chunk) + return rval + compact(blocks, block_size) + end + def decode(chunk) + raise "chunk is too small for metadata (8 bytes)" unless chunk.size > 7 + + context = Context.new + requested_size = chunk[0..3].unpack("L*").first + the_seed = chunk[4..7].unpack("L*").first + block_size = get_block_size(requested_size) + chunk_data = { + :blocks => expand(chunk[8..-1], block_size), + :context => context, + :seed => the_seed + } + + ensure_decode_format(requested_size, block_size) + + found_new_block = decode_chunk(chunk_data, context) + + @known_chunks.unshift(chunk_data) + if found_new_block - nil while do_decode(block_size, ctx) + nil while do_decode(context) end + + if decode_done + self.replace(compact(@blocks[0.. at data_blocks], block_size)) + return true + else + return false + end + end - return oneline_done(block_size) + def decode_done + data = @blocks[0.. at data_blocks] + data.compact.size == data.size end +# private + # - # Returns whether the decoding is done. + # Misc stuff # - def oneline_done(block_size = get_block_size) - if @_decode_status - if _oneline_done(@_decode_status, block_size) - slice!(@_original_size..-1) - true - else - false - end + + def expand(s, block_size) + if block_size < 8 + rval = s.unpack("b*").first + rval = rval.gsub(/(.{#{block_size},#{block_size}})/, "\\1#{"0" * (8 - block_size)}") + rval += "0" * (8 - (rval.size % 8)) if (rval.size % 8) > 0 + rval = [rval].pack("b*") + return rval.split(//) + elsif block_size == 8 + return rval.split(//) else - return nil + raise "block sizes > 8 not yet supported" end end + + def compact(blocks, block_size) + if block_size < 8 + rval = blocks.join + rval = rval.unpack("b*") + rval = rval.first.gsub(/(.{#{block_size},#{block_size}}).{#{8 - block_size},#{8 - block_size}}/, + "\\1") + rval = rval[0...(-(rval.size % 8))] if (rval.size % 8) > 0 + return [rval].pack("b*") + elsif block_size == 8 + return rval.join + else + raise "block sizes > 8 not yet supported" + end + end + + def get_degree(context) + f = context.rand + P.each_with_index do |p, i| + f -= p + return i if f < 0 + end + return P.size + end - # - # Returns the decode status of all bytes in this String. - # - def decode_status - return nil unless @_decode_status - @_decode_status.unpack("b*").first + def get_aux_blocks(nr_of_data_blocks) + (0.55 * Q * E * nr_of_data_blocks).ceil end + def get_block_size(string_size) + return 1 + end + + def xor(s1, s2) + rval = "" + s1.split(//).each_with_index do |b, i| + rval << (s1[i] ^ s2[i]).chr + end + return rval + end + # - # Returns the relative decode status of this entire String. + # Decoding stuff # - def decode_level(block_size = get_block_size) - ones = 0 - decode_status[0..(size + @_aux_blocks.size)].split(//).each do |s| - ones += 1 if s == "1" + + def do_decode(context) + found_new_block = false + @known_chunks.each do |chunk_data| + found_new_block = decode_chunk(chunk_data, context) || found_new_block end - ones.to_f / ((size + @_aux_blocks.size) / block_size).to_f + found_new_block = aux_decode || found_new_block + return found_new_block end - private + def aux_decode + got_new_block = false - def ensure_encode_size(block_size) - @_original_size ||= nil - unless @_original_size - @_original_size = size - if size % block_size != 0 - concat(" " * (block_size - (size % block_size))) + @data_blocks.upto(@blocks.size - 1) do |i| + aux_block = @blocks[i] + if aux_block + source_blocks = @aux_hash[i - @data_blocks] + if source_blocks.size == 1 + block_nr = source_blocks.first + if @blocks[block_nr].nil? + @blocks[block_nr] = aux_block + got_new_block = true + end + else + missing_blocks = source_blocks.size + missing_block = nil + xor_sum = aux_block + source_blocks.each do |block| + source_block = @blocks[block] + if source_block + missing_blocks -= 1 + xor_sum = xor(xor_sum, source_block) + else + missing_block = block + end + end + + if missing_blocks == 1 + @blocks[missing_block] = xor_sum + got_new_block = true + end + end end end + + return got_new_block end - def get_aux_blocks - (self.size * (Q * E * 0.55)).ceil + def decode_chunk(chunk_data, context) + got_new_block = false + + context.seed = chunk_data[:seed] + + chunk_data[:blocks].each do |block| + degree = get_degree(context) + + if degree == 1 + block_nr = context.rand(@blocks.size) + + if @blocks[block_nr].nil? + @blocks[block_nr] = block + got_new_block = true + end + else + missing_blocks = degree + missing_block_nr = nil + xor_sum = block + degree.downto(1) do + block_nr = context.rand(@blocks.size) + + if @blocks[block_nr] + xor_sum = xor(xor_sum, @blocks[block_nr]) + missing_blocks -= 1 + else + missing_block_nr = block_nr + end + + end + + if missing_blocks == 1 + @block[block_nr] = xor_sum + got_new_block = true + end + end + end + + return got_new_block end - def do_decode(block_size, ctx) - found_new_block = false - @_known_chunks.each do |known_chunk| - found_new_block = _decode_chunk(known_chunk, @_decode_status, @_aux_blocks, block_size, ctx) || found_new_block + def generate_aux_hash + rval = Array.new(get_aux_blocks(@blocks.size)) + + context = Context.new(@blocks.size) + + @blocks.each_with_index do |b, i| + 1.upto(Q) do + aux_block_nr = context.rand(rval.size) + rval[aux_block_nr] ||= [] + rval[aux_block_nr] << i + end end - ensure_aux_hash(block_size, ctx) - found_new_block = _aux_decode(@_decode_status, @_aux_blocks, @_aux_hash, block_size) || found_new_block - return found_new_block + + return rval end - def get_block_size - return 1 + def ensure_decode_format(requested_size, block_size) + unless @blocks + self.concat("\000" * requested_size) + @blocks = Array.new(expand(self, block_size).size) + @data_blocks = @blocks.size + @blocks += Array.new(get_aux_blocks(@blocks.size)) + @aux_hash = generate_aux_hash + @known_chunks ||= [] + end end - - def ensure_decode_size(chunk) - needed_size = chunk[4..7].unpack("L").first + + def ensure_size(requested_size) if size == 0 - concat("\000" * needed_size) - elsif size != needed_size - raise "The argument to oneline_decode must be a chunk produced by oneline_encode from the same source" + concat("\000" * requested_size) + @decoded_blocks = Set.new + elsif size != requested_size + raise "size of #{self} (#{size}) is wrong, should be #{requested_size}" end end - def ensure_aux_blocks(ctx, block_size) - @_aux_blocks ||= nil - _fill_aux_blocks(get_aux_blocks, Q, block_size, ctx) unless @_aux_blocks + # + # Encoding stuff + # + + def generate_check_block(context) + print "generating check block:" + block_nr = context.rand(@blocks.size) + rval = @blocks[block_nr] + print " [#{block_nr}](#{blocks[block_nr]}), " + + degree = get_degree(context) + + 2.upto(degree) do + block_nr = context.rand(@blocks.size) + rval = xor(rval, @blocks[block_nr]) + print " [#{block_nr}](#{blocks[block_nr]}), " + end + puts " => #{rval}" + return rval end + + def generate_aux_blocks + rval = Array.new(get_aux_blocks(@blocks.size)) - def ensure_aux_hash(block_size, ctx) - @_aux_hash ||= nil - _fill_aux_hash(Q, get_aux_blocks, block_size, ctx) unless @_aux_hash + context = Context.new(@blocks.size) + + @blocks.each_with_index do |b, i| + print "generating aux blocks for #{i}:" + 1.upto(Q) do + aux_block_nr = context.rand(rval.size) + if rval[aux_block_nr].nil? + rval[aux_block_nr] = b + else + rval[aux_block_nr] = xor(rval[aux_block_nr], b) + end + print " #{aux_block_nr} => #{rval[aux_block_nr]}, " + end + puts + end + + return rval end - + + def ensure_encode_format(block_size) + unless @blocks + @blocks = expand(self, block_size) + @blocks += generate_aux_blocks + end + end + end end Modified: trunk/oneliner/tests/superstring_benchmark.rb =================================================================== --- trunk/oneliner/tests/superstring_benchmark.rb 2007-01-15 13:57:35 UTC (rev 166) +++ trunk/oneliner/tests/superstring_benchmark.rb 2007-01-17 16:46:36 UTC (rev 167) @@ -24,14 +24,9 @@ end def measure_required(dest, source) - total = source.size.to_f - used = source.size.to_f dest.oneline_decode!(source.oneline_encode!(source.size)) - while (!dest.oneline_decode!(source.oneline_encode!((source.size.to_f * 0.01).to_i + 8))) - used += (source.size.to_f * 0.01) - end - return used/total + nil while (!dest.oneline_decode!(source.oneline_encode!((source.size.to_f * 0.1).to_i + 8))) + return dest.instance_eval do @_used_blocks end.to_f / source.size.to_f end - end From nobody at rubyforge.org Wed Jan 17 12:36:34 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Wed, 17 Jan 2007 12:36:34 -0500 (EST) Subject: [Archipelago-submits] [168] trunk/oneliner/lib/oneliner/superstring.rb: working??!?! Message-ID: <20070117173634.936CF52416CD@rubyforge.org> Revision: 168 Author: zond Date: 2007-01-17 12:36:34 -0500 (Wed, 17 Jan 2007) Log Message: ----------- working??!?! Modified Paths: -------------- trunk/oneliner/lib/oneliner/superstring.rb Modified: trunk/oneliner/lib/oneliner/superstring.rb =================================================================== --- trunk/oneliner/lib/oneliner/superstring.rb 2007-01-17 16:46:36 UTC (rev 167) +++ trunk/oneliner/lib/oneliner/superstring.rb 2007-01-17 17:36:34 UTC (rev 168) @@ -39,6 +39,7 @@ self.seed = s end def seed=(s) + puts "seeding with #{s}" @seed = s randomize(s) end @@ -47,20 +48,20 @@ end def rand(max = false) randomize(@source) if @index << 2 >= @source.size + number = @source.unpack("@#{@index * 4}L").first + @index += 1 if max - rval = @source.unpack("@#{@index * 4}L").first % max - @index += 1 - return rval + return number % max else - rval = @source.unpack("@#{@index * 4}f").first.abs - @index += 1 - return rval + return number.to_f / MAXLONG.to_f end end private def randomize(s) @index = 0 - @source = Digest::SHA512.hexdigest("#{s}") + @source = Digest::SHA512.hexdigest("#{s}").gsub(/(.{2,2})/, ",\\1").split(/,/)[1..-1].collect do |byte| + byte.hex + end.pack("C*") end end @@ -78,7 +79,7 @@ blocks = [] while (blocks.size * block_size) / 8 < (requested_size - 8) - blocks << generate_check_block(context) + blocks << generate_check_block(context, blocks.size) end return rval + compact(blocks, block_size) @@ -236,15 +237,22 @@ context.seed = chunk_data[:seed] - chunk_data[:blocks].each do |block| + chunk_data[:blocks].each_with_index do |block, i| + print "looking at check block [#{i}](#{block.inspect}):" + degree = get_degree(context) if degree == 1 block_nr = context.rand(@blocks.size) + print " [#{block_nr}]" + if @blocks[block_nr].nil? @blocks[block_nr] = block got_new_block = true + print "! => #{block.inspect}" + else + print " => #{block.inspect}" end else missing_blocks = degree @@ -253,20 +261,26 @@ degree.downto(1) do block_nr = context.rand(@blocks.size) + print " [#{block_nr}]" + if @blocks[block_nr] + print "!" xor_sum = xor(xor_sum, @blocks[block_nr]) missing_blocks -= 1 else + print "?" missing_block_nr = block_nr end end if missing_blocks == 1 - @block[block_nr] = xor_sum + @blocks[missing_block_nr] = xor_sum got_new_block = true + print " => [#{missing_block_nr}]=#{xor_sum.inspect}" end end + puts end return got_new_block @@ -312,20 +326,20 @@ # Encoding stuff # - def generate_check_block(context) - print "generating check block:" + def generate_check_block(context, n) + degree = get_degree(context) + + print "generating check block [#{n}]:" block_nr = context.rand(@blocks.size) rval = @blocks[block_nr] - print " [#{block_nr}](#{blocks[block_nr]}), " + print " [#{block_nr}](#{@blocks[block_nr].inspect}), " - degree = get_degree(context) - 2.upto(degree) do block_nr = context.rand(@blocks.size) rval = xor(rval, @blocks[block_nr]) - print " [#{block_nr}](#{blocks[block_nr]}), " + print " [#{block_nr}](#{@blocks[block_nr].inspect}), " end - puts " => #{rval}" + puts " => #{rval.inspect}" return rval end @@ -335,7 +349,7 @@ context = Context.new(@blocks.size) @blocks.each_with_index do |b, i| - print "generating aux blocks for #{i}:" + print "generating aux blocks for [#{i}](#{b.inspect}):" 1.upto(Q) do aux_block_nr = context.rand(rval.size) if rval[aux_block_nr].nil? @@ -343,7 +357,7 @@ else rval[aux_block_nr] = xor(rval[aux_block_nr], b) end - print " #{aux_block_nr} => #{rval[aux_block_nr]}, " + print " #{aux_block_nr} => #{rval[aux_block_nr].inspect}, " end puts end From nobody at rubyforge.org Thu Jan 18 11:11:44 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Jan 2007 11:11:44 -0500 (EST) Subject: [Archipelago-submits] [169] trunk/oneliner: now with tests and benchmarks Message-ID: <20070118161145.1137D5242720@rubyforge.org> Revision: 169 Author: zond Date: 2007-01-18 11:11:44 -0500 (Thu, 18 Jan 2007) Log Message: ----------- now with tests and benchmarks Modified Paths: -------------- trunk/oneliner/ext/superstring_ext.c trunk/oneliner/lib/oneliner/superstring.rb trunk/oneliner/tests/superstring_benchmark.rb trunk/oneliner/tests/superstring_test.rb Modified: trunk/oneliner/ext/superstring_ext.c =================================================================== --- trunk/oneliner/ext/superstring_ext.c 2007-01-17 17:36:34 UTC (rev 168) +++ trunk/oneliner/ext/superstring_ext.c 2007-01-18 16:11:44 UTC (rev 169) @@ -15,6 +15,12 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// DEPRECATION NOTICE: Note that this file is not used AT ALL at this time. +// It is only a rest from the last version of the code, and acts as a placeholder +// for the next round of optimization. +// + #include "ruby.h" #include #include Modified: trunk/oneliner/lib/oneliner/superstring.rb =================================================================== --- trunk/oneliner/lib/oneliner/superstring.rb 2007-01-17 17:36:34 UTC (rev 168) +++ trunk/oneliner/lib/oneliner/superstring.rb 2007-01-18 16:11:44 UTC (rev 169) @@ -24,7 +24,7 @@ # A String subclass providing Online Code functionality. # class SuperString < String - + MAXLONG = "\377\377\377\377".unpack("L*")[0] E = 0.01 Q = 3 @@ -35,11 +35,15 @@ end class Context - def initialize(s = (Kernel.srand && Kernel.rand(MAXLONG))) + def initialize(s = nil) + unless s + Kernel.srand + s = Kernel.rand(MAXLONG) + end self.seed = s end def seed=(s) - puts "seeding with #{s}" + puts "seeding with #{s}" if $DEBUG @seed = s randomize(s) end @@ -67,14 +71,11 @@ def encode(requested_size) raise "requested size is too small for metadata (8 bytes)" unless requested_size > 7 - - rval = "" - block_size = get_block_size(self.size) - ensure_encode_format(block_size) + ensure_encode_format context = Context.new - - rval << [self.size].pack("L*") + + rval = [self.size].pack("L*") rval << [context.seed].pack("L*") blocks = [] @@ -82,26 +83,28 @@ blocks << generate_check_block(context, blocks.size) end - return rval + compact(blocks, block_size) + return rval + compact(blocks) end - def decode(chunk) + def decode!(chunk) raise "chunk is too small for metadata (8 bytes)" unless chunk.size > 7 context = Context.new + requested_size = chunk[0..3].unpack("L*").first + + ensure_decode_format(requested_size) + the_seed = chunk[4..7].unpack("L*").first - block_size = get_block_size(requested_size) + chunk_data = { - :blocks => expand(chunk[8..-1], block_size), + :blocks => expand(chunk[8..-1]), :context => context, :seed => the_seed } - ensure_decode_format(requested_size, block_size) + found_new_block = decode_chunk(chunk_data) - found_new_block = decode_chunk(chunk_data, context) - @known_chunks.unshift(chunk_data) if found_new_block @@ -109,7 +112,7 @@ end if decode_done - self.replace(compact(@blocks[0.. at data_blocks], block_size)) + self.replace(compact(@blocks[0...nr_of_blocks])) return true else return false @@ -117,42 +120,47 @@ end def decode_done - data = @blocks[0.. at data_blocks] + data = @blocks[0...nr_of_blocks] data.compact.size == data.size end -# private + private # # Misc stuff # - - def expand(s, block_size) + + def used_blocks + @known_chunks.inject(0) do |sum, chunk_data| + sum + chunk_data[:blocks].size + end + end + + def expand(s) if block_size < 8 rval = s.unpack("b*").first rval = rval.gsub(/(.{#{block_size},#{block_size}})/, "\\1#{"0" * (8 - block_size)}") rval += "0" * (8 - (rval.size % 8)) if (rval.size % 8) > 0 rval = [rval].pack("b*") return rval.split(//) - elsif block_size == 8 - return rval.split(//) else - raise "block sizes > 8 not yet supported" + bytes_per_block = block_size / 8 + rval = s + rval += "\000" * (bytes_per_block - (rval.size % bytes_per_block)) if (rval.size % bytes_per_block) > 0 + return rval.gsub(/(.{#{bytes_per_block},#{bytes_per_block}})/, ",\\1").split(/,/)[1..-1] end end - def compact(blocks, block_size) + def compact(blocks) if block_size < 8 rval = blocks.join rval = rval.unpack("b*") rval = rval.first.gsub(/(.{#{block_size},#{block_size}}).{#{8 - block_size},#{8 - block_size}}/, "\\1") - rval = rval[0...(-(rval.size % 8))] if (rval.size % 8) > 0 + rval += "0" * (8 - (rval.size % 8)) if (rval.size % 8) > 0 return [rval].pack("b*") - elsif block_size == 8 - return rval.join else - raise "block sizes > 8 not yet supported" + return blocks.join end end @@ -165,14 +173,25 @@ return P.size end - def get_aux_blocks(nr_of_data_blocks) - (0.55 * Q * E * nr_of_data_blocks).ceil + def nr_of_aux_blocks + (0.55 * Q * E * nr_of_blocks).ceil end - def get_block_size(string_size) - return 1 + def block_size + unless defined?(@block_size) + if size < 256 + @block_size = 1 + else + @block_size = size / 128 + end + end + return @block_size end + def nr_of_blocks + @nr_of_blocks ||= ((size * 8) / block_size.to_f).ceil + end + def xor(s1, s2) rval = "" s1.split(//).each_with_index do |b, i| @@ -188,7 +207,7 @@ def do_decode(context) found_new_block = false @known_chunks.each do |chunk_data| - found_new_block = decode_chunk(chunk_data, context) || found_new_block + found_new_block = decode_chunk(chunk_data) || found_new_block end found_new_block = aux_decode || found_new_block return found_new_block @@ -197,26 +216,38 @@ def aux_decode got_new_block = false - @data_blocks.upto(@blocks.size - 1) do |i| + nr_of_blocks.upto(nr_of_blocks - 1) do |i| + + print "looking at aux block [#{i}]:" if $DEBUG + aux_block = @blocks[i] if aux_block - source_blocks = @aux_hash[i - @data_blocks] + source_blocks = @aux_hash[i - nr_of_blocks] if source_blocks.size == 1 block_nr = source_blocks.first + + print " [#{block_nr}]" if $DEBUG + if @blocks[block_nr].nil? @blocks[block_nr] = aux_block got_new_block = true + print "! => [#{block_nr}]=#{aux_block.inspect}" if $DEBUG + else + print " => #{aux_block.inspect}" if $DEBUG end else missing_blocks = source_blocks.size missing_block = nil xor_sum = aux_block source_blocks.each do |block| + print " [#{block}]" if $DEBUG source_block = @blocks[block] if source_block missing_blocks -= 1 xor_sum = xor(xor_sum, source_block) + print "!" if $DEBUG else + print "?" if $DEBUG missing_block = block end end @@ -224,51 +255,53 @@ if missing_blocks == 1 @blocks[missing_block] = xor_sum got_new_block = true + print " => [#{missing_block}]=#{xor_sum.inspect}" if $DEBUG end end end + puts if $DEBUG end return got_new_block end - def decode_chunk(chunk_data, context) + def decode_chunk(chunk_data) got_new_block = false - context.seed = chunk_data[:seed] + chunk_data[:context].seed = chunk_data[:seed] chunk_data[:blocks].each_with_index do |block, i| - print "looking at check block [#{i}](#{block.inspect}):" + print "looking at check block [#{i}](#{block.inspect}):" if $DEBUG - degree = get_degree(context) + degree = get_degree(chunk_data[:context]) if degree == 1 - block_nr = context.rand(@blocks.size) + block_nr = chunk_data[:context].rand(nr_of_blocks) - print " [#{block_nr}]" + print " [#{block_nr}]" if $DEBUG if @blocks[block_nr].nil? @blocks[block_nr] = block got_new_block = true - print "! => #{block.inspect}" + print "! => [#{block_nr}]=#{block.inspect}" if $DEBUG else - print " => #{block.inspect}" + print " => #{block.inspect}" if $DEBUG end else missing_blocks = degree missing_block_nr = nil xor_sum = block degree.downto(1) do - block_nr = context.rand(@blocks.size) + block_nr = chunk_data[:context].rand(nr_of_blocks) - print " [#{block_nr}]" + print " [#{block_nr}]" if $DEBUG if @blocks[block_nr] - print "!" + print "!" if $DEBUG xor_sum = xor(xor_sum, @blocks[block_nr]) missing_blocks -= 1 else - print "?" + print "?" if $DEBUG missing_block_nr = block_nr end @@ -277,19 +310,19 @@ if missing_blocks == 1 @blocks[missing_block_nr] = xor_sum got_new_block = true - print " => [#{missing_block_nr}]=#{xor_sum.inspect}" + print " => [#{missing_block_nr}]=#{xor_sum.inspect}" if $DEBUG end end - puts + puts if $DEBUG end return got_new_block end def generate_aux_hash - rval = Array.new(get_aux_blocks(@blocks.size)) + rval = Array.new(nr_of_aux_blocks) - context = Context.new(@blocks.size) + context = Context.new(nr_of_blocks) @blocks.each_with_index do |b, i| 1.upto(Q) do @@ -302,12 +335,11 @@ return rval end - def ensure_decode_format(requested_size, block_size) - unless @blocks + def ensure_decode_format(requested_size) + unless defined?(@blocks) self.concat("\000" * requested_size) - @blocks = Array.new(expand(self, block_size).size) - @data_blocks = @blocks.size - @blocks += Array.new(get_aux_blocks(@blocks.size)) + @blocks = Array.new(nr_of_blocks) + @blocks += Array.new(nr_of_aux_blocks) @aux_hash = generate_aux_hash @known_chunks ||= [] end @@ -329,27 +361,27 @@ def generate_check_block(context, n) degree = get_degree(context) - print "generating check block [#{n}]:" - block_nr = context.rand(@blocks.size) + print "generating check block [#{n}]:" if $DEBUG + block_nr = context.rand(nr_of_blocks) rval = @blocks[block_nr] - print " [#{block_nr}](#{@blocks[block_nr].inspect}), " + print " [#{block_nr}](#{@blocks[block_nr].inspect}), " if $DEBUG 2.upto(degree) do - block_nr = context.rand(@blocks.size) + block_nr = context.rand(nr_of_blocks) rval = xor(rval, @blocks[block_nr]) - print " [#{block_nr}](#{@blocks[block_nr].inspect}), " + print " [#{block_nr}](#{@blocks[block_nr].inspect}), " if $DEBUG end - puts " => #{rval.inspect}" + puts " => #{rval.inspect}" if $DEBUG return rval end def generate_aux_blocks - rval = Array.new(get_aux_blocks(@blocks.size)) + rval = Array.new(nr_of_aux_blocks) - context = Context.new(@blocks.size) + context = Context.new(nr_of_blocks) @blocks.each_with_index do |b, i| - print "generating aux blocks for [#{i}](#{b.inspect}):" + print "generating aux blocks for [#{i}](#{b.inspect}):" if $DEBUG 1.upto(Q) do aux_block_nr = context.rand(rval.size) if rval[aux_block_nr].nil? @@ -357,17 +389,17 @@ else rval[aux_block_nr] = xor(rval[aux_block_nr], b) end - print " #{aux_block_nr} => #{rval[aux_block_nr].inspect}, " + print " #{aux_block_nr} => #{rval[aux_block_nr].inspect}, " if $DEBUG end - puts + puts if $DEBUG end return rval end - def ensure_encode_format(block_size) - unless @blocks - @blocks = expand(self, block_size) + def ensure_encode_format + unless defined?(@blocks) + @blocks = expand(self) @blocks += generate_aux_blocks end end Modified: trunk/oneliner/tests/superstring_benchmark.rb =================================================================== --- trunk/oneliner/tests/superstring_benchmark.rb 2007-01-17 17:36:34 UTC (rev 168) +++ trunk/oneliner/tests/superstring_benchmark.rb 2007-01-18 16:11:44 UTC (rev 169) @@ -4,11 +4,9 @@ class SuperStringTest < Test::Unit::TestCase def test_decoding - puts "required for 512 blocks: #{required(100, 512)}" - puts "required for 1024 blocks: #{required(100, 1024)}" - puts "required for 2048 blocks: #{required(100, 2048)}" - puts "required for 4096 blocks: #{required(100, 4096)}" - puts "required for 8096 blocks: #{required(100, 8096)}" + puts "required for 512 blocks: #{required(10, 64)}" + puts "required for 1024 blocks: #{required(10, 128)}" + puts "required for 2040 blocks: #{required(10, 128 + 127)}" end private @@ -24,9 +22,12 @@ end def measure_required(dest, source) - dest.oneline_decode!(source.oneline_encode!(source.size)) - nil while (!dest.oneline_decode!(source.oneline_encode!((source.size.to_f * 0.1).to_i + 8))) - return dest.instance_eval do @_used_blocks end.to_f / source.size.to_f + dest.decode!(source.encode(source.size)) + while (!dest.decode!(source.encode((source.size.to_f * 0.05).ceil + 8))) + print "." + STDOUT.flush + end + return dest.instance_eval do used_blocks end.to_f / source.instance_eval do nr_of_blocks end.to_f end end Modified: trunk/oneliner/tests/superstring_test.rb =================================================================== --- trunk/oneliner/tests/superstring_test.rb 2007-01-17 17:36:34 UTC (rev 168) +++ trunk/oneliner/tests/superstring_test.rb 2007-01-18 16:11:44 UTC (rev 169) @@ -3,38 +3,20 @@ class SuperStringTest < Test::Unit::TestCase - def test_randomness - s = Oneliner::SuperString.new - c = s._get_aes_context - 1000.times do - r = s._macro_rand(c) - assert(r >= 0) - assert(r < 1) - r2 = s._macro_random(c, 13) - assert(r2 >= 0) - assert(r2 < 13) + def test_decoding + 1.upto(5) do |i| + print "." + STDOUT.flush + size_test(5 ** i) end - 10.times do - seed = rand(1 << 31) - values = [] - s._aes_seed_context(c, seed) - 100.times do - values << s._aes_random(c) - end - s._aes_seed_context(c, seed) - 100.times do |n| - assert_equal(values[n], s._aes_random(c)) - end - end end - def test_decoding - 10.times do - s = Oneliner::SuperString.new - s2 = Oneliner::SuperString.new(" " * 1024) - assert(s.oneline_decode!(s2.oneline_encode!(2048))) - assert_equal(s2, s) - end + private + + def size_test(size) + s = Oneliner::SuperString.new(" " * size) + s2 = Oneliner::SuperString.new + assert(s, s2.decode!(s.encode((s.size * (1.2)).ceil + 8))) end end From nobody at rubyforge.org Thu Jan 18 13:47:33 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Jan 2007 13:47:33 -0500 (EST) Subject: [Archipelago-submits] [170] trunk/oneliner: heavily optimized Message-ID: <20070118184733.F29E752426DB@rubyforge.org> Revision: 170 Author: zond Date: 2007-01-18 13:47:33 -0500 (Thu, 18 Jan 2007) Log Message: ----------- heavily optimized Modified Paths: -------------- trunk/oneliner/ext/superstring_ext.c trunk/oneliner/lib/oneliner/superstring.rb trunk/oneliner/lib/oneliner.rb Modified: trunk/oneliner/ext/superstring_ext.c =================================================================== --- trunk/oneliner/ext/superstring_ext.c 2007-01-18 16:11:44 UTC (rev 169) +++ trunk/oneliner/ext/superstring_ext.c 2007-01-18 18:47:33 UTC (rev 170) @@ -15,15 +15,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// DEPRECATION NOTICE: Note that this file is not used AT ALL at this time. -// It is only a rest from the last version of the code, and acts as a placeholder -// for the next round of optimization. -// - #include "ruby.h" #include -#include #include #include @@ -36,508 +29,129 @@ // Encrypt the buffer of ctx and set its counter to 0 // static void -aes_randomize_context(char *ctx) +aes_randomize_context(VALUE self) { AES_KEY key; - int tmp; AES_set_encrypt_key((unsigned char *) "0123456789012345", 128, &key); - ( (int *) ctx )[1]++; - for (tmp = 2; tmp < 6; tmp++) - ( (int *) ctx )[tmp] = ( (int *) ctx )[1]; - - AES_encrypt((unsigned char *) ctx + 8, (unsigned char *) ctx + 8, &key); - ( (int *) ctx )[0] = 0; + rb_str_modify(self); + AES_encrypt((unsigned char *) RSTRING(self)->ptr + 4, + (unsigned char *) RSTRING(self)->ptr + 4, + &key); + ( (int *) RSTRING(self)->ptr )[0] = 1; } // -// Get the int at the counter of ctx in the buffer of ctx. +// Fill the buffer of context with seed and randomize it. // -static int -aes_random(char *ctx) -{ - int *int_ctx = (int *) ctx; - if (int_ctx[0] < 4) { - int return_value = int_ctx[int_ctx[0] + 2]; - int_ctx[0]++; - return return_value; - } else { - aes_randomize_context(ctx); - return aes_random(ctx); - } -} - -// -// Fill the buffer of ctx with seed and randomize it. -// -static void -aes_seed_context(char *ctx, int seed) -{ - int tmp; - - ( (int *) ctx )[1] = seed; - - aes_randomize_context(ctx); -} - -// -// Return a ruby String suitable to use as a randomness context. -// static VALUE -get_aes_context() +aes_seed_context(VALUE self, VALUE seed) { - return rb_str_new(0, 16 + 4 + 16); -} - -// -// Use macros for the random functions so that they are easy to swap. -// -#define SEED(ctx, s) aes_seed_context(ctx, s) -#define RAND(ctx) (((double) ((unsigned int) aes_random(ctx)))/((double)UINT_MAX)) -#define RANDOM(ctx, n) (( (unsigned int) aes_random(ctx)) % (n)) -#define N_DATA_BLOCKS(self, block_size) (RSTRING(self)->len / block_size) -#define N_AUX_BLOCKS(aux_blocks, block_size) (RSTRING(aux_blocks)->len / block_size) -#define N_BLOCKS(self, aux_blocks, block_size) ((RSTRING(self)->len + RSTRING(aux_blocks)->len) / block_size) - - -// -// Make dest into source1 ^ source2. -// -static void -xor_string(char *dest, char *source1, char *source2, int len) -{ int tmp; - for (tmp = 0; tmp < (len / 4); tmp++) { - ( (int *) dest )[tmp] = ( (int *) source1 )[tmp] ^ ( (int *) source2 )[tmp]; - } - for (tmp = 0; tmp < (len % 4); tmp++) { - dest[len - tmp - 1] = source1[len - tmp - 1] ^ source2[len - tmp - 1]; - } -} -// -// Get a random degree for a check block. -// -static int -get_degree(int size, VALUE rnd_ctx) -{ - int rval = 1; - double d = RAND(RSTRING(rnd_ctx)->ptr) - P[rval]; - while (d > 0.0) { - rval ++; - d = d - P[rval]; - } - if (rval > size) - return size; - else - return rval; -} + if (RSTRING(self)->len < 17) + rb_str_concat(self, rb_str_new(0, 17)); -// -// Return whether the block_number is known according to the decode_status. -// -static char -get_is_known(VALUE decode_status, int block_number) -{ - int byte_in_status = block_number / 8; - char bit_in_byte = 1 << (block_number % 8); - return ((RSTRING(decode_status)->ptr[byte_in_status]) & bit_in_byte) == bit_in_byte; -} + rb_str_modify(self); + for (tmp = 1; tmp < 5; tmp++) + ( (int *) RSTRING(self)->ptr )[tmp] = NUM2INT(seed); -// -// Set that the block_number is known according to the decode_status. -// -static void -set_is_known(VALUE decode_status, int block_number) -{ - int byte_in_status = block_number / 8; - char bit_in_byte = 1 << (block_number % 8); - rb_str_modify(decode_status); - RSTRING(decode_status)->ptr[byte_in_status] = RSTRING(decode_status)->ptr[byte_in_status] | bit_in_byte; -} + aes_randomize_context(self); -// -// Set the data or aux block with index to be value, and set it as known. -// -static void -set_value(VALUE aux_blocks, int index, char *value, VALUE self, VALUE decode_status, int block_size) -{ - if ((index * block_size) < RSTRING(self)->len) { - rb_str_modify(self); - memcpy(RSTRING(self)->ptr + (index * block_size), value, block_size); - set_is_known(decode_status, index); - } else { - rb_str_modify(aux_blocks); - memcpy(RSTRING(aux_blocks)->ptr + ((index - N_DATA_BLOCKS(self, block_size)) * block_size), value, block_size); - set_is_known(decode_status, index); - } + return Qnil; } // -// Get the value at index from data or aux blocks. +// Get the int at the counter of context in the buffer of context. // -static char* -get_value(VALUE aux_blocks, int index, VALUE self, int block_size) +static VALUE +aes_random(int argc, VALUE *argv, VALUE self) { - if ((index * block_size) < RSTRING(self)->len) { - return RSTRING(self)->ptr + (index * block_size); - } else { - return RSTRING(aux_blocks)->ptr + ((index - N_DATA_BLOCKS(self, block_size)) * block_size); - } -} - -// -// Get a random check block of block_size from our data and aux blocks and append it to chunk at index. -// -static void -append_check_block(VALUE self, int seed, int index, VALUE aux_blocks, VALUE rnd_ctx, char *chunk, int block_size) -{ - int degree; - int empty_block = 1; - int tmp; - - - // Find [degree] blocks. - for (degree = get_degree(RSTRING(self)->len, rnd_ctx); degree > 0; degree--) { - int block_number = RANDOM(RSTRING(rnd_ctx)->ptr, N_BLOCKS(self, aux_blocks, block_size)); - char *found_block = get_value(aux_blocks, block_number, self, block_size); - - // Create the block by xoring. - if (empty_block) { - memcpy(chunk + (index * block_size), found_block, block_size); - empty_block = 0; + int *int_context = (int *) RSTRING(self)->ptr; + if (int_context[0] < 5) { + int return_value = int_context[int_context[0]]; + int_context[0]++; + if (argc == 0) { + return rb_float_new( ( (double) ( (unsigned int) return_value ) ) / ( (double) UINT_MAX )); } else { - xor_string(chunk + index, chunk + index, found_block, block_size); + VALUE max = argv[0]; + return INT2NUM(( (unsigned int) return_value ) % NUM2INT(max)); } + } else { + aes_randomize_context(self); + return aes_random(argc, argv, self); } } // -// Get a random context, mainly for testing purposes. +// Initialize a context. // -static VALUE -_get_aes_context(VALUE self) +static VALUE +context_initialize(int argc, VALUE *argv, VALUE self) { - return (get_aes_context()); + rb_str_concat(self, rb_str_new(0, 17)); } // -// Seed a context, mainly for testing purposes. +// Make dest into source1 ^ source2. // -static VALUE -_aes_seed_context(VALUE self, VALUE _ctx, VALUE _s) +static VALUE +string_xor(VALUE self, VALUE subject) { - char * ctx = STR2CSTR(_ctx); - int s = NUM2INT(_s); - - aes_seed_context(ctx, s); - return Qnil; -} - -// -// Get a random int from the context, mainly for testing purposes. -// -static VALUE -_aes_random(VALUE self, VALUE _ctx) -{ - char * ctx = STR2CSTR(_ctx); - - return INT2NUM(aes_random(ctx)); -} - -// -// Get what the RAND macro produces, mainly for testing purposes. -// -static VALUE -_macro_rand(VALUE self, VALUE _ctx) -{ - char * ctx = STR2CSTR(_ctx); - - return rb_float_new(RAND(ctx)); -} - -// -// Get what the RANDOM macro produces, mainly for testing purposes. -// -static VALUE -_macro_random(VALUE self, VALUE _ctx, VALUE _lim) -{ - char * ctx = STR2CSTR(_ctx); - int lim = NUM2INT(_lim); - - return INT2NUM(RANDOM(ctx, lim)); -} - -// -// Decode the given _chunk using the provided _decode_status and _aux_blocks. -// -// Returns whether the decoding produced any new blocks. -// -static VALUE -_decode_chunk(VALUE self, VALUE _chunk, VALUE _decode_status, VALUE _aux_blocks, VALUE block_size_value) -{ - VALUE chunk = (_chunk); - VALUE decode_status = (_decode_status); - VALUE aux_blocks = (_aux_blocks); - int seed = ( (int *) RSTRING(chunk)->ptr )[0]; - int size = ( (int *) RSTRING(chunk)->ptr )[1]; int tmp; - char got_new_block = 0; - VALUE rnd_ctx = get_aes_context(); - int block_size = NUM2INT(block_size_value); - - SEED(RSTRING(rnd_ctx)->ptr, seed); - for (tmp = 8; tmp < RSTRING(chunk)->len; tmp = tmp + block_size) { - int degree; - - degree = get_degree(size, rnd_ctx); - if (degree == 1) { - int block_nr; - block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, (size + RSTRING(aux_blocks)->len) / block_size); - if (!get_is_known(decode_status, block_nr)) { - set_value(aux_blocks, block_nr, RSTRING(chunk)->ptr + tmp, self, decode_status, block_size); - got_new_block = 1; - } - } else { - int missing_blocks; - int missing_block = 0; - int tmp2; - char xor_sum[block_size]; + int len = RSTRING(self)->len; + VALUE return_value = rb_str_new(0, len); - memcpy(xor_sum, RSTRING(chunk)->ptr + tmp, block_size); + Check_Type(subject, T_STRING); - for (missing_blocks = tmp2 = degree; tmp2 > 0; tmp2--) { - int block_nr; - block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, (size + RSTRING(aux_blocks)->len) / block_size); - if (get_is_known(decode_status, block_nr)) { - int tmp3; - char *this_value = get_value(aux_blocks, block_nr, self, block_size); + if (len != RSTRING(subject)->len) + rb_raise(rb_eTypeError, "argument to xor must be of same length as receiver"); - missing_blocks--; - xor_string(xor_sum, xor_sum, this_value, block_size); - } else { - missing_block = block_nr; - } - } - if (missing_blocks == 1) { - set_value(aux_blocks, missing_block, xor_sum, self, decode_status, block_size); - got_new_block = 1; - } - } + rb_str_modify(return_value); + for (tmp = 0; tmp < len; tmp++) { + ( (int *) RSTRING(return_value)->ptr )[tmp] = ( (int *) RSTRING(self)->ptr )[tmp] ^ ( (int *) RSTRING(subject)->ptr )[tmp]; } - - return (got_new_block ? Qtrue : Qfalse); -} - -// -// Create the @_aux_blocks instance attribute with _size blocks and the given _q value. -// -static VALUE -_fill_aux_blocks(VALUE self, VALUE _size, VALUE _q, VALUE block_size_value) -{ - int size = NUM2INT(_size); - int q = NUM2INT(_q); - int block_size = NUM2INT(block_size_value); - - char aux_blocks[size * block_size]; - char initialized_aux_blocks[size]; - int tmp, tmp2, tmp3; - VALUE rnd_ctx = get_aes_context(); - - for (tmp = 0; tmp < size; tmp++) - initialized_aux_blocks[tmp] = 0; - - SEED(RSTRING(rnd_ctx)->ptr, RSTRING(self)->len); - for (tmp = 0; tmp < RSTRING(self)->len; tmp = tmp + block_size) { - for (tmp2 = 0; tmp2 < q; tmp2++) { - int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); - if (initialized_aux_blocks[aux_block_nr]) { - xor_string(aux_blocks + (aux_block_nr * block_size), aux_blocks + (aux_block_nr * block_size), RSTRING(self)->ptr + tmp, block_size); - } else { - memcpy(aux_blocks + (aux_block_nr * block_size), RSTRING(self)->ptr + tmp, block_size); - initialized_aux_blocks[aux_block_nr] = 1; - } - } + for (tmp = 0; tmp < (len % 4); tmp++) { + RSTRING(return_value)->ptr[len - tmp - 1] = RSTRING(self)->ptr[len - tmp - 1] ^ RSTRING(subject)->ptr[len - tmp - 1]; } - rb_ivar_set(self, rb_intern("@_aux_blocks"), rb_str_new(aux_blocks, size * block_size)); - return Qnil; -} -// -// Return a chunk of check blocks that is _chunk_size big. -// -static VALUE -_get_chunk(VALUE self, VALUE _chunk_size, VALUE _aux_blocks, VALUE block_size_value) -{ - int chunk_size = NUM2INT(_chunk_size); - VALUE aux_blocks = (_aux_blocks); - int block_size = NUM2INT(block_size_value); - - unsigned int tmp; - int seed; - struct timeval tmp_timeval; - char chunk[chunk_size]; - VALUE rnd_ctx = get_aes_context(); - gettimeofday(&tmp_timeval, NULL); - srandom(tmp_timeval.tv_usec); - seed = random(); - - ( (int *) chunk) [0] = seed; - ( (int *) chunk) [1] = RSTRING(self)->len; - SEED(RSTRING(rnd_ctx)->ptr, seed); - for (tmp = 8; tmp < chunk_size; tmp = tmp + block_size) { - append_check_block(self, seed, tmp, aux_blocks, rnd_ctx, chunk, block_size); - } - - return (rb_str_new(chunk, chunk_size)); + return return_value; } // -// Create the instance attribute @_aux_hash containing the structure of our aux blocks. +// Get a random degree // -static VALUE -_fill_aux_hash(VALUE self, VALUE _q, VALUE _size, VALUE block_size_value) +static VALUE +superstring_get_degree(VALUE self, VALUE f_value) { - int q = NUM2INT(_q); - int size = NUM2INT(_size); - int block_size = NUM2INT(block_size_value); - - int tmp, tmp2; - VALUE aux_ary = rb_ary_new(); - VALUE set_func = rb_intern("[]="); - VALUE get_func = rb_intern("[]"); - VALUE push_func = rb_intern("<<"); - VALUE size_func = rb_intern("size"); - VALUE rnd_ctx = get_aes_context(); - - SEED(RSTRING(rnd_ctx)->ptr, RSTRING(self)->len); - for (tmp = 0; tmp < RSTRING(self)->len; tmp++) { - for (tmp2 = 0; tmp2 < q; tmp2++) { - int aux_block_nr = RANDOM(RSTRING(rnd_ctx)->ptr, size); - VALUE data_blocks_for_this_aux_block; - if ((data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2NUM(aux_block_nr))) == Qnil) - rb_funcall(aux_ary, set_func, 2, INT2NUM(aux_block_nr), (data_blocks_for_this_aux_block = rb_ary_new())); - rb_funcall(data_blocks_for_this_aux_block, push_func, 1, INT2NUM(tmp)); - } + double f = RFLOAT(f_value)->value; + int tmp = 0; + while (f > 0) { + tmp++; + f = f - P[tmp]; } - for (tmp = 0; tmp < size; tmp++) { - VALUE data_blocks_for_this_aux_block = rb_funcall(aux_ary, get_func, 1, INT2NUM(tmp)); - int number_of_data_blocks = NUM2INT(rb_funcall(data_blocks_for_this_aux_block, size_func, 0)); - VALUE data_block_string = rb_str_new(0, number_of_data_blocks * 4); - for (tmp2 = 0; tmp2 < number_of_data_blocks; tmp2++) { - rb_str_modify(data_block_string); - ( (int *) RSTRING(data_block_string)->ptr )[tmp2] = (int) NUM2INT(rb_funcall(data_blocks_for_this_aux_block, - get_func, - 1, - INT2NUM(tmp2))); - } - rb_funcall(aux_ary, set_func, 2, INT2NUM(tmp), data_block_string); - } - rb_ivar_set(self, rb_intern("@_aux_hash"), aux_ary); - return Qnil; + return INT2NUM(tmp); } -// -// Returns whether the decoding process is finished. -// -static VALUE -_oneline_done(VALUE self, VALUE decode_status, VALUE block_size_value) -{ - int block_size = NUM2INT(block_size_value); - int tmp; - int number_of_ints = RSTRING(self)->len / 32; - int number_of_chars = RSTRING(self)->len / 8; - - if (decode_status == Qnil) - return (Qfalse); - for (tmp = 0; tmp < number_of_ints; tmp++) - if (( (unsigned int *) RSTRING(decode_status)->ptr )[tmp] != UINT_MAX) - return Qfalse; - for (tmp = (number_of_ints * 4); tmp < number_of_chars; tmp++) - if (( (unsigned char) RSTRING(decode_status)->ptr[tmp] ) != UCHAR_MAX) - return (Qfalse); - for (tmp = 0; tmp < ((RSTRING(self)->len / block_size) % 8); tmp++) - if (! (( (unsigned char) RSTRING(decode_status)->ptr[RSTRING(decode_status)->len - 1] ) & (1 << tmp))) - return (Qfalse); - return (Qtrue); -} - -// -// Decode our aux blocks, and return if it produced any new blocks. -// -static VALUE -_aux_decode(VALUE self, VALUE _decode_status, VALUE _aux_blocks, VALUE _aux_hash, VALUE block_size_value) -{ - VALUE decode_status = (_decode_status); - VALUE aux_blocks = (_aux_blocks); - VALUE aux_hash = (_aux_hash); - int block_size = NUM2INT(block_size_value); - - int tmp; - char got_new_block = 0; - VALUE get_func = rb_intern("[]"); - for (tmp = 0; tmp < RSTRING(aux_blocks)->len; tmp = tmp + block_size) { - if (get_is_known(decode_status, (RSTRING(self)->len + tmp) / block_size)) { - VALUE data_block_string = rb_funcall(aux_hash, get_func, 1, INT2NUM(tmp)); - if (RSTRING(data_block_string)->len == 4) { - int block_nr = ( (int *) RSTRING(data_block_string)->ptr )[0]; - if (!get_is_known(decode_status, block_nr)) { - set_value(aux_blocks, block_nr, RSTRING(aux_blocks)->ptr + tmp, self, decode_status, block_size); - got_new_block = 1; - } else { - } - } else { - int missing_blocks; - int missing_block = 0; - int tmp2; - char xor_sum[block_size]; - - memcpy(xor_sum, RSTRING(aux_blocks)->ptr + tmp, block_size); - - for (missing_blocks = (tmp2 = ((RSTRING(data_block_string)->len / 4) - 1)) + 1; tmp2 > -1; tmp2--) { - int block_nr = ( (int *) RSTRING(data_block_string)->ptr )[tmp2]; - if (get_is_known(decode_status, block_nr)) { - int tmp3; - char *this_value = get_value(aux_blocks, block_nr, self, block_size); - - missing_blocks--; - xor_string(xor_sum, xor_sum, this_value, block_size); - } else { - missing_block = block_nr; - } - } - if (missing_blocks == 1) { - set_value(aux_blocks, missing_block, xor_sum, self, decode_status, block_size); - got_new_block = 1; - } - } - } - } - - return (got_new_block ? Qtrue : Qfalse); -} - - #ifdef __cplusplus extern "C" { #endif void Init_superstring_ext() { - VALUE c = rb_cObject; - c = rb_const_get_at(c,rb_intern("Oneliner")); - c = rb_const_get_at(c,rb_intern("SuperString")); - rb_define_method(c, "_aes_random", (VALUE(*)(ANYARGS))_aes_random, 1); - rb_define_method(c, "_aes_seed_context", (VALUE(*)(ANYARGS))_aes_seed_context, 2); - rb_define_method(c, "_aux_decode", (VALUE(*)(ANYARGS))_aux_decode, 4); - rb_define_method(c, "_decode_chunk", (VALUE(*)(ANYARGS))_decode_chunk, 4); - rb_define_method(c, "_fill_aux_blocks", (VALUE(*)(ANYARGS))_fill_aux_blocks, 3); - rb_define_method(c, "_fill_aux_hash", (VALUE(*)(ANYARGS))_fill_aux_hash, 3); - rb_define_method(c, "_get_aes_context", (VALUE(*)(ANYARGS))_get_aes_context, 0); - rb_define_method(c, "_get_chunk", (VALUE(*)(ANYARGS))_get_chunk, 3); - rb_define_method(c, "_macro_rand", (VALUE(*)(ANYARGS))_macro_rand, 1); - rb_define_method(c, "_macro_random", (VALUE(*)(ANYARGS))_macro_random, 2); - rb_define_method(c, "_oneline_done", (VALUE(*)(ANYARGS))_oneline_done, 2); + VALUE string = rb_const_get(rb_cObject, rb_intern("String")); + VALUE superstring = rb_define_class_under(rb_define_module("Oneliner"), + "SuperString", + string); + VALUE context = rb_define_class_under(superstring, + "Context", + string); + rb_define_const(context, "INT_MAX", INT2NUM(INT_MAX)); + rb_define_method(context, "initialize", context_initialize, -1); + rb_define_method(context, "random", aes_random, -1); + rb_define_method(context, "seed", aes_seed_context, 1); + rb_define_method(string, "^", string_xor, 1); + rb_define_method(superstring, "get_degree", superstring_get_degree, 1); } #ifdef __cplusplus } Modified: trunk/oneliner/lib/oneliner/superstring.rb =================================================================== --- trunk/oneliner/lib/oneliner/superstring.rb 2007-01-18 16:11:44 UTC (rev 169) +++ trunk/oneliner/lib/oneliner/superstring.rb 2007-01-18 18:47:33 UTC (rev 170) @@ -25,7 +25,6 @@ # class SuperString < String - MAXLONG = "\377\377\377\377".unpack("L*")[0] E = 0.01 Q = 3 F = (Math.log((E ** 2) / 4) / Math.log(1 - (E / 2))).abs.to_i @@ -34,49 +33,17 @@ P << (((1 - P[1]) * F) / ((F - 1) * i * (i - 1))) end - class Context - def initialize(s = nil) - unless s - Kernel.srand - s = Kernel.rand(MAXLONG) - end - self.seed = s - end - def seed=(s) - puts "seeding with #{s}" if $DEBUG - @seed = s - randomize(s) - end - def seed - @seed - end - def rand(max = false) - randomize(@source) if @index << 2 >= @source.size - number = @source.unpack("@#{@index * 4}L").first - @index += 1 - if max - return number % max - else - return number.to_f / MAXLONG.to_f - end - end - private - def randomize(s) - @index = 0 - @source = Digest::SHA512.hexdigest("#{s}").gsub(/(.{2,2})/, ",\\1").split(/,/)[1..-1].collect do |byte| - byte.hex - end.pack("C*") - end - end - def encode(requested_size) raise "requested size is too small for metadata (8 bytes)" unless requested_size > 7 ensure_encode_format + srand + seed = rand(Context::INT_MAX) context = Context.new + context.seed(seed) rval = [self.size].pack("L*") - rval << [context.seed].pack("L*") + rval << [seed].pack("L*") blocks = [] while (blocks.size * block_size) / 8 < (requested_size - 8) @@ -164,17 +131,8 @@ end end - def get_degree(context) - f = context.rand - P.each_with_index do |p, i| - f -= p - return i if f < 0 - end - return P.size - end - def nr_of_aux_blocks - (0.55 * Q * E * nr_of_blocks).ceil + @nr_of_aux_blocks ||= (0.55 * Q * E * nr_of_blocks).ceil end def block_size @@ -192,14 +150,6 @@ @nr_of_blocks ||= ((size * 8) / block_size.to_f).ceil end - def xor(s1, s2) - rval = "" - s1.split(//).each_with_index do |b, i| - rval << (s1[i] ^ s2[i]).chr - end - return rval - end - # # Decoding stuff # @@ -244,7 +194,7 @@ source_block = @blocks[block] if source_block missing_blocks -= 1 - xor_sum = xor(xor_sum, source_block) + xor_sum = xor_sum ^ source_block print "!" if $DEBUG else print "?" if $DEBUG @@ -268,15 +218,15 @@ def decode_chunk(chunk_data) got_new_block = false - chunk_data[:context].seed = chunk_data[:seed] + chunk_data[:context].seed(chunk_data[:seed]) chunk_data[:blocks].each_with_index do |block, i| print "look