Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <chrono>
- #include <array>
- #include <iterator>
- #include <so_5/all.hpp>
- #include <md5_cpp11/all.hpp>
- using namespace std;
- using namespace std::chrono;
- using password = array< char, 5 >;
- ostream & operator<<( ostream & to, const password & pw )
- {
- copy( begin(pw), end(pw), ostream_iterator< password::value_type >(to) );
- return to;
- }
- password::value_type next_byte( password::value_type b )
- {
- switch( b )
- {
- case 'z' : return '0';
- case '9' : return 'a';
- default : return b + 1;
- }
- }
- void next_pass( password & p )
- {
- for( auto e = p.rbegin(); e != p.rend(); ++e )
- {
- *e = next_byte( *e );
- if( '0' != *e )
- break;
- }
- }
- struct process_range : public so_5::rt::message_t
- {
- const password m_start;
- const password m_end;
- process_range( const password & start, const password & end )
- : m_start( start )
- , m_end( end )
- {}
- };
- struct found : public so_5::rt::message_t
- {
- const password m_result;
- found( const password & result ) : m_result( result ) {}
- };
- struct get_next_range : public so_5::rt::signal_t {};
- void generate_next_range(
- password & last,
- const so_5::rt::mbox_t & channel )
- {
- auto start = last;
- last[ 0 ] = next_byte( last[ 0 ] );
- so_5::send< process_range >( channel, start, last );
- }
- void worker(
- const so_5::rt::mbox_t & channel,
- const md5_cpp11::digest & etalon,
- const process_range & evt )
- {
- auto pw = evt.m_start;
- while( pw != evt.m_end && md5_cpp11::make_digest( pw ) != etalon )
- next_pass( pw );
- if( pw == evt.m_end )
- so_5::send< get_next_range >( channel );
- else
- so_5::send< found >( channel, pw );
- }
- void do_brute_force( so_5::rt::environment_t & env )
- {
- const auto hash = md5_cpp11::from_hex_string(
- "95ebc3c7b3b9f1d2c40fec14415d3cb8" ); // "zzzzz"
- using namespace so_5::disp::adv_thread_pool;
- auto workers = thread::hardware_concurrency();
- auto coop = env.create_coop( so_5::autoname,
- create_private_disp( env, workers )->binder(
- params_t{}.fifo( fifo_t::individual ) ) );
- const auto channel = env.create_local_mbox();
- // State for generator.
- auto last = make_shared< password >();
- last->fill( '0' );
- // Generator itself.
- coop->define_agent()
- .on_start( [channel, workers] {
- for( size_t i = 0; i != workers; ++i )
- so_5::send< get_next_range >( channel );
- } )
- .event< get_next_range >( channel,
- [last, channel] {
- generate_next_range( *last, channel );
- } );
- // Worker.
- coop->define_agent().event( channel,
- [channel, hash]( const process_range & evt ) {
- worker( channel, hash, evt );
- },
- so_5::thread_safe );
- // Result printer.
- coop->define_agent().event( channel,
- [&env]( const found & evt ) {
- cout << "password: " << evt.m_result << endl;
- env.stop();
- } );
- env.register_coop( move( coop ) );
- }
- double time_spent( const steady_clock::time_point s )
- {
- const auto e = steady_clock::now();
- return duration_cast< milliseconds >( e - s ).count() / 1000.0;
- }
- int main()
- {
- try
- {
- const auto started_at = steady_clock::now();
- so_5::launch( do_brute_force );
- cout << "time: " << time_spent( started_at ) << "s" << endl;
- return 0;
- }
- catch( const exception & x )
- {
- cerr << "Exception: " << x.what() << endl;
- }
- return 2;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement