Exemplo n.º 1
0
def repeat_match(password):
    matches = []
    greedy = r"(.+)\1+"
    lazy = r"(.+?)\1+"
    lazy_anchored = r"^(.+?)\1+$"
    lastIndex = 0

    while lastIndex < len(password):
        greedy_match = re.search(greedy, password[lastIndex:])
        lazy_match = re.search(lazy, password[lastIndex:])

        if greedy_match is None:
            break

        if len(greedy_match.group(0)) > len(lazy_match.group(0)):
            match = greedy_match
            base_token = re.search(lazy_anchored, match.group(0)).group(1)

        else:
            match = lazy_match
            base_token = match.group(1)

        i, j = [
            match.start() + lastIndex,
            match.start() + len(match.group(0)) - 1 + lastIndex
        ]

        # TODO: Implement base analysis
        base_analysis = scoring.most_guessable_match_sequence(
            base_token, omnimatch(base_token))
        base_matches = base_analysis[
            "match_sequence"] if "match_sequence" in base_analysis and base_analysis[
                "match_sequence"] is not None else None
        base_guesses = base_analysis["guesses"]
        matches.append({
            "pattern": "repeat",
            "i": i,
            "j": j,
            "token": match.group(0),
            "base_token": base_token,
            "base_guesses": base_guesses,
            "base_matches": base_matches,
            "repeat_count": len(match.group(0)) / len(base_token)
        })
        lastIndex = j + 1
    return matches
Exemplo n.º 2
0
    def test_repeat_guesses(self):
        pattern_list = [["aa", "a", 2], ["999", "9", 3], ["$$$$", "$", 4],
                        ["abab", "ab", 2],
                        [
                            "batterystaplebatterystaplebatterystaple",
                            "batterystaple", 3
                        ]]
        for [token, base_token, repeat_count] in pattern_list:
            base_guesses = scoring.most_guessable_match_sequence(
                base_token, matching.omnimatch(base_token))["guesses"]
            match = {
                "token": token,
                "base_token": base_token,
                "base_guesses": base_guesses,
                "repeat_count": repeat_count
            }

            expected_guesses = base_guesses * repeat_count
            msg = "the repeat pattern '{}' has guesses of {}".format(
                token, expected_guesses)
            self.assertEqual(scoring.repeat_guesses(match), expected_guesses,
                             msg)
Exemplo n.º 3
0
    def test_repeat_guesses(self):
        pattern_list = [
            ["aa",   "a",  2],
            ["999",  "9",  3],
            ["$$$$", "$",  4],
            ["abab", "ab", 2],
            ["batterystaplebatterystaplebatterystaple", "batterystaple", 3]
        ]
        for [token, base_token, repeat_count] in pattern_list:
            base_guesses = scoring.most_guessable_match_sequence(
                base_token,
                matching.omnimatch(base_token)
            )["guesses"]
            match = {
                "token": token,
                "base_token": base_token,
                "base_guesses": base_guesses,
                "repeat_count": repeat_count
            }

            expected_guesses = base_guesses * repeat_count
            msg = "the repeat pattern '{}' has guesses of {}".format(token, expected_guesses)
            self.assertEqual(scoring.repeat_guesses(match), expected_guesses, msg)
Exemplo n.º 4
0
    def test_search(self):
        def m(i, j, guesses):
            return {
                "i": i,
                "j": j,
                "guesses": guesses
            }
        password = "******"

        # for tests, set additive penalty to zero.
        exclude_additive = True

        # Case
        def msg1(s):
            return "returns one bruteforce match given an empty match sequence: {}".format(s)

        result = scoring.most_guessable_match_sequence(password, [])
        self.assertEqual(len(result["sequence"]), 1, msg1("len(result) == 1"))
        m0 = result["sequence"][0]
        self.assertEqual(m0["pattern"], "bruteforce", msg1("match['pattern'] == 'bruteforce'"))
        self.assertEqual(m0["token"], password, msg1("match['token'] == '{}'".format(password)))
        self.assertEqual([m0["i"], m0["j"]], [0, 9], msg1("[i, j] == [{}, {}]".format(m0["i"], m0["j"])))

        # Case
        def msg2(s):
            return "returns match + bruteforce when match covers a prefix of password: {}".format(s)
        m0 = m(0, 5, 1)
        matches = [m0]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 2, msg2("len(result.match.sequence) == 2"))
        self.assertEqual(result["sequence"][0], m0, msg2("first match is the provided match object"))
        m1 = result["sequence"][1]
        self.assertEqual(m1["pattern"], "bruteforce", msg2("second match is bruteforce"))
        self.assertEqual([m1["i"], m1["j"]], [6, 9], msg2("second match covers full suffix after first match"))

        # Case
        def msg3(s):
            return "returns bruteforce + match when match covers a suffix: {}".format(s)
        m1 = m(3, 9, 1)
        matches = [m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 2, msg3("result.match.sequence.length == 2"))
        m0 = result["sequence"][0]
        self.assertEqual(m0["pattern"], "bruteforce", msg3("first match is bruteforce"))
        self.assertEqual([m0["i"], m0["j"]], [0, 2], msg3("first match covers full prefix before second match"))
        self.assertEqual(result["sequence"][1], m1, msg3("second match is the provided match object"))

        # Case
        def msg4(s):
            return "returns bruteforce + match + bruteforce when match covers an infix: {}".format(s)
        m1 = m(1, 8, 1)
        matches = [m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 3, msg4("result.length == 3"))
        self.assertEqual(result["sequence"][1], m1, msg4("middle match is the provided match object"))
        m0 = result["sequence"][0]
        m2 = result["sequence"][2]
        self.assertEqual([m0["i"], m0["j"]], [0, 0], msg4("first match covers full prefix before second match"))
        self.assertEqual([m2["i"], m2["j"]], [9, 9], msg4("third match covers full suffix after second match"))

        # Case
        def msg5(s):
            return "chooses lower-guesses match given two matches of the same span: {}".format(s)
        m0, m1 = (m(0, 9, 1), m(0, 9, 2))
        matches = [m0, m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 1, msg5("result.length == 1"))
        self.assertEqual(result["sequence"][0], m0, msg5("result.sequence[0] == m0"))
        m0["guesses"] = 3
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 1, msg5("result.length == 1"))
        self.assertEqual(result["sequence"][0], m1, msg5("result.sequence[0] == m1"))

        # Case
        def msg6(s):
            return "when m0 covers m1 and m2, choose [m0] when m0 < m1 * m2 * fact(2): {}".format(s)
        m0, m1, m2 = (m(0, 9, 3), m(0, 3, 2), m(4, 9, 1))
        matches = [m0, m1, m2]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(result["guesses"], 3, msg6("total guesses == 3"))
        self.assertEqual(result["sequence"], [m0], msg6("sequence is [m0]"))

        # Case
        def msg7(s):
            return "when m0 covers m1 and m2, choose [m1, m2] when m0 > m1 * m2 * fact(2): {}".format(s)
        m0["guesses"] = 5
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(result["guesses"], 4, msg7("total guesses == 3"))
        self.assertEqual(result["sequence"], [m1, m2], msg7("sequence is [m0]"))
Exemplo n.º 5
0
    def test_search(self):
        def m(i, j, guesses):
            return {
                "i": i,
                "j": j,
                "guesses": guesses
            }
        password = "******"

        # for tests, set additive penalty to zero.
        exclude_additive = True

        # Case
        def msg1(s):
            return "returns one bruteforce match given an empty match sequence: {}".format(s)

        result = scoring.most_guessable_match_sequence(password, [])
        self.assertEqual(len(result["sequence"]), 1, msg1("len(result) == 1"))
        m0 = result["sequence"][0]
        self.assertEqual(m0["pattern"], "bruteforce", msg1("match['pattern'] == 'bruteforce'"))
        self.assertEqual(m0["token"], password, msg1("match['token'] == '{}'".format(password)))
        self.assertEqual([m0["i"], m0["j"]], [0, 9], msg1("[i, j] == [{}, {}]".format(m0["i"], m0["j"])))

        # Case
        def msg2(s):
            return "returns match + bruteforce when match covers a prefix of password: {}".format(s)
        m0 = m(0, 5, 1)
        matches = [m0]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 2, msg2("len(result.match.sequence) == 2"))
        self.assertEqual(result["sequence"][0], m0, msg2("first match is the provided match object"))
        m1 = result["sequence"][1]
        self.assertEqual(m1["pattern"], "bruteforce", msg2("second match is bruteforce"))
        self.assertEqual([m1["i"], m1["j"]], [6, 9], msg2("second match covers full suffix after first match"))

        # Case
        def msg3(s):
            return "returns bruteforce + match when match covers a suffix: {}".format(s)
        m1 = m(3, 9, 1)
        matches = [m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 2, msg3("result.match.sequence.length == 2"))
        m0 = result["sequence"][0]
        self.assertEqual(m0["pattern"], "bruteforce", msg3("first match is bruteforce"))
        self.assertEqual([m0["i"], m0["j"]], [0, 2], msg3("first match covers full prefix before second match"))
        self.assertEqual(result["sequence"][1], m1, msg3("second match is the provided match object"))

        # Case
        def msg4(s):
            return "returns bruteforce + match + bruteforce when match covers an infix: {}".format(s)
        m1 = m(1, 8, 1)
        matches = [m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 3, msg4("result.length == 3"))
        self.assertEqual(result["sequence"][1], m1, msg4("middle match is the provided match object"))
        m0 = result["sequence"][0]
        m2 = result["sequence"][2]
        self.assertEqual([m0["i"], m0["j"]], [0, 0], msg4("first match covers full prefix before second match"))
        self.assertEqual([m2["i"], m2["j"]], [9, 9], msg4("third match covers full suffix after second match"))

        # Case
        def msg5(s):
            return "chooses lower-guesses match given two matches of the same span: {}".format(s)
        m0, m1 = (m(0, 9, 1), m(0, 9, 2))
        matches = [m0, m1]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 1, msg5("result.length == 1"))
        self.assertEqual(result["sequence"][0], m0, msg5("result.sequence[0] == m0"))
        m0["guesses"] = 3
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(len(result["sequence"]), 1, msg5("result.length == 1"))
        self.assertEqual(result["sequence"][0], m1, msg5("result.sequence[0] == m1"))

        # Case
        def msg6(s):
            return "when m0 covers m1 and m2, choose [m0] when m0 < m1 * m2 * fact(2): {}".format(s)
        m0, m1, m2 = (m(0, 9, 3), m(0, 3, 2), m(4, 9, 1))
        matches = [m0, m1, m2]
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(result["guesses"], 3, msg6("total guesses == 3"))
        self.assertEqual(result["sequence"], [m0], msg6("sequence is [m0]"))

        # Case
        def msg7(s):
            return "when m0 covers m1 and m2, choose [m1, m2] when m0 > m1 * m2 * fact(2): {}".format(s)
        m0["guesses"] = 5
        result = scoring.most_guessable_match_sequence(password, matches, exclude_additive)
        self.assertEqual(result["guesses"], 4, msg7("total guesses == 3"))
        self.assertEqual(result["sequence"], [m1, m2], msg7("sequence is [m0]"))