Skip to content

Commit 289e03d

Browse files
v2023-03-15.0900; added stdout option + tweaks
v2023-03-15.0900-optimize; added "stdout", fixed "lines/sec" to show "M lines/sec", tweaked output buffer for stdout, tweaked sha2xxx flags to allow "shaxxx", ex: "sha512"
1 parent 846c5b3 commit 289e03d

File tree

1 file changed

+110
-100
lines changed

1 file changed

+110
-100
lines changed

hashgen.go

+110-100
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,25 @@ import (
99
"encoding/base64"
1010
"encoding/binary"
1111
"encoding/hex"
12-
"unicode/utf16"
1312
"flag"
1413
"fmt"
15-
"log"
16-
"hash"
17-
"os"
18-
"sync"
19-
"time"
20-
"hash/crc32"
21-
"hash/crc64"
22-
"strconv"
2314
"github.com/alexedwards/argon2id"
24-
"golang.org/x/crypto/md4"
2515
"golang.org/x/crypto/bcrypt"
16+
"golang.org/x/crypto/blake2b"
17+
"golang.org/x/crypto/blake2s"
18+
"golang.org/x/crypto/md4"
2619
"golang.org/x/crypto/ripemd160"
2720
"golang.org/x/crypto/sha3"
28-
"golang.org/x/crypto/blake2s"
29-
"golang.org/x/crypto/blake2b"
21+
"hash"
22+
"hash/crc32"
23+
"hash/crc64"
24+
"io"
25+
"log"
26+
"os"
27+
"strconv"
28+
"sync"
29+
"time"
30+
"unicode/utf16"
3031
)
3132

3233
// version history
@@ -38,50 +39,49 @@ import (
3839
// v2022-12-21.1400-goroutine; added multiple new algo's including hashcat mode equivalents
3940
// v2022-12-23.1200-goroutine; added argon2id (very slow), added sync / wait group for future use, change h/s readout from millions to thousands,
4041
// v2022-12-24.1800-optimize; optimized all hashing functions, tweaked buffer size
42+
// v2023-03-15.0900-optimize; added "stdout", fixed "lines/sec" to show "M lines/sec", tweaked output buffer for stdout, tweaked sha2xxx flags to allow "shaxxx", ex: "sha512"
4143

42-
// TODO:
44+
// TODO:
4345
// continue to add more hash functions
44-
// add "-o stdout" flag to print hashes to stdout
45-
// continue optimizing hash functions for better performance (ex: ntlm is currently slower than md5)
46+
// continue optimizing hash functions for better performance
4647
// fine tune goroutines for better performance with read --> hash function --> write
47-
// add feature to allow hash cracking in addition to hash generation (future program: hashgenie)
4848

4949
func versionFunc() {
50-
funcBase64Decode("Q3ljbG9uZSBoYXNoIGdlbmVyYXRvciB2MjAyMi0xMi0yNC4xODAwLW9wdGltaXplCg==")
50+
funcBase64Decode("Q3ljbG9uZSBoYXNoIGdlbmVyYXRvciB2MjAyMy0wMy0xNS4wOTAwLW9wdGltaXplCg==")
5151
}
5252

5353
// help function
5454
func helpFunc() {
55-
versionFunc()
56-
str := "Example Usage:\n"+
57-
"\n./hashgen -m md5 -w wordlist.txt -o output.txt\n"+
58-
"\nFunction: \t Hashcat Mode:\n"+
59-
"argon2id (very slow!)\n"+
60-
"base64encode\n"+
61-
"base64decode\n"+
62-
"bcrypt \t\t 3200\n"+
63-
"blake2s-256\n"+
64-
"blake2b-256\n"+
65-
"blake2b-384\n"+
66-
"blake2b-512 \t 600\n"+
67-
"crc32 \t\t 11500\n"+
68-
"crc64\n"+
69-
"md4 \t\t 900\n"+
70-
"md5 \t\t 0\n"+
71-
"ntlm \t\t 1000\n"+
72-
"plaintext \t 99999\n"+
73-
"ripemd-160 \t 6000\n"+
74-
"sha1 \t\t 100\n"+
75-
"sha2-224 \t 1300\n"+
76-
"sha2-384 \t 10800\n"+
77-
"sha2-256 \t 1400\n"+
78-
"sha2-512 \t 1700\n"+
79-
"sha2-512-224\n"+
80-
"sha2-512-256\n"+
81-
"sha3-224 \t 17300\n"+
82-
"sha3-256 \t 17400\n"+
83-
"sha3-384 \t 17400\n"+
84-
"sha3-512 \t 17400\n"
55+
versionFunc()
56+
str := "Example Usage:\n" +
57+
"\n./hashgen -m md5 -w wordlist.txt -o output.txt\n" +
58+
"\nFunction: \t Hashcat Mode:\n" +
59+
"argon2id (very slow!)\n" +
60+
"base64encode\n" +
61+
"base64decode\n" +
62+
"bcrypt \t\t 3200\n" +
63+
"blake2s-256\n" +
64+
"blake2b-256\n" +
65+
"blake2b-384\n" +
66+
"blake2b-512 \t 600\n" +
67+
"crc32 \t\t 11500\n" +
68+
"crc64\n" +
69+
"md4 \t\t 900\n" +
70+
"md5 \t\t 0\n" +
71+
"ntlm \t\t 1000\n" +
72+
"plaintext \t 99999\n" +
73+
"ripemd-160 \t 6000\n" +
74+
"sha1 \t\t 100\n" +
75+
"sha2-224 \t 1300\n" +
76+
"sha2-384 \t 10800\n" +
77+
"sha2-256 \t 1400\n" +
78+
"sha2-512 \t 1700\n" +
79+
"sha2-512-224\n" +
80+
"sha2-512-256\n" +
81+
"sha3-224 \t 17300\n" +
82+
"sha3-256 \t 17400\n" +
83+
"sha3-384 \t 17400\n" +
84+
"sha3-512 \t 17400\n"
8585
fmt.Println(str)
8686
os.Exit(0)
8787
}
@@ -93,40 +93,40 @@ func main() {
9393
var inputFile string
9494
flag.StringVar(&inputFile, "w", "", "Input file to process")
9595
var outputFile string
96-
flag.StringVar(&outputFile, "o", "", "Output file to write hashes to")
96+
flag.StringVar(&outputFile, "o", "stdout", "Output file to write hashes to (use 'stdout' to print to console)")
9797
version := flag.Bool("version", false, "Program version:")
98-
cyclone := flag.Bool("cyclone", false, "hashgen")
99-
help := flag.Bool("help", false, "Prints help:")
98+
cyclone := flag.Bool("cyclone", false, "hashgen")
99+
help := flag.Bool("help", false, "Prints help:")
100100
flag.Parse()
101101

102102
// run sanity checks for -version & -help
103-
if *version == true {
104-
versionFunc()
105-
os.Exit(0)
106-
} else if *cyclone == true {
107-
funcBase64Decode("Q29kZWQgYnkgY3ljbG9uZSA7KQo=")
108-
os.Exit(0)
109-
} else if *help == true {
110-
helpFunc()
111-
}
103+
if *version == true {
104+
versionFunc()
105+
os.Exit(0)
106+
} else if *cyclone == true {
107+
funcBase64Decode("Q29kZWQgYnkgY3ljbG9uZSA7KQo=")
108+
os.Exit(0)
109+
} else if *help == true {
110+
helpFunc()
111+
}
112112
// run sanity checks on algo input (-m)
113-
if len(hashFunc) < 1 {
114-
fmt.Println("--> missing '-m algo' <--\n")
115-
helpFunc()
116-
os.Exit(0)
117-
}
113+
if len(hashFunc) < 1 {
114+
fmt.Println("--> missing '-m algo' <--\n")
115+
helpFunc()
116+
os.Exit(0)
117+
}
118118
// run sanity checks on wordlist input (-w)
119-
if len(inputFile) < 1 {
120-
fmt.Println("--> missing '-w wordlist' <--\n")
121-
helpFunc()
122-
os.Exit(0)
123-
}
119+
if len(inputFile) < 1 {
120+
fmt.Println("--> missing '-w wordlist' <--\n")
121+
helpFunc()
122+
os.Exit(0)
123+
}
124124
// run sanity checks on output (-o)
125-
if len(outputFile) < 1 {
126-
fmt.Println("--> missing '-o filename' <--\n")
127-
helpFunc()
128-
os.Exit(0)
129-
}
125+
if len(outputFile) < 1 {
126+
fmt.Println("--> missing '-o filename' <--\n")
127+
helpFunc()
128+
os.Exit(0)
129+
}
130130
// open input file
131131
input, err := os.Open(inputFile)
132132
if err != nil {
@@ -135,12 +135,19 @@ func main() {
135135
}
136136
defer input.Close()
137137
// open output file
138-
output, err := os.Create(outputFile)
139-
if err != nil {
140-
fmt.Printf("--> Error opening output file: %v <--\n", err)
141-
os.Exit(1)
138+
var output io.Writer
139+
if outputFile == "stdout" {
140+
output = os.Stdout
141+
} else {
142+
file, err := os.Create(outputFile)
143+
if err != nil {
144+
fmt.Printf("--> Error opening output file: %v <--\n", err)
145+
os.Exit(1)
146+
}
147+
defer file.Close()
148+
output = file
142149
}
143-
defer output.Close()
150+
144151
// create hash functions from flag -m
145152
var h hash.Hash
146153
switch hashFunc {
@@ -152,17 +159,17 @@ func main() {
152159
h = md4.New()
153160
case "sha1", "100":
154161
h = sha1.New()
155-
case "sha2-224", "sha2_224", "sha2224", "1300":
162+
case "sha2-224", "sha2_224", "sha2224", "sha224", "1300":
156163
hashFunc = "sha2-224"
157-
case "sha2-384", "sha2_384", "sha2384","10800":
164+
case "sha2-384", "sha2_384", "sha2384", "sha384", "10800":
158165
hashFunc = "sha2-384"
159-
case "sha2-256", "sha2_256", "sha2256", "1400":
166+
case "sha2-256", "sha2_256", "sha2256", "sha256", "1400":
160167
h = sha256.New()
161-
case "sha2-512", "sha2_512", "sha2512", "1700":
168+
case "sha2-512", "sha2_512", "sha2512", "sha512", "1700":
162169
h = sha512.New()
163-
case "sha2-512-224", "sha2_512_224", "sha2512224":
170+
case "sha2-512-224", "sha2_512_224", "sha2512224", "sha512224":
164171
h = sha512.New512_224()
165-
case "sha2-512-256", "sha2_512_256" , "sha2512256":
172+
case "sha2-512-256", "sha2_512_256", "sha2512256", "sha512256":
166173
h = sha512.New512_256()
167174
case "ripemd-160", "ripemd_160", "ripemd160", "6000":
168175
h = ripemd160.New()
@@ -199,26 +206,26 @@ func main() {
199206
default:
200207
fmt.Printf("--> Invalid hash function: %s <--\n", hashFunc)
201208
helpFunc()
202-
os.Exit(0)
209+
os.Exit(0)
203210
}
204-
211+
205212
// create read / write buffers
206213
// input buffer
207214
inputBuffer := bufio.NewScanner(input)
208-
// set buffer capacity to 10mb
209-
const maxCapacity = 10*1024*1024
215+
// set input buffer
216+
const maxCapacity = 10 * 1024 * 1024
210217
buf := make([]byte, maxCapacity)
211218
inputBuffer.Buffer(buf, maxCapacity)
212-
// set output buffer to 100mb
213-
outputBuffer := bufio.NewWriterSize(output, 100*1024*1024)
219+
// set output buffer
220+
outputBuffer := bufio.NewWriterSize(output, 10*1024*1024)
214221

215222
// create buffered channels to receive lines <-- not currently emplimented
216223
//lines := make(chan string, 10*1024*1024)
217224
//linesHash := make(chan string, 10*1024*1024)
218225

219226
// create WaitGroup to wait for goroutines to finish
220227
var wg sync.WaitGroup
221-
228+
222229
// create goroutine bool channel
223230
done := make(chan bool)
224231
// start hashgen goroutine
@@ -325,7 +332,7 @@ func main() {
325332
hashString := strconv.FormatUint(hash, 16)
326333
outputBuffer.WriteString(hashString + "\n")
327334
linesHashed++
328-
}
335+
}
329336
} else if hashFunc == "base64encode" {
330337
// base64encode
331338
for inputBuffer.Scan() {
@@ -392,8 +399,9 @@ func main() {
392399
}
393400
}
394401
elapsedTime := time.Since(startTime)
395-
linesPerSecond := float64(linesHashed) / elapsedTime.Seconds() *0.001 // convert to thousand hashes per second
396-
log.Printf("Finished hashing %d lines in %v (%.3f lines/sec)\n", linesHashed, elapsedTime, linesPerSecond)
402+
runTime := float64(elapsedTime.Seconds())
403+
linesPerSecond := float64(linesHashed) / elapsedTime.Seconds() * 0.000001 // convert to thousand hashes per second
404+
log.Printf("Finished hashing %d lines in %.3f sec (%.3f M lines/sec)\n", linesHashed, runTime, linesPerSecond)
397405
done <- true
398406
}()
399407

@@ -409,10 +417,12 @@ func main() {
409417

410418
// base64 decode function used for displaying encoded messages
411419
func funcBase64Decode(line string) {
412-
str, err := base64.StdEncoding.DecodeString(line)
413-
if err != nil {
420+
str, err := base64.StdEncoding.DecodeString(line)
421+
if err != nil {
414422
log.Println("--> Text doesn't appear to be base64 encoded. <--")
415-
os.Exit(0)
416-
}
417-
fmt.Printf("%s\n", str)
423+
os.Exit(0)
424+
}
425+
fmt.Printf("%s\n", str)
418426
}
427+
428+
// end code

0 commit comments

Comments
 (0)