在嵌套for循环中使用并发? (蛮力)

时间:2018-01-12 19:40:30

标签: loops go concurrency crypt

我正在调整我在课堂上制作的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个嵌套用于循环)。

1 个答案:

答案 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频道。

停止程序有点棘手。我们需要一个停止例程来等待所有消费者或破解密码。