我正在调整我在课堂上制作的C程序中的代码&我试图将我用C编写的所有程序转换为Go以学习语言。我并不完全"得到"虽然并发。如何将并发应用于嵌套for循环?我程序的当前迭代是SLOW,比我用C编写的慢得多。
这是我的代码:
package main
import (
"fmt"
"os"
"unsafe"
)
// #cgo LDFLAGS: -lcrypt
// #define _GNU_SOURCE
// #include <crypt.h>
// #include <stdlib.h>
import "C"
// credit for this solution goes to https://stackoverflow.com/questions/14109915/what-is-gos-equivalent-to-pythons-crypt-crypt
// for showing that you can wrap go in C via CGO
// crypt wraps C library crypt_r
func crypt(key, salt string) string {
data := C.struct_crypt_data{}
ckey := C.CString(key)
csalt := C.CString(salt)
out := C.GoString(C.crypt_r(ckey, csalt, &data))
C.free(unsafe.Pointer(ckey))
C.free(unsafe.Pointer(csalt))
return out
}
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: ./cracker k")
return
}
cipher := os.Args[1]
var guess [5]byte
for i := 65; i < 123; i++ {
if i >= 91 && i <= 96 {
} else {
guess[0] = byte(i)
if cipher == crypt(string(guess[:1]), "50") {
fmt.Println(string(guess[:1]))
return
}
fmt.Println(string(guess[:1]))
for j := 65; j < 123; j++ {
if j >= 91 && j <= 96 {
} else {
guess[1] = byte(j)
if cipher == crypt(string(guess[:2]), "50") {
fmt.Println(string(guess[:2]))
return
}
fmt.Println(string(guess[:2]))
for k := 65; k < 123; k++ {
if k >= 91 && k <= 96 {
} else {
guess[2] = byte(k)
if cipher == crypt(string(guess[:3]), "50") {
fmt.Println(string(guess[:3]))
return
}
fmt.Println(string(guess[:3]))
for l := 65; l < 123; l++ {
if l >= 91 && l <= 96 {
} else {
guess[3] = byte(l)
if cipher == crypt(string(guess[:4]), "50") {
fmt.Println(string(guess[:4]))
return
}
fmt.Println(string(guess[:4]))
for m := 65; m < 123; m++ {
if m >= 91 && m <= 96 {
} else {
guess[4] = byte(m)
if cipher == crypt(string(guess[:5]), "50") {
fmt.Println(string(guess[:5]))
return
}
fmt.Println(string(guess[:5]))
}
}
}
}
}
}
}
}
}
}
}
该程序的目的是强制使用DES哈希,它可以处理长度最多为5个字符的任何密码(因此,5个嵌套用于循环)。
答案 0 :(得分:0)
我不会重写您的代码,但我可以为您提供示例解决方案,以便填写空白。
package main
import (
"fmt"
"runtime"
"sync"
)
func produce(in chan string) {
defer close(in)
for i := 0; i < 1000; i++ {
in <- fmt.Sprintf("%d", i)
}
}
func consume(in, out chan string, wg *sync.WaitGroup) {
defer wg.Done()
for s := range in {
if s == "500" {
out <- s
}
}
}
func stop(out chan string, wg *sync.WaitGroup) {
wg.Wait()
close(out)
}
func main() {
in, out := make(chan string), make(chan string)
wg := &sync.WaitGroup{}
go produce(in)
for i := 0; i < runtime.NumCPU(); i++ {
wg.Add(1)
go consume(in, out, wg)
}
go stop(out, wg)
fmt.Println(<-out)
}
这个想法是在生产者中生成密码提议,并将大量计算推向消费者。将有与CPU一样多的消费者。制作人通过关闭in
频道发出工作结束信号。消费者从in
频道中选择下一个密码提案并尝试计算哈希值。如果他们成功,他们会将密码放入out
频道。
停止程序有点棘手。我们需要一个停止例程来等待所有消费者或破解密码。