From: Martin Bosslet Date: 2011-01-24T09:42:09+09:00 Subject: [ruby-core:34813] [Ruby 1.9-Feature#4309][Open] [ext/openssl] ASN1 performance enhancement --mimepart_4d3ccade13674_1386598b1b02572 Content-Type: text/plain Content-Transfer-Encoding: Quoted-printable Content-Disposition: inline Feature #4309: [ext/openssl] ASN1 performance enhancement http://redmine.ruby-lang.org/issues/show/4309 Author: Martin Bosslet Status: Open, Priority: Normal Category: ext, Target version: 1.9.3 Hi all, recently I noticed that the method = static int ossl_asn1_default_tag(VALUE obj) (in ossl_asn1.c) iterates through an internal array each time a default t= ag is to be looked up resulting in O(n) runtime performance. I thought this to be the ideal situation for using a hash an= d so I added one with OpenSSL::ASN1Data subclasses = acting as keys and the corresponding tags as values. I also did some prof= iling to see whether the constant lookup time made some impact. I first ran a test encoding and parsing a certificate a coup= le of times and that's what I got: Old code: 1.998611 seconds. 2.004065 seconds. 1.981882 seconds. 2.129491 seconds. 1.953846 seconds. 1.957313 seconds. 1.958523 seconds. 1.976004 seconds. 1.925835 seconds. 1.974381 seconds. New code: 1.886169 seconds. 1.871291 seconds. 1.829164 seconds. 1.927687 seconds. 1.879508 seconds. 1.848399 seconds. 1.942286 seconds. 1.908133 seconds. 1.839384 seconds. 1.861159 seconds. Not much, but I think the improvement is noticeable. Next I ran a "worst = case scenario" for the old code. I encoded and decoded a Sequence with 4 BMPString values, since BMPString= with tag 30 is at the end of = the internal array. Here the performance gain was roughly 15%: Old code worst case: 1.507455 seconds. 1.503871 seconds. 1.563551 seconds. 1.523261 seconds. 1.564125 seconds. 1.526295 seconds. 1.553073 seconds. 1.877483 seconds. 1.543568 seconds. 1.518273 seconds. New code worst case: 1.347785 seconds. 1.359214 seconds. 1.389248 seconds. 1.466773 seconds. 1.350079 seconds. 1.406290 seconds. 1.393683 seconds. 1.368601 seconds. 1.350600 seconds. 1.373738 seconds Please find attached the patch (including tests) that would add this impr= ovement to Ruby trunk. Best regards, Martin PS: I also changed the UNIVERSAL_TAG_NAME constant's name for OpenSSL::AS= N1::EndOfContent from "EOC" to "END_OF_CONTENT" because all other names are the uppercase versions of th= eir corresponding classes, this would have been the only exception to that rule. = Then I also exported two methods, default_tag and default_tag_of_class, f= or the ASN1 module. I needed = them for something I'm currently working on. These latter changes are ind= ependent of the performance improvement described above. ---------------------------------------- http://redmine.ruby-lang.org --mimepart_4d3ccade13674_1386598b1b02572 Content-Type: text/x-patch; name=class_tag_map.diff Content-Transfer-Encoding: Base64 Content-Disposition: attachment; filename=class_tag_map.diff ClByb3BlcnR5IGNoYW5nZXMgb246IHJ1YnkvZXh0L29wZW5zc2wKX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fXwpNb2RpZmllZDogc3ZuOmlnbm9yZQogICAtIEdO VW1ha2VmaWxlCk1ha2VmaWxlCmRlcApleHRjb25mLmgKbWttZi5sb2cKb3Bl bnNzbC5hCmNvbmZ0ZXN0LmRTWU0KCiAgICsgR05VbWFrZWZpbGUKTWFrZWZp bGUKZGVwCmV4dGNvbmYuaApta21mLmxvZwpvcGVuc3NsLmEKY29uZnRlc3Qu ZFNZTQpvcGVuc3NsLnNvCgoKSW5kZXg6IHJ1YnkvZXh0L29wZW5zc2wvb3Nz bF9hc24xLmMKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gcnVieS9leHQv b3BlbnNzbC9vc3NsX2FzbjEuYwkocmV2aXNpb24gMzA2NDApCisrKyBydWJ5 L2V4dC9vcGVuc3NsL29zc2xfYXNuMS5jCSh3b3JraW5nIGNvcHkpCkBAIC00 NTQsNyArNDU0LDcgQEAKIH0gb3NzbF9hc24xX2luZm9fdDsKIAogc3RhdGlj IG9zc2xfYXNuMV9pbmZvX3Qgb3NzbF9hc24xX2luZm9bXSA9IHsKLSAgICB7 ICJFT0MiLCAgICAgICAgICAgICAgICZjQVNOMUVuZE9mQ29udGVudCwgICAg fSwgIC8qICAwICovCisgICAgeyAiRU5EX09GX0NPTlRFTlQiLCAgICAmY0FT TjFFbmRPZkNvbnRlbnQsICAgIH0sICAvKiAgMCAqLwogICAgIHsgIkJPT0xF QU4iLCAgICAgICAgICAgJmNBU04xQm9vbGVhbiwgICAgICAgICB9LCAgLyog IDEgKi8KICAgICB7ICJJTlRFR0VSIiwgICAgICAgICAgICZjQVNOMUludGVn ZXIsICAgICAgICAgfSwgIC8qICAyICovCiAgICAgeyAiQklUX1NUUklORyIs ICAgICAgICAmY0FTTjFCaXRTdHJpbmcsICAgICAgIH0sICAvKiAgMyAqLwpA QCAtNDg3LDEwICs0ODcsMzQgQEAKICAgICB7ICJCTVBTVFJJTkciLCAgICAg ICAgICZjQVNOMUJNUFN0cmluZywgICAgICAgfSwgIC8qIDMwICovCiB9Owog CisKKwogaW50IG9zc2xfYXNuMV9pbmZvX3NpemUgPSAoc2l6ZW9mKG9zc2xf YXNuMV9pbmZvKS9zaXplb2Yob3NzbF9hc24xX2luZm9bMF0pKTsKIAorc3Rh dGljIFZBTFVFIGNsYXNzX3RhZ19tYXA7CisKIHN0YXRpYyBpbnQgb3NzbF9h c24xX2RlZmF1bHRfdGFnKFZBTFVFIG9iaik7CiAKK3N0YXRpYyBWQUxVRQor b3NzbF9hc24xX2RlZmF1bHRfdGFnX2NsYXNzKFZBTFVFIHNlbGYsIFZBTFVF IGtsYXNzKQoreworICAgIFZBTFVFIHRhZyA9IHJiX2hhc2hfbG9va3VwKGNs YXNzX3RhZ19tYXAsIGtsYXNzKTsKKyAgICBpZiAodGFnICE9IFFuaWwpIHsK KyAgICAgICAgcmV0dXJuIHRhZzsKKyAgICB9CisKKyAgICBvc3NsX3JhaXNl KGVBU04xRXJyb3IsICJ1bml2ZXJzYWwgdGFnIGZvciAlcyBub3QgZm91bmQi LAorCSAgICAgICByYl9jbGFzczJuYW1lKGtsYXNzKSk7CisKKyAgICByZXR1 cm4gUW5pbDsgLyogZHVtbXkgKi8KK30KKworc3RhdGljIFZBTFVFCitvc3Ns X2FzbjFfZGVmYXVsdF90YWdfcHVibGljKFZBTFVFIHNlbGYsIFZBTFVFIG9i aikKK3sKKyAgcmV0dXJuIElOVDJOVU0ob3NzbF9hc24xX2RlZmF1bHRfdGFn KG9iaikpOworfQorCiBBU04xX1RZUEUqCiBvc3NsX2FzbjFfZ2V0X2FzbjF0 eXBlKFZBTFVFIG9iaikKIHsKQEAgLTU3MCwxNCArNTk0LDE1IEBACiBzdGF0 aWMgaW50CiBvc3NsX2FzbjFfZGVmYXVsdF90YWcoVkFMVUUgb2JqKQogewot ICAgIGludCBpOworICAgIFZBTFVFIHRtcF9jbGFzcyA9IENMQVNTX09GKG9i aik7CisgICAgd2hpbGUgKHRtcF9jbGFzcykgeworICAgICAgICBWQUxVRSB0 YWcgPSByYl9oYXNoX2xvb2t1cChjbGFzc190YWdfbWFwLCB0bXBfY2xhc3Mp OworICAgICAgICBpZiAodGFnICE9IFFuaWwpIHsKKyAgICAgICAgICAgIHJl dHVybiBOVU0ySU5UKHRhZyk7CisgICAgICAgIH0KKyAgICAgICAgdG1wX2Ns YXNzID0gUkNMQVNTX1NVUEVSKHRtcF9jbGFzcyk7CisgICAgfQogCi0gICAg Zm9yKGkgPSAwOyBpIDwgb3NzbF9hc24xX2luZm9fc2l6ZTsgaSsrKXsKLQlp Zihvc3NsX2FzbjFfaW5mb1tpXS5rbGFzcyAmJgotCSAgIHJiX29ial9pc19r aW5kX29mKG9iaiwgKm9zc2xfYXNuMV9pbmZvW2ldLmtsYXNzKSl7Ci0JICAg IHJldHVybiBpOwotCX0KLSAgICB9CiAgICAgb3NzbF9yYWlzZShlQVNOMUVy cm9yLCAidW5pdmVyc2FsIHRhZyBmb3IgJXMgbm90IGZvdW5kIiwKIAkgICAg ICAgcmJfY2xhc3MybmFtZShDTEFTU19PRihvYmopKSk7CiAKQEAgLTg0MSw3 ICs4NjYsNyBAQAogICAgICAgICAgICAgb3NzbF9hc24xX3NldF9pbmZpbml0 ZV9sZW5ndGgoYXNuMWRhdGEsIFF0cnVlKTsKICAgICAgICAgZWxzZQogICAg ICAgICAgICAgb3NzbF9hc24xX3NldF9pbmZpbml0ZV9sZW5ndGgoYXNuMWRh dGEsIFFmYWxzZSk7Ci0gICAgICAgIAorCiAJcmJfYXJ5X3B1c2goYXJ5LCBh c24xZGF0YSk7CiAJbGVuZ3RoIC09IGxlbjsKICAgICAgICAgaWYob25jZSkg YnJlYWs7CkBAIC0xMTkwLDYgKzEyMTUsOCBAQAogICAgIHJiX2RlZmluZV9t b2R1bGVfZnVuY3Rpb24obUFTTjEsICJ0cmF2ZXJzZSIsIG9zc2xfYXNuMV90 cmF2ZXJzZSwgMSk7CiAgICAgcmJfZGVmaW5lX21vZHVsZV9mdW5jdGlvbiht QVNOMSwgImRlY29kZSIsIG9zc2xfYXNuMV9kZWNvZGUsIDEpOwogICAgIHJi X2RlZmluZV9tb2R1bGVfZnVuY3Rpb24obUFTTjEsICJkZWNvZGVfYWxsIiwg b3NzbF9hc24xX2RlY29kZV9hbGwsIDEpOworICAgIHJiX2RlZmluZV9tb2R1 bGVfZnVuY3Rpb24obUFTTjEsICJkZWZhdWx0X3RhZ19vZl9jbGFzcyIsIG9z c2xfYXNuMV9kZWZhdWx0X3RhZ19jbGFzcywgMSk7CisgICAgcmJfZGVmaW5l X21vZHVsZV9mdW5jdGlvbihtQVNOMSwgImRlZmF1bHRfdGFnIiwgb3NzbF9h c24xX2RlZmF1bHRfdGFnX3B1YmxpYywgMSk7CiAgICAgYXJ5ID0gcmJfYXJ5 X25ldygpOwogICAgIHJiX2RlZmluZV9jb25zdChtQVNOMSwgIlVOSVZFUlNB TF9UQUdfTkFNRSIsIGFyeSk7CiAgICAgZm9yKGkgPSAwOyBpIDwgb3NzbF9h c24xX2luZm9fc2l6ZTsgaSsrKXsKQEAgLTEyNjAsNCArMTI4NywzMSBAQAog ICAgIHJiX2F0dHIoY0FTTjFCaXRTdHJpbmcsIHJiX2ludGVybigidW51c2Vk X2JpdHMiKSwgMSwgMSwgMCk7CiAKICAgICByYl9kZWZpbmVfbWV0aG9kKGNB U04xRW5kT2ZDb250ZW50LCAiaW5pdGlhbGl6ZSIsIG9zc2xfYXNuMWVvY19p bml0aWFsaXplLCAwKTsKKworICAgIGNsYXNzX3RhZ19tYXAgPSByYl9oYXNo X25ldygpOworICAgIHJiX2hhc2hfYXNldChjbGFzc190YWdfbWFwLCBjQVNO MUVuZE9mQ29udGVudCwgSU5UMk5VTSgwKSk7CisgICAgcmJfaGFzaF9hc2V0 KGNsYXNzX3RhZ19tYXAsIGNBU04xQm9vbGVhbiwgSU5UMk5VTSgxKSk7Cisg ICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19tYXAsIGNBU04xSW50ZWdlciwg SU5UMk5VTSgyKSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19tYXAs IGNBU04xQml0U3RyaW5nLCBJTlQyTlVNKDMpKTsKKyAgICByYl9oYXNoX2Fz ZXQoY2xhc3NfdGFnX21hcCwgY0FTTjFPY3RldFN0cmluZywgSU5UMk5VTSg0 KSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19tYXAsIGNBU04xTnVs bCwgSU5UMk5VTSg1KSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19t YXAsIGNBU04xT2JqZWN0SWQsIElOVDJOVU0oNikpOworICAgIHJiX2hhc2hf YXNldChjbGFzc190YWdfbWFwLCBjQVNOMUVudW1lcmF0ZWQsIElOVDJOVU0o MTApKTsKKyAgICByYl9oYXNoX2FzZXQoY2xhc3NfdGFnX21hcCwgY0FTTjFV VEY4U3RyaW5nLCBJTlQyTlVNKDEyKSk7CisgICAgcmJfaGFzaF9hc2V0KGNs YXNzX3RhZ19tYXAsIGNBU04xU2VxdWVuY2UsIElOVDJOVU0oMTYpKTsKKyAg ICByYl9oYXNoX2FzZXQoY2xhc3NfdGFnX21hcCwgY0FTTjFTZXQsIElOVDJO VU0oMTcpKTsKKyAgICByYl9oYXNoX2FzZXQoY2xhc3NfdGFnX21hcCwgY0FT TjFOdW1lcmljU3RyaW5nLCBJTlQyTlVNKDE4KSk7CisgICAgcmJfaGFzaF9h c2V0KGNsYXNzX3RhZ19tYXAsIGNBU04xUHJpbnRhYmxlU3RyaW5nLCBJTlQy TlVNKDE5KSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19tYXAsIGNB U04xVDYxU3RyaW5nLCBJTlQyTlVNKDIwKSk7CisgICAgcmJfaGFzaF9hc2V0 KGNsYXNzX3RhZ19tYXAsIGNBU04xVmlkZW90ZXhTdHJpbmcsIElOVDJOVU0o MjEpKTsKKyAgICByYl9oYXNoX2FzZXQoY2xhc3NfdGFnX21hcCwgY0FTTjFJ QTVTdHJpbmcsIElOVDJOVU0oMjIpKTsKKyAgICByYl9oYXNoX2FzZXQoY2xh c3NfdGFnX21hcCwgY0FTTjFVVENUaW1lLCBJTlQyTlVNKDIzKSk7CisgICAg cmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19tYXAsIGNBU04xR2VuZXJhbGl6ZWRU aW1lLCBJTlQyTlVNKDI0KSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3Rh Z19tYXAsIGNBU04xR3JhcGhpY1N0cmluZywgSU5UMk5VTSgyNSkpOworICAg IHJiX2hhc2hfYXNldChjbGFzc190YWdfbWFwLCBjQVNOMUlTTzY0U3RyaW5n LCBJTlQyTlVNKDI2KSk7CisgICAgcmJfaGFzaF9hc2V0KGNsYXNzX3RhZ19t YXAsIGNBU04xR2VuZXJhbFN0cmluZywgSU5UMk5VTSgyNykpOworICAgIHJi X2hhc2hfYXNldChjbGFzc190YWdfbWFwLCBjQVNOMVVuaXZlcnNhbFN0cmlu ZywgSU5UMk5VTSgyOCkpOworICAgIHJiX2hhc2hfYXNldChjbGFzc190YWdf bWFwLCBjQVNOMUJNUFN0cmluZywgSU5UMk5VTSgzMCkpOworCisgICAgcmJf ZGVmaW5lX2NvbnN0KG1BU04xLCAiQ0xBU1NfVEFHX01BUCIsIGNsYXNzX3Rh Z19tYXApOwogfQogCkluZGV4OiBydWJ5L3Rlc3Qvb3BlbnNzbC90ZXN0X2Fz bjEucmIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gcnVieS90ZXN0L29w ZW5zc2wvdGVzdF9hc24xLnJiCShyZXZpc2lvbiAzMDY0MCkKKysrIHJ1Ynkv dGVzdC9vcGVuc3NsL3Rlc3RfYXNuMS5yYgkod29ya2luZyBjb3B5KQpAQCAt NDMwLDQgKzQzMCwzNiBAQAogICAgIGVuZAogICBlbmQKICAgCisgIGRlZiB0 ZXN0X2RlZmF1bHRfdGFnX29mX2NsYXNzCisgICAgT3BlblNTTDo6QVNOMTo6 Q0xBU1NfVEFHX01BUC5lYWNoIGRvIHxrbGFzcywgdGFnfAorICAgICAgYXNz ZXJ0X2VxdWFsKHRhZywgT3BlblNTTDo6QVNOMS5kZWZhdWx0X3RhZ19vZl9j bGFzcyhrbGFzcykpCisgICAgZW5kCisgIGVuZAorICAKKyAgZGVmIHRlc3Rf ZGVmYXVsdF90YWcKKyAgICBhc3NlcnRfZXF1YWwoMCwgT3BlblNTTDo6QVNO MS5kZWZhdWx0X3RhZyhPcGVuU1NMOjpBU04xOjpFbmRPZkNvbnRlbnQubmV3 KSkgICAgCisgICAgYXNzZXJ0X2VxdWFsKDEsIE9wZW5TU0w6OkFTTjEuZGVm YXVsdF90YWcoT3BlblNTTDo6QVNOMTo6Qm9vbGVhbi5uZXcodHJ1ZSkpKQor ICAgIGFzc2VydF9lcXVhbCgyLCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFn KE9wZW5TU0w6OkFTTjE6OkludGVnZXIubmV3KDEpKSkKKyAgICBhc3NlcnRf ZXF1YWwoMywgT3BlblNTTDo6QVNOMS5kZWZhdWx0X3RhZyhPcGVuU1NMOjpB U04xOjpCaXRTdHJpbmcubmV3KCJceDAxIikpKQorICAgIGFzc2VydF9lcXVh bCg0LCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6OkFTTjE6 Ok9jdGV0U3RyaW5nLm5ldygiXHgwMSIpKSkgICAgCisgICAgYXNzZXJ0X2Vx dWFsKDUsIE9wZW5TU0w6OkFTTjEuZGVmYXVsdF90YWcoT3BlblNTTDo6QVNO MTo6TnVsbC5uZXcobmlsKSkpICAgIAorICAgIGFzc2VydF9lcXVhbCg2LCBP cGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6OkFTTjE6Ok9iamVj dElkLm5ldygiMS4yLjMuNC41IikpKSAgICAKKyAgICBhc3NlcnRfZXF1YWwo MTAsIE9wZW5TU0w6OkFTTjEuZGVmYXVsdF90YWcoT3BlblNTTDo6QVNOMTo6 RW51bWVyYXRlZC5uZXcoMSkpKSAgICAKKyAgICBhc3NlcnRfZXF1YWwoMTIs IE9wZW5TU0w6OkFTTjEuZGVmYXVsdF90YWcoT3BlblNTTDo6QVNOMTo6VVRG OFN0cmluZy5uZXcoImEiKSkpIAorICAgIGFzc2VydF9lcXVhbCgxNiwgT3Bl blNTTDo6QVNOMS5kZWZhdWx0X3RhZyhPcGVuU1NMOjpBU04xOjpTZXF1ZW5j ZS5uZXcoW10pKSkgICAgCisgICAgYXNzZXJ0X2VxdWFsKDE3LCBPcGVuU1NM OjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6OkFTTjE6OlNldC5uZXcoW10p KSkgICAgCisgICAgYXNzZXJ0X2VxdWFsKDE4LCBPcGVuU1NMOjpBU04xLmRl ZmF1bHRfdGFnKE9wZW5TU0w6OkFTTjE6Ok51bWVyaWNTdHJpbmcubmV3KCJh IikpKQorICAgIGFzc2VydF9lcXVhbCgxOSwgT3BlblNTTDo6QVNOMS5kZWZh dWx0X3RhZyhPcGVuU1NMOjpBU04xOjpQcmludGFibGVTdHJpbmcubmV3KCJh IikpKQorICAgIGFzc2VydF9lcXVhbCgyMCwgT3BlblNTTDo6QVNOMS5kZWZh dWx0X3RhZyhPcGVuU1NMOjpBU04xOjpUNjFTdHJpbmcubmV3KCJhIikpKQor ICAgIGFzc2VydF9lcXVhbCgyMSwgT3BlblNTTDo6QVNOMS5kZWZhdWx0X3Rh ZyhPcGVuU1NMOjpBU04xOjpWaWRlb3RleFN0cmluZy5uZXcoImEiKSkpCisg ICAgYXNzZXJ0X2VxdWFsKDIyLCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFn KE9wZW5TU0w6OkFTTjE6OklBNVN0cmluZy5uZXcoImEiKSkpCisgICAgYXNz ZXJ0X2VxdWFsKDIzLCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5T U0w6OkFTTjE6OlVUQ1RpbWUubmV3KFRpbWUubm93KSkpCisgICAgYXNzZXJ0 X2VxdWFsKDI0LCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6 OkFTTjE6OkdlbmVyYWxpemVkVGltZS5uZXcoVGltZS5ub3cpKSkKKyAgICBh c3NlcnRfZXF1YWwoMjUsIE9wZW5TU0w6OkFTTjEuZGVmYXVsdF90YWcoT3Bl blNTTDo6QVNOMTo6R3JhcGhpY1N0cmluZy5uZXcoImEiKSkpCisgICAgYXNz ZXJ0X2VxdWFsKDI2LCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5T U0w6OkFTTjE6OklTTzY0U3RyaW5nLm5ldygiYSIpKSkKKyAgICBhc3NlcnRf ZXF1YWwoMjcsIE9wZW5TU0w6OkFTTjEuZGVmYXVsdF90YWcoT3BlblNTTDo6 QVNOMTo6R2VuZXJhbFN0cmluZy5uZXcoImEiKSkpCisgICAgYXNzZXJ0X2Vx dWFsKDI4LCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6OkFT TjE6OlVuaXZlcnNhbFN0cmluZy5uZXcoImEiKSkpCisgICAgYXNzZXJ0X2Vx dWFsKDMwLCBPcGVuU1NMOjpBU04xLmRlZmF1bHRfdGFnKE9wZW5TU0w6OkFT TjE6OkJNUFN0cmluZy5uZXcoImEiKSkpCisgIGVuZAorICAKIGVuZCBpZiBk ZWZpbmVkPyhPcGVuU1NMKQo= --mimepart_4d3ccade13674_1386598b1b02572--