LoginSignup
14
12

More than 5 years have passed since last update.

「数字6桁パスワードのMD5ハッシュ値の総当たり」をGolangでやってみた

Last updated at Posted at 2014-09-25

今更だけど qiita でたまたま目についたので Golang ではどんなものなのかやってみた。
他の言語についてはここから参照されたし。

実行環境

OS: Ubuntu 14.04 LTS
CPU: Intel(R) Core(TM) i7-4510U CPU @ 2.00GHz
言語: go version go1.3 linux/amd64

ソースコード

まずは愚直にやってみたバージョン。
他の言語と比べてもかなりシンプルな方ですね。

bruteforce.go
package main

import (
    "crypto/md5"
    "fmt"
    "os"
    "bytes"
    "encoding/hex"
)

const NUMMAX = 1000000

func main() {
    pw, _ := hex.DecodeString(os.Args[2])

    for i := 0; i < NUMMAX; i++ {
        sum := md5.Sum([]byte(fmt.Sprintf("%s$%06d", os.Args[1], i)))
        if bytes.Equal(pw, sum[:]) {
            fmt.Printf("Solved: %06d\n", i)
            return
        }
    }
}

実行結果

shell
$ time go run bruteforce.go hoge 4b364677946ccf79f841114e73ccaf4f
Solved: 567890

real    0m0.566s
user    0m0.540s
sys 0m0.027s

なんとコンパイル込みで約0.56秒でした。
この時点で結構早かったので高速化する気が一気に失せました。。。

ちなみにコンパイルして実行した結果は以下の通り。

shell
$ go build bruteforce.go
$ time ./bruteforce hoge 4b364677946ccf79f841114e73ccaf4f
Solved: 567890

real    0m0.445s
user    0m0.434s
sys 0m0.012s

コンパイルにかかっている時間は0.1秒のようです。
普段Scala使ってるとこのコンパイル速度は驚異的ですね!

続いて、皆さん並列実行版も計測してらっしゃるので、Goroutine版も用意しました。
並列化してもコードはシンプルでいいですね!

bruteforce2.go
package main

import (
    "crypto/md5"
    "fmt"
    "os"
    "bytes"
    "encoding/hex"
    "runtime"
    "sync"
)

const NUMMAX = 1000000

func main() {
    numCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(numCPU)
    pw, _ := hex.DecodeString(os.Args[2])
    var wg sync.WaitGroup
    var once sync.Once
    wg.Add(1)

    for i := 0; i < numCPU; i++ {
        go func(start, step int) {
            defer once.Do(wg.Done)
            for j := start; j < NUMMAX; j += step {
                sum := md5.Sum([]byte(fmt.Sprintf("%s$%06d", os.Args[1], j)))
                if bytes.Equal(pw, sum[:]) {
                    fmt.Printf("Solved: %06d\n", j)
                    return
                }
            }
        }(i, numCPU)
    }

    wg.Wait()
}

実行結果

shell
$ go build bruteforce2.go
$ time ./bruteforce2 hoge 4b364677946ccf79f841114e73ccaf4f
Solved: 567890

real    0m0.256s
user    0m0.812s
sys 0m0.028s

0.25秒でした。
個人的にはもっと速度出てほしかったですけど、十分かな?
Ultrabookでこの速度なので、デスクトップとか4コアとかのCPUだともっと早いと思う。

まとめ

Golang で書いたコードは速いし書くのは簡単だし、オススメ

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12