Skip to content

Commit

Permalink
v0.3.6 (#41)
Browse files Browse the repository at this point in the history
* Change default passphrase transformations

* Update defaults for passphrases

* Stub markdown output

* Add markdown table output

- added the -md flag which allows output formatting as a markdown table with the command used
- linted
  • Loading branch information
JakeWnuk authored Oct 5, 2024
1 parent 0c94308 commit 52f0630
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 55 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ git clone https://github.com/JakeWnuk/ptt && cd ptt && docker build -t ptt . &&

### Usage:
```
Usage of Password Transformation Tool (ptt) version (0.3.5):
Usage of Password Transformation Tool (ptt) version (0.3.6):
ptt [options] [...]
Accepts standard input and/or additonal arguments.
Expand All @@ -63,6 +63,8 @@ These modify or filter the transformation mode.
Only output items of a certain length (does not adjust for rules). Accepts ranges separated by '-'.
-m int
Minimum numerical frequency to include in output.
-md
If Markdown format should be used for output instead.
-n int
Maximum number of items to return in output.
-o string
Expand Down
2 changes: 1 addition & 1 deletion docs/USAGE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Password Transformation Tool (PTT) Usage Guide
## Version 0.3.5
## Version 0.3.6

### Table of Contents
#### Getting Started
Expand Down
19 changes: 15 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/jakewnuk/ptt/pkg/utils"
)

var version = "0.3.5"
var version = "0.3.6"
var wg sync.WaitGroup
var mutex = &sync.Mutex{}
var retain models.FileArgumentFlag
Expand Down Expand Up @@ -88,6 +88,7 @@ func main() {
verbose2 := flag.Bool("vv", false, "Show statistics output when possible.")
verbose3 := flag.Bool("vvv", false, "Show verbose statistics output when possible.")
minimum := flag.Int("m", 0, "Minimum numerical frequency to include in output.")
markDownOutput := flag.Bool("md", false, "If Markdown format should be used for output instead.")
outputVerboseMax := flag.Int("n", 0, "Maximum number of items to return in output.")
transformation := flag.String("t", "", "Transformation to apply to input.")
replacementMask := flag.String("rm", "uldsbt", "Replacement mask for transformations if applicable.")
Expand Down Expand Up @@ -238,12 +239,22 @@ func main() {

fmt.Fprintf(os.Stderr, "[*] Task complete with %d unique results.\n", len(primaryMap))

// Print in markdown if provided
if *markDownOutput {
command := "ptt "
for _, arg := range os.Args[1:] {
command += arg + " "
}

format.PrintArrayToMarkdown(primaryMap, command)
}

// Print output to stdout
if *verbose3 {
if *verbose3 && !*markDownOutput {
format.PrintStatsToSTDOUT(primaryMap, *verbose3, *outputVerboseMax)
} else if *verbose2 {
} else if *verbose2 && !*markDownOutput {
format.PrintStatsToSTDOUT(primaryMap, *verbose3, *outputVerboseMax)
} else {
} else if !*markDownOutput {
format.PrintArrayToSTDOUT(primaryMap, *verbose)
}

Expand Down
77 changes: 53 additions & 24 deletions pkg/format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,35 @@ func PrintArrayToSTDOUT(freq map[string]int, verbose bool) {
}
}

// PrintArrayToMarkdown prints an array of items to stdout in markdown format
// including the item and the frequency.
//
// Args:
// freq (map[string]int): A map of item frequencies
// command (string): The command that was run
//
// Returns:
// None
func PrintArrayToMarkdown(freq map[string]int, command string) {

fmt.Println("| Item | Frequency |")
fmt.Println("| ---- | --------- |")

p := make(models.PairList, len(freq))
i := 0
for k, v := range freq {
p[i] = models.Pair{k, v}
i++
}
sort.Sort(sort.Reverse(p))
for _, pair := range p {
fmt.Printf("| %s | %d |\n", pair.Key, pair.Value)
}

fmt.Println(fmt.Sprintf("Command: %s\n", command))

}

// PrintStatsToSTDOUT prints statistics about the frequency map to stdout
// including several statistics about the frequency map. If verbose is true,
// additional information is printed and increased number of items are
Expand All @@ -58,12 +87,12 @@ func PrintArrayToSTDOUT(freq map[string]int, verbose bool) {
//
// freq (map[string]int): A map of item frequencies
// verbose (bool): If true, additional information is printed
// max (int): The maximum number of items to print
// maxItems (int): The maximum number of items to print
//
// Returns:
//
// None
func PrintStatsToSTDOUT(freq map[string]int, verbose bool, max int) {
func PrintStatsToSTDOUT(freq map[string]int, verbose bool, maxItems int) {

// Sort by frequency
p := make(models.PairList, len(freq))
Expand All @@ -77,12 +106,12 @@ func PrintStatsToSTDOUT(freq map[string]int, verbose bool, max int) {
sort.Sort(sort.Reverse(p))
sort.Sort(sort.Reverse(normalizedP))

if max == 0 {
max = 25
if maxItems == 0 {
maxItems = 25
}

if max > len(p) {
max = len(p)
if maxItems > len(p) {
maxItems = len(p)
}

if len(p) == 0 {
Expand All @@ -93,7 +122,7 @@ func PrintStatsToSTDOUT(freq map[string]int, verbose bool, max int) {
// Print the statistics
if verbose {
fmt.Fprintf(os.Stderr, "[*] Starting statistics generation. Please wait...\n")
fmt.Println(fmt.Sprintf("Verbose Statistics: max=%d", max))
fmt.Println(fmt.Sprintf("Verbose Statistics: max=%d", maxItems))
fmt.Println("--------------------------------------------------")
fmt.Println(CreateVerboseStats(freq))
fmt.Println("--------------------------------------------------")
Expand All @@ -108,14 +137,14 @@ func PrintStatsToSTDOUT(freq map[string]int, verbose bool, max int) {

// Use the longest key to normalize padding for the graph
longest := 0
for _, value := range p[0:max] {
for _, value := range p[0:maxItems] {
if len(value.Key) > longest {
longest = len(value.Key)
}
}

// Print the top items
for index, value := range p[0:max] {
for index, value := range p[0:maxItems] {
if value.Value == 1 && index == 0 {
fmt.Println("[!] No items with a frequency greater than 1!")
break
Expand Down Expand Up @@ -179,15 +208,15 @@ func CreateVerboseStats(freq map[string]int) string {
stats += fmt.Sprintf("Smallest frequency: %d\n", p[len(p)-1].Value)

stats += "\nPlots:\n"
plot, min, q1, q2, q3, max := CreateBoxAndWhiskersPlot(lengths)
plot, minBW, q1, q2, q3, maxBW := CreateBoxAndWhiskersPlot(lengths)
stats += fmt.Sprintf("Item Length: %s\n", plot)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", min, q1, q2, q3, max)
plot, min, q1, q2, q3, max = CreateBoxAndWhiskersPlot(frequencies)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", minBW, q1, q2, q3, maxBW)
plot, minBW, q1, q2, q3, maxBW = CreateBoxAndWhiskersPlot(frequencies)
stats += fmt.Sprintf("Item Frequency: %s\n", plot)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", min, q1, q2, q3, max)
plot, min, q1, q2, q3, max = CreateBoxAndWhiskersPlot(complexities)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", minBW, q1, q2, q3, maxBW)
plot, minBW, q1, q2, q3, maxBW = CreateBoxAndWhiskersPlot(complexities)
stats += fmt.Sprintf("Item Complexity: %s\n", plot)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", min, q1, q2, q3, max)
stats += fmt.Sprintf("Min: %d, Q1: %d, Q2: %d, Q3: %d, Max: %d\n", minBW, q1, q2, q3, maxBW)

stats += "\nCategory Counts:\n"
for category, count := range categoryCounts {
Expand Down Expand Up @@ -384,19 +413,19 @@ func CalculateQuartiles(data []int) (int, int, int) {
// int: The maximum value
func CreateBoxAndWhiskersPlot(data []int) (string, int, int, int, int, int) {
q1, q2, q3 := CalculateQuartiles(data)
min := data[0]
max := data[len(data)-1]
minBW := data[0]
maxBW := data[len(data)-1]

// Normalize the plot
largest := max
largest := maxBW
normalizedQ1 := q1 * 50 / largest
normalizedQ2 := q2 * 50 / largest
normalizedQ3 := q3 * 50 / largest
normalizedMin := min * 50 / largest
normalizedMax := max * 50 / largest
normalizedMin := minBW * 50 / largest
normalizedMax := maxBW * 50 / largest

plot := fmt.Sprintf("|%s[%s|%s]%s|", strings.Repeat("-", normalizedQ1-normalizedMin), strings.Repeat("=", normalizedQ2-normalizedQ1), strings.Repeat("=", normalizedQ3-normalizedQ2), strings.Repeat("-", normalizedMax-normalizedQ3))
return plot, min, q1, q2, q3, max
return plot, minBW, q1, q2, q3, maxBW
}

// SaveArrayToJSON saves an array of items to a JSON file at the specified path
Expand Down Expand Up @@ -488,15 +517,15 @@ func RetainRemove(textMap map[string]int, retainMap map[string]int, removeMap ma
// Args:
//
// freq (map[string]int): A map of item frequencies
// min (int): The minimum frequency threshold
// minF (int): The minimum frequency threshold
//
// Returns:
//
// (map[string]int): A new map of item frequencies above the minimum threshold
func RemoveMinimumFrequency(freq map[string]int, min int) map[string]int {
func RemoveMinimumFrequency(freq map[string]int, minF int) map[string]int {
newFreq := make(map[string]int)
for key, value := range freq {
if value >= min {
if value >= minF {
newFreq[key] = value
}
}
Expand Down
31 changes: 7 additions & 24 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -1004,10 +1004,6 @@ func GeneratePassphrase(text string, n int) []string {
var turkTitleCaseWords string
var CAPSlowerWords []string
var lowerCAPSWords []string
var lowerl33tWords []string
var l33tlowerWords []string
var CAPSl33tWords []string
var l33tCAPSWords []string
tick := false
titleCaseWords = cases.Title(language.Und, cases.NoLower).String(text)
turkTitleCaseWords = cases.Upper(language.Turkish, cases.NoLower).String(text)
Expand All @@ -1017,41 +1013,28 @@ func GeneratePassphrase(text string, n int) []string {
if tick {
CAPSlowerWords = append(CAPSlowerWords, strings.ToUpper(word))
lowerCAPSWords = append(lowerCAPSWords, strings.ToLower(word))
lowerl33tWords = append(lowerl33tWords, strings.ToLower(word))
l33tlowerWords = append(l33tlowerWords, strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(word, "a", "4"), "e", "3")))
CAPSl33tWords = append(CAPSl33tWords, strings.ToUpper(word))
l33tCAPSWords = append(l33tCAPSWords, strings.ReplaceAll(strings.ReplaceAll(word, "a", "4"), "e", "3"))
} else {
CAPSlowerWords = append(CAPSlowerWords, strings.ToLower(word))
lowerCAPSWords = append(lowerCAPSWords, strings.ToUpper(word))
lowerl33tWords = append(lowerl33tWords, strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(word, "a", "4"), "e", "3")))
l33tlowerWords = append(l33tlowerWords, strings.ToLower(word))
CAPSl33tWords = append(CAPSl33tWords, strings.ReplaceAll(strings.ReplaceAll(word, "a", "4"), "e", "3"))
l33tCAPSWords = append(l33tCAPSWords, strings.ToUpper(word))
}

tick = !tick

}
CAPSlowerPassphrase := strings.Join(CAPSlowerWords, "")
lowerCAPSPassphrase := strings.Join(lowerCAPSWords, "")
lowerl33tPassphrase := strings.Join(lowerl33tWords, "")
l33tlowerPassphrase := strings.Join(l33tlowerWords, "")
CAPSl33tPassphrase := strings.Join(CAPSl33tWords, "")
l33tCAPSPassphrase := strings.Join(l33tCAPSWords, "")

passphrases = append(passphrases, strings.ReplaceAll(titleCaseWords, " ", ""))
passphrases = append(passphrases, strings.ReplaceAll(turkTitleCaseWords, " ", ""))
passphrases = append(passphrases, strings.ReplaceAll(titleCaseWords, " ", "-"))
passphrases = append(passphrases, strings.ReplaceAll(turkTitleCaseWords, " ", "-"))
passphrases = append(passphrases, strings.ReplaceAll(titleCaseWords, " ", "_"))
passphrases = append(passphrases, strings.ReplaceAll(turkTitleCaseWords, " ", "_"))
passphrases = append(passphrases, CAPSlowerPassphrase)
passphrases = append(passphrases, lowerCAPSPassphrase)
passphrases = append(passphrases, lowerl33tPassphrase)
passphrases = append(passphrases, l33tlowerPassphrase)
passphrases = append(passphrases, CAPSl33tPassphrase)
passphrases = append(passphrases, l33tCAPSPassphrase)
passphrases = append(passphrases, strings.Join(CAPSlowerWords, " "))
passphrases = append(passphrases, strings.Join(CAPSlowerWords, ""))
passphrases = append(passphrases, strings.Join(lowerCAPSWords, " "))
passphrases = append(passphrases, strings.Join(lowerCAPSWords, ""))
passphrases = append(passphrases, strings.ReplaceAll(text, " ", ""))
passphrases = append(passphrases, titleCaseWords)
passphrases = append(passphrases, turkTitleCaseWords)

return passphrases
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ func TestGeneratePassphrase(t *testing.T) {

// Define test cases
testCases := TestCases{
{"I <3 you", 3, []string{"I<3you", "I<3YOU", "i<3you", "I<3YOU", "I<3You", "i<3you", "i<3you", "I<3YOU", "I-<3-You", "I-<3-YOU", "I_<3_YOU", "I_<3_You"}},
{"I <3 you", 3, []string{"I<3You", "I<3YOU", "I-<3-You", "I-<3-YOU", "I_<3_You", "I_<3_YOU", "i <3 you", "i<3you", "I <3 YOU", "I<3YOU", "I<3you", "I <3 You", "I <3 YOU"}},
}

// Run test cases
Expand Down

0 comments on commit 52f0630

Please sign in to comment.