private void generateMatches ( final long start_time , final String password , final Match match , final Map < Match , List < Match > > non_intersecting_matches , final Map < Integer , Match > brute_force_matches , final List < Match > matches , int matches_length ) throws TimeoutException { if ( System . currentTimeMillis ( ) - start_time > configuration . getCombinationAlgorithmTimeout ( ) ) { throw new TimeoutException ( "Took too long to get best matches" ) ; } int index = matches . size ( ) ; matches . add ( match ) ; matches_length += match . getLength ( ) ; boolean found_next = false ; for ( Match next_match : non_intersecting_matches . get ( match ) ) { if ( matches . size ( ) > 1 ) { Match last_match = matches . get ( matches . size ( ) - 2 ) ; if ( next_match . getStartIndex ( ) < last_match . getEndIndex ( ) && last_match . getStartIndex ( ) < next_match . getEndIndex ( ) ) { continue ; } } generateMatches ( start_time , password , next_match , non_intersecting_matches , brute_force_matches , matches , matches_length ) ; found_next = true ; } if ( ! found_next ) { // We always look for the most complete match, even if it's not the lowest entropy. if ( best_matches . isEmpty ( ) || ( matches_length >= best_matches_length && ( calcEntropy ( matches , false ) / matches_length ) < ( calcEntropy ( best_matches , false ) / best_matches_length ) ) ) { best_matches . clear ( ) ; best_matches . addAll ( matches ) ; best_matches_length = matches_length ; backfillBruteForce ( password , brute_force_matches , best_matches ) ; } } // Leave the array in the same state we found it in at the start. matches . remove ( index ) ; }
Recursive function to generate match combinations to get an optimal match .