Compare commits
13 Commits
v1.3.0
...
7e826b75d7
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e826b75d7 | |||
| 72f4797428 | |||
| aad2144e7c | |||
| a1c8d6e531 | |||
| 0d5d7503ec | |||
| ee1a0fedcc | |||
| 3fc3f35bb5 | |||
| 9a98788476 | |||
| 43b8d3b618 | |||
| 6d1e700d8b | |||
| 1b2fcd72b9 | |||
| 6c20c7bb8b | |||
| f5289baecd |
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -14,8 +15,9 @@ import (
|
||||
var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?")
|
||||
|
||||
const (
|
||||
Version = "1.3.0"
|
||||
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
||||
Version = "1.3.3"
|
||||
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
||||
chunkSize = 16 // The size of each chunk of the password to be generated by the worker goroutines
|
||||
)
|
||||
|
||||
func matchArguments(args []string) string {
|
||||
@@ -26,11 +28,10 @@ func matchArguments(args []string) string {
|
||||
|
||||
// First argument is special, must be an integer, -v, or -h
|
||||
var size = 0 // Password length
|
||||
err := error(nil)
|
||||
if size, err = strconv.Atoi(args[0]); err == nil { // If first argument is an integer
|
||||
} else if args[0] == "-v" {
|
||||
switch args[0] {
|
||||
case "-v":
|
||||
return "GoPass version " + Version
|
||||
} else if args[0] == "-h" {
|
||||
case "-h":
|
||||
return "GoPass - A simple password generator written in Go\n" +
|
||||
"Usage: gopass [length] [disallowed characters] [optional remove symbols -s]\n" +
|
||||
" Example: gopass 16\n" +
|
||||
@@ -38,16 +39,23 @@ func matchArguments(args []string) string {
|
||||
" Example: gopass 16 -s\n" +
|
||||
"\nFor help (this output): gopass -h\n" +
|
||||
"For version: gopass -v\n"
|
||||
default:
|
||||
err := error(nil)
|
||||
size, err = strconv.Atoi(args[0])
|
||||
if err != nil {
|
||||
return "Invalid first argument (\"" + args[0] + "\") supplied! (Type gopass -h for help)"
|
||||
}
|
||||
}
|
||||
|
||||
for i := 1; i < len(args); i++ {
|
||||
v := args[i]
|
||||
if v == "-s" {
|
||||
switch {
|
||||
case v == "-s":
|
||||
removeDisallowed([]rune(symbols))
|
||||
} else if strings.HasPrefix(v, "-r=") { // If argument starts with -r=
|
||||
case strings.HasPrefix(v, "-r="):
|
||||
// Remove all characters after the = until next whitespace
|
||||
removeDisallowed([]rune(v[2:]))
|
||||
} else {
|
||||
default:
|
||||
return "Invalid argument (\"" + v + "\") supplied! (Type gopass -h for help)"
|
||||
}
|
||||
}
|
||||
@@ -61,28 +69,57 @@ func matchArguments(args []string) string {
|
||||
|
||||
// Remove all disallowed characters from the allowedCharacters slice
|
||||
func removeDisallowed(disallowed []rune) {
|
||||
disallowedMap := make(map[rune]bool, len(disallowed))
|
||||
for _, r := range disallowed {
|
||||
for i, v := range allowedCharacters {
|
||||
if v == r {
|
||||
allowedCharacters = append(allowedCharacters[:i], allowedCharacters[i+1:]...)
|
||||
}
|
||||
disallowedMap[r] = true
|
||||
}
|
||||
|
||||
i := 0
|
||||
for _, v := range allowedCharacters {
|
||||
if !disallowedMap[v] {
|
||||
allowedCharacters[i] = v
|
||||
i++
|
||||
}
|
||||
}
|
||||
allowedCharacters = allowedCharacters[:i]
|
||||
}
|
||||
|
||||
func generatePassword(size int) string {
|
||||
// Make empty array of runes with size of size
|
||||
pass := make([]rune, size)
|
||||
|
||||
// Assign every slot of pass to a random allowedCharacter
|
||||
for i := range pass {
|
||||
// Generate a random int greater than 0 and not to exceed the length of allowedCharacters
|
||||
index, err := rand.Int(rand.Reader, big.NewInt(int64(len(allowedCharacters))))
|
||||
if err != nil {
|
||||
println("Error securely generating random character!")
|
||||
return ""
|
||||
}
|
||||
pass[i] = allowedCharacters[index.Int64()]
|
||||
// Create a channel to receive chunks of the password
|
||||
passChan := make(chan []rune)
|
||||
|
||||
// Determine the number of worker goroutines to use
|
||||
numWorkers := runtime.NumCPU()
|
||||
|
||||
// Launch the worker goroutines
|
||||
for i := 0; i < numWorkers; i++ {
|
||||
go func() {
|
||||
allowedLen := len(allowedCharacters)
|
||||
for {
|
||||
// Generate a chunk of the password
|
||||
chunk := make([]rune, chunkSize)
|
||||
for i := range chunk {
|
||||
index, err := rand.Int(rand.Reader, big.NewInt(int64(allowedLen)))
|
||||
if err != nil {
|
||||
println("Error securely generating random character chunk!")
|
||||
return
|
||||
}
|
||||
chunk[i] = allowedCharacters[index.Int64()]
|
||||
}
|
||||
|
||||
// Send the chunk of the password to the main goroutine
|
||||
passChan <- chunk
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Collect the chunks of the password from the channel
|
||||
for i := 0; i < size; i += chunkSize {
|
||||
chunk := <-passChan
|
||||
copy(pass[i:], chunk)
|
||||
}
|
||||
|
||||
return string(pass)
|
||||
|
||||
Reference in New Issue
Block a user