22 Stimmen

Wie hoch ist die Entropie des Dot-Passwort-Systems von Android?

Wie viele Permutationen des androids dot login system möglich sind? Ich bin mir sicher, dass die Lösung dieses Problems in der Diskreten Mathematik liegt, und zwar Permutationen ohne Wiederholung Wenn Ihre Antwort keine Permutationen oder Kombinationen enthält, sind Sie falsch.

Die Länge von Passwörtern liegt zwischen 4 und 9 Punkten, insgesamt gibt es aber 9 Punkte zu permutieren, so dass meine ursprüngliche Gleichung lautet:

9P4+9P5+9P6+9P7+9P8+9P9

Ich weiß jedoch, dass diese Gleichung unvollständig ist, weil sie nicht alle Regeln berücksichtigt. Jeder Punkt unterscheidet sich durch seine Position. Wenn man also jedem Punkt eine Zahl zuordnet, sieht das wie folgt aus:

123
456
789

Das Passwort "1397" ist nicht möglich. Wenn Sie versuchen, dieses Passwort zu verwenden, haben Sie in Wirklichkeit "1236987" eingegeben, da die Zahlen dazwischen automatisch ausgewählt werden. Es muss eine weitere Gleichung erstellt werden, um diese Einschränkungen zu berücksichtigen, und dann von meiner obigen nPr-Gleichung abgezogen werden.

Ce site Link hat ein großartiges Video, in dem jemand den Android-Login benutzt. Es geht auch mehr ins Detail in die Regeln. Die Mathematik auf dieser Seite ist völlig falsch, er ist nicht einmal in der Nähe einer echten Lösung.

20voto

Omnifarious Punkte 52299

Dies ist nur eine Teilantwort. Die einzigen relevanten Ausgangspunkte sind 1, 2 und 5. Für die Punkte 1 und 2 kann man mit einer einfachen Rotationstransformation ein Muster erzeugen, das einem Muster entspricht, das bei einem beliebigen anderen Punkt (außer 5) beginnt. Das heißt, wenn man alle Muster, die bei 1 und 2 beginnen, aufzählen kann, kann man auch alle Muster zählen, die bei einer anderen Zahl als 5 beginnen, indem man mit 4 multipliziert.

Die Pfade, die bei 5 beginnen, sind ein anderer Fall. Man kann sie alle zählen, indem man alle Pfade zählt, die mit 5->1 und 5->2 beginnen und mit 4 multipliziert, da man wiederum alle anderen möglichen Pfade mit einer einfachen Rotationstransformation erzeugen kann.

Eine Möglichkeit, die Pfade aufzuzählen, wäre also...

(Alle Wege, die mit 1 beginnen + alle Wege, die mit 2 beginnen + alle Wege, die mit 5->1 beginnen + alle Wege, die mit 5->2 beginnen) * 4

Auch hier wieder das Nummerierungssystem, um den Überblick zu behalten:

1  2  3
4  5  6
7  8  9

Für diesen ersten Schritt:

Von 1 -> 2, 4, 5, 6 und 8 sind zugänglich.

Von 2 -> 1, 3, 4, 5, 6, 7 und 9 sind zugänglich (grundsätzlich nur nicht 8 oder sich selbst).

Von 5 -> 1, 2, 3, 4, 6, 7, 8, und 9 sind zugänglich.

Bei den Zügen danach wird es dann richtig interessant.

Zum Beispiel ist 1537 ein gültiges Passwort. 1539 ist es nicht.

Hier sind die Regeln kurz und bündig:

Kein Punkt darf zweimal Teil des Pfades sein. Ist ein Punkt nicht Teil des Pfades und wird er von einem Übergang genau überquert, wird er Teil des Pfades zwischen Quell- und Zielpunkt.

Hier sind einige Beispielpfade:

  • 2->3->1->8 ist erlaubt.
  • 1->3->2->5 ist nicht erlaubt, weil 2 nicht Teil des Pfades ist, wenn 1->3 genau über 2 geht, also wird der Pfad zu 1->2->3->5, ob du es willst oder nicht.
  • 1->2->3->7 ist nicht zulässig, weil 3->7 die 5 überquert und die 5 nicht bereits Teil des Pfades ist.
  • 1->5->3->7 ist erlaubt. Die 5 wird bei 3->7 ignoriert, da sie bereits Teil des Pfades ist.

Dieses Programm:

class LockPattern(object):
    def __init__(self, *args):
        if (len(args) == 1) and hasattr(args[0], '__iter__'):
            args = tuple(args[0])
        if len(args) > 9:
            raise TypeError("A LockPattern may have at most 9 elements.")
        self._pattern = ()
        for move in args:
            if not self.isValidNextStep(move):
                raise TypeError("%r is not a valid lock sequence." % (args,))
            else:
                self._pattern = self._pattern + (move,)
    def __len__(self):
        return len(self._pattern)
    def __iter__(self):
        return iter(self._pattern)
    def isValidNextStep(self, nextdot):
        nextdot = int(nextdot)
        if (nextdot < 1) or (nextdot > 9):
            raise ValueError("A lock sequence may only contain values from 1 "
                             "to 9 and %d isn't." % (nextdot,))
        if len(self._pattern) <= 0:
            return True # Any dot is valid for the first dot
        if len(self._pattern) >= 9:
            return False
        if nextdot in self._pattern:
            return False # No dot may be visited twice
        prevdot = self._pattern[-1]
        dotpair = tuple(sorted((prevdot, nextdot)))
        if dotpair == (1,3):
            return 2 in self._pattern
        if dotpair == (1,7):
            return 4 in self._pattern
        if dotpair in ((1,9),(2,8),(3,7),(4,6)):
            return 5 in self._pattern
        if dotpair == (3,9):
            return 6 in self._pattern
        if dotpair == (7,9):
            return 8 in self._pattern
        return True
    def isValidLockSequence(self):
        return 4 <= len(self)
    def newSequenceAddDot(self, nextdot):
        if not self.isValidNextStep(nextdot):
            raise ValueError("%d is not a valid next dot for the sequence." % (nextdot,))
        newseq = LockPattern()
        newseq._pattern = self._pattern + (nextdot,)
        return newseq

def genAllPatterns(starting = LockPattern()):
    if starting.isValidLockSequence():
        yield starting
    for dot in xrange(1,10):
        if starting.isValidNextStep(dot):
            for result in genAllPatterns(starting.newSequenceAddDot(dot)):
                yield result

print reduce(lambda x, p: x+1, genAllPatterns(), 0)

Erzeugt eine Antwort von 389112.

Es bestätigt auch meine früheren Intuitionen:

lsts = tuple(((p, list(genAllPatterns(LockPattern(p)))) for p in ((1,), (2,), (5,1), (5,2))))
[(x[0], len(x[1])) for x in lsts]
-> [((1,), 38042), ((2,), 43176), ((5, 1), 7352), ((5, 2), 8708)]
sum((len(x[1]) for x in lsts)
-> 97278
97278 * 4
-> 389112

2voto

Tyler McHenry Punkte 71707

Das Wichtigste ist, dass Sie, sobald Sie zwei beliebige Punkte besucht haben, jeden anderen Punkt erreichen können, ohne einen Punkt zu passieren, den Sie noch nicht besucht haben. Sobald Sie also zwei Startpunkte (in der richtigen Reihenfolge) ausgewählt haben, können Sie den Rest Ihres Passworts nach Belieben und in beliebiger Reihenfolge wählen. (Dies liegt daran, dass "Springerzüge" erlaubt sind, zumindest laut der von Ihnen verlinkten Seite)

Ohne die beiden Anfangspunkte ergibt sich also die Anzahl der verbleibenden 2-7-stelligen Zahlen: 7P2 + 7P3 + 7P4 + 7P5 + 7P6 + 7P7. Es gibt 56 potenzielle zweistellige Anfangsköpfe, weil man von jedem Eckpunkt aus 5 Züge machen kann, von jedem Randpunkt aus 7 und vom Mittelpunkt aus 8. Die Gesamtzahl der Entriegelungsmuster wäre also 56 * (7P2 + 7P3 + 7P4 + 7P5 + 7P6 + 7P7) = 766 752.

Wenn das falsch ist, liegt es wahrscheinlich daran, dass ich die Regeln dieses Systems nicht kenne.

2voto

JSchlather Punkte 1524

Zunächst einmal möchte ich sagen, dass "omnifarious" richtig zu sein scheint. Was können wir mit Mathematik anfangen. Ich würde ihm zustimmen, wenn er sagt, dass es tatsächlich nur 3 Fälle gibt, mit denen man sich beschäftigen muss. 1, 2 und 5.

Der Auftraggeber möchte eine elegante Zählformel, von der ich bezweifle, dass sie für ein Problem wie dieses existiert. Wenn man alle 9 Punkte verwendet, findet man Hamilton'sche Pfade, die, wenn es sich um einen vollständigen Graphen handeln würde, sehr einfach zu zählen wären (ist es aber nicht). Da jeder der drei Fälle einzigartig ist, muss man sie alle durchzählen, um die Gesamtzahl der Pfade zu ermitteln.

Schauen wir uns den ersten Fall an, der in einer Ecke beginnt. Du hast vier Möglichkeiten für eine Ecke, dann hast du 5 Möglichkeiten für dein nächstes Feld. Sie werden schnell sehen, dass sich unsere Formel ziemlich schnell ausdehnt, weil wir 5 Auswahlmöglichkeiten haben und diese 5 Auswahlmöglichkeiten in 2 Gruppen aufteilen müssen.

Wenn man auf ein mittleres Feld zieht, hat man immer die gleichen Möglichkeiten, egal auf welches Feld man zieht. Im Gegensatz zum Zug auf 5, der uns viel mehr Möglichkeiten gibt, ist unsere Formel bereits:

4*(4*(6)+1*(7))

Dann müssen wir die Optionen 6 und 7 in weitere Gruppen aufteilen. Wenn wir auf ein Seitenfeld ziehen, dann können wir jetzt auf zwei Seitenfelder, drei Ecken und ein Mittelfeld ziehen. Unsere Formel lautet dann:

4*(4*(2*(5)+3*(3)+1*(7))+1*(7))

Dann müssen wir damit beginnen, die Frage zu lösen, ob wir in das mittlere Quadrat gegangen wären, und ich werde hier aufhören. Die Suche nach Hamiltonschen Pfaden ist NP-komplett, auch wenn wir sie nur abzählen. Aber es gibt hier keine Eigenschaften, die wir für eine elegante Lösung ausnutzen können. Es handelt sich um ein graphentheoretisches Problem, bei dem man die Lösung mit roher Gewalt herbeiführen muss, wie es zuvor von Omnifarious getan wurde.

Ich werde versuchen zu erklären, warum Ihre Intuition falsch ist, das sagen Sie:

"Ich weiß mit Sicherheit, dass die Lösung in der diskreten Mathematik liegt, insbesondere bei Permutationen ohne Wiederholung. Wenn deine Antwort keine Permutationen oder Kombinationen verwendet, bist du falsch."

Leider wissen Sie das nicht mit Sicherheit, weil Sie keine Formel kennen (es sei denn, Sie können mir einen strengen, nicht-konstruktiven Beweis zeigen). Tatsache ist, dass eine Permutation oder eine Kombination bedeutet, dass man bei n Elementen bei jeder Iteration ein beliebiges Element auswählen kann. Nun kann man die Anzahl der Elemente, die man auswählen kann, und die Anzahl der Elemente, die man bei bestimmten Iterationen auswählen kann, einschränken. Was man aber nicht tun kann, und wofür man eine elegante Lösung erwarten kann, ist, dass das Auswählen bestimmter Gegenstände Auswirkungen darauf hat, welche Gegenstände man als nächstes auswählen kann. Das ist genau das, was diese Frage macht und warum es keine schöne Formel gibt, die Kombinationen und Permutationen verwendet.

Kurz gesagt, die Formel, die Sie suchen, gibt es nicht, aber Omnifarious hat die richtige Antwort gefunden.

2voto

DGaff Punkte 409

Omnifarious lag mit seinem Posting definitiv richtig - es gibt 389.112 Kombinationen. Ich habe einen riesigen Artikel über den gesamten Prozess der Bestimmung dieses Algorithmus gepostet, zusammen mit einer Textdatei, die jede einzelne Kombination von 1-9 auflistet (was möglich zu sein scheint, soweit ich das auf dem Telefon meiner Freundin erkennen konnte). Der Link zu diesem Inhalt ist dieser: http://bit.ly/hEHcBJ

1voto

Jim Punkte 631

Ich weiß nicht, ob sich noch jemand dafür interessiert, aber es handelt sich um ein Graphenpfad-Zählproblem. Es gibt 9 Knoten, also erstellen Sie eine 9 x 9 Matrix (jede Zeile ist ein Von-Knoten, jede Spalte ein Nach-Knoten). Wenn Knoten n mit Knoten m verbunden ist, setze (n,m) und (m,n) beide auf 1. Tun Sie dies für alle Verbindungen. Lassen Sie den Rest auf Null. Dies wird die Adjazenzmatrix genannt. Erhöhen Sie diese Matrix auf die Anzahl der Zeilen im Muster, und addieren Sie alle Einträge. Dies ist die Anzahl der Permutationen. Wenn es jemanden interessiert, werde ich etwas Python-Code posten (auf meinem Telefon, sonst würde ich ihn jetzt posten)

import numpy as np
paths = [[1,3,4],[2,3,4,5],[4,5],[4,6,7],[5,6,7,8],[7,8],[7],[8],[]]
m = [[0 for i in range(0,len(paths))] for j in range(0,len(paths))]

for i in range(0,len(paths)):
    for j in paths[i]:
        m[i][j] = 1
        m[j][i] = 1

for row in m:
    print row

[0, 1, 0, 1, 1, 0, 0, 0, 0]
[1, 0, 1, 1, 1, 1, 0, 0, 0]
[0, 1, 0, 0, 1, 1, 0, 0, 0]
[1, 1, 0, 0, 1, 0, 1, 1, 0]
[1, 1, 1, 1, 0, 1, 1, 1, 1]
[0, 1, 1, 0, 1, 0, 0, 1, 1]
[0, 0, 0, 1, 1, 0, 0, 1, 0]
[0, 0, 0, 1, 1, 1, 1, 0, 1]
[0, 0, 0, 0, 1, 1, 0, 1, 0]

adj = np.matrix(m)

adj.sum()
40

(adj**2).sum()
200

(adj**6).sum()
107648

Meine Antworten stimmen nicht mit denen überein, die andere Leute oben gegeben haben, also habe ich auch eine Graph-Traversal-Simulation für den fraglichen Graphen geschrieben. Die Antworten der Simulation (wegen der Erschöpfung) stimmen mit den Antworten aus der Adjazenzmatrixberechnung überein. Ich habe auch die ersten beiden (eine Kante und zwei Kanten) von Hand berechnet und erhielt die gleichen Antworten (40 und 200). Beachten Sie, dass ich davon ausgehe, dass Sie denselben Knoten wiederholt besuchen können (d. h. 1->2->1->2...).

Mein Diagramm:

0 - 1 - 2
| X | X |
3 - 4 - 5
| X | X |
6 - 7 - 8

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X