mirror of
https://github.com/status-im/zxcvbn-go.git
synced 2025-02-10 10:16:55 +00:00
Get all permutation of leet sub
This commit is contained in:
parent
58d1351487
commit
7725100293
@ -8,7 +8,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
// "github.com/deckarep/golang-set"
|
|
||||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -328,6 +327,32 @@ func l33tMatch(password string) []match.Match {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAllPermutationsOfLeetSubstitutions(password string, substitutionsMap map[string][]string) []string {
|
||||||
|
|
||||||
|
var permutations []string
|
||||||
|
|
||||||
|
for index, char := range password {
|
||||||
|
for value, splice := range substitutionsMap {
|
||||||
|
for _, sub := range splice {
|
||||||
|
if string(char) == sub {
|
||||||
|
var permutation string
|
||||||
|
permutation = password[:index]+value+password[index+1:]
|
||||||
|
|
||||||
|
permutations = append(permutations, permutation)
|
||||||
|
if index < len(permutation) {
|
||||||
|
tempPermutations := getAllPermutationsOfLeetSubstitutions(permutation[index + 1:], substitutionsMap)
|
||||||
|
for _, temp := range tempPermutations {
|
||||||
|
permutations = append(permutations, permutation[:index + 1] + temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permutations
|
||||||
|
}
|
||||||
//TODO: what is the return value of this?
|
//TODO: what is the return value of this?
|
||||||
//func enumerateL33tSubs(table map[string]string) []string {
|
//func enumerateL33tSubs(table map[string]string) []string {
|
||||||
//
|
//
|
||||||
@ -386,12 +411,12 @@ func l33tMatch(password string) []match.Match {
|
|||||||
// return nil
|
// return nil
|
||||||
//}
|
//}
|
||||||
|
|
||||||
func relevantL33tSubtable(password string) map[string]string {
|
func relevantL33tSubtable(password string) map[string][]string {
|
||||||
relevantSubs := make(map[string]string)
|
relevantSubs := make(map[string][]string)
|
||||||
for key, values := range L33T_TABLE.Graph {
|
for key, values := range L33T_TABLE.Graph {
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
if strings.Contains(password, value) {
|
if strings.Contains(password, value) {
|
||||||
relevantSubs[value] = key
|
relevantSubs[key] = append(relevantSubs[key], value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,4 +128,43 @@ func TestLeetSubTable(t *testing.T){
|
|||||||
|
|
||||||
subs = relevantL33tSubtable("p4ssw0rd")
|
subs = relevantL33tSubtable("p4ssw0rd")
|
||||||
assert.Len(t, subs, 2, "p4ssw0rd should produce 2 subs")
|
assert.Len(t, subs, 2, "p4ssw0rd should produce 2 subs")
|
||||||
|
|
||||||
|
subs = relevantL33tSubtable("1eet")
|
||||||
|
assert.Len(t, subs, 2, "1eet should produce 2 subs")
|
||||||
|
assert.Equal(t, subs["i"][0], "1")
|
||||||
|
assert.Equal(t, subs["l"][0], "1")
|
||||||
|
|
||||||
|
|
||||||
|
subs = relevantL33tSubtable("4pple@pple")
|
||||||
|
assert.Len(t, subs, 1, "4pple@pple should produce 1 subs")
|
||||||
|
assert.Len(t, subs["a"], 2)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPermutationsOfLeetSubstitutions(t *testing.T){
|
||||||
|
password := "p4ssw0rd" //[passw0rd, password, p4ssword]
|
||||||
|
possibleSubs := relevantL33tSubtable(password)
|
||||||
|
|
||||||
|
permutations := getAllPermutationsOfLeetSubstitutions(password, possibleSubs)
|
||||||
|
|
||||||
|
assert.Len(t, permutations, 3, "There should be 3 permutations for "+password)
|
||||||
|
|
||||||
|
password = "p4$sw0rd" //[pa$sw0rd, passw0rd, password, pa$sword, p4ssw0rd, p4ssword, p4$sword]
|
||||||
|
possibleSubs = relevantL33tSubtable(password)
|
||||||
|
|
||||||
|
permutations = getAllPermutationsOfLeetSubstitutions(password, possibleSubs)
|
||||||
|
assert.Len(t, permutations, 7, "There should be 7 (? check my math) permutations for "+password)
|
||||||
|
|
||||||
|
password = "p4$$w0rd" //[pa$sw0rd, passw0rd, password, pa$sword, p4ssw0rd, p4ssword, p4$sword]
|
||||||
|
possibleSubs = relevantL33tSubtable(password)
|
||||||
|
|
||||||
|
permutations = getAllPermutationsOfLeetSubstitutions(password, possibleSubs)
|
||||||
|
assert.Len(t, permutations, 15, "Check my math 2*2*2*2 - 1 "+password)
|
||||||
|
|
||||||
|
|
||||||
|
password = "1337"
|
||||||
|
possibleSubs = relevantL33tSubtable(password)
|
||||||
|
permutations = getAllPermutationsOfLeetSubstitutions(password, possibleSubs)
|
||||||
|
assert.Len(t, permutations, 35, "check my math 3*2*2*3 -1 ")
|
||||||
}
|
}
|
@ -3,26 +3,24 @@ package zxcvbn
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Use these test to see how close to feature parity the library is.
|
Use these test to see how close to feature parity the library is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
allowableError = float64(0.01)
|
allowableError = float64(0.01)
|
||||||
)
|
)
|
||||||
|
|
||||||
type failedTest struct {
|
type failedTest struct {
|
||||||
Password string
|
Password string
|
||||||
Expect float64
|
Expect float64
|
||||||
Actual float64
|
Actual float64
|
||||||
PError float64
|
PError float64
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var failedTests []failedTest
|
var failedTests []failedTest
|
||||||
@ -32,11 +30,11 @@ func TestPasswordStrength(t *testing.T) {
|
|||||||
|
|
||||||
//Expected calculated by running zxcvbn-python
|
//Expected calculated by running zxcvbn-python
|
||||||
runTest(t, "zxcvbn", float64(6.845490050944376))
|
runTest(t, "zxcvbn", float64(6.845490050944376))
|
||||||
runTest(t, "Tr0ub4dour&3",float64(17.296) )
|
runTest(t, "Tr0ub4dour&3", float64(17.296))
|
||||||
runTest(t,"qwER43@!", float64(26.44) )
|
runTest(t, "qwER43@!", float64(26.44))
|
||||||
runTest(t,"correcthorsebatterystaple", float64(45.212) )
|
runTest(t, "correcthorsebatterystaple", float64(45.212))
|
||||||
runTest(t,"coRrecth0rseba++ery9.23.2007staple$", float64(66.018) )
|
runTest(t, "coRrecth0rseba++ery9.23.2007staple$", float64(66.018))
|
||||||
runTest(t,"D0g..................", float64(20.678) )
|
runTest(t, "D0g..................", float64(20.678))
|
||||||
runTest(t, "abcdefghijk987654321", float64(11.951))
|
runTest(t, "abcdefghijk987654321", float64(11.951))
|
||||||
runTest(t, "neverforget13/3/1997", float64(32.628))
|
runTest(t, "neverforget13/3/1997", float64(32.628))
|
||||||
runTest(t, "1qaz2wsx3edc", float64(19.314))
|
runTest(t, "1qaz2wsx3edc", float64(19.314))
|
||||||
@ -71,20 +69,20 @@ func TestPasswordStrength(t *testing.T) {
|
|||||||
fmt.Printf(formatString, test.Password, allowableError, test.PError, test.Expect, test.Actual)
|
fmt.Printf(formatString, test.Password, allowableError, test.PError, test.Expect, test.Actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
pTestPassed := (float64(numTestRan - len(failedTests))/ float64(numTestRan))* float64(100)
|
pTestPassed := (float64(numTestRan-len(failedTests)) / float64(numTestRan)) * float64(100)
|
||||||
|
|
||||||
fmt.Println("\n % of the test passed " + strconv.FormatFloat(pTestPassed, 'f', -1, 64) )
|
fmt.Println("\n % of the test passed " + strconv.FormatFloat(pTestPassed, 'f', -1, 64))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTest(t *testing.T, password string, pythonEntropy float64) {
|
func runTest(t *testing.T, password string, pythonEntropy float64) {
|
||||||
//Calculated by running it through python-zxcvbn
|
//Calculated by running it through python-zxcvbn
|
||||||
goEntropy := GoPasswordStrength(password, nil)
|
goEntropy := GoPasswordStrength(password, nil)
|
||||||
perror := math.Abs(goEntropy-pythonEntropy)/pythonEntropy
|
perror := math.Abs(goEntropy-pythonEntropy) / pythonEntropy
|
||||||
|
|
||||||
numTestRan++
|
numTestRan++
|
||||||
if perror > allowableError {
|
if perror > allowableError {
|
||||||
failedTests = append(failedTests, failedTest{Password:password, Expect:pythonEntropy, Actual:goEntropy,PError:perror})
|
failedTests = append(failedTests, failedTest{Password: password, Expect: pythonEntropy, Actual: goEntropy, PError: perror})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user