Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make go run fast #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ We support various languages to help you solve the obnoxious PoW.
- [X] NodeJs
- [X] Browser-based
- [X] Ruby
- [X] Go (contributed by [Lee Xun](https://github.com/LeeXun))
- [X] Go (contributed by [Lee Xun](https://github.com/LeeXun), optimized by @RobinJadoul)
- [ ] Rust
- [ ] C/C++
- [ ] Java
Expand Down
75 changes: 24 additions & 51 deletions solver/go.go
Original file line number Diff line number Diff line change
@@ -1,68 +1,41 @@
package pow
package main

import (
"crypto/sha256"
"errors"
"fmt"
"os"
"strconv"
"encoding/binary"
"math/bits"
)

// Solver is a pow solver
type Solver struct {
SolverConfig
}

// SolverConfig is config struct for Solver
type SolverConfig struct {
Prefix string
Difficulty int
}

// New returns a POW solver
func New(c SolverConfig) (*Solver, error) {
if c.Difficulty <= 0 {
return nil, errors.New("Difficulty should > 0")
}
return &Solver{
SolverConfig{
Prefix: c.Prefix,
Difficulty: c.Difficulty,
},
}, nil
}

// Solve returns two fields,
// @ret1 the number of iteration after solving the pow.
// @ret2 binary form of the answer.
func (s *Solver) Solve() (attempts int, binaryString string) {
// Solve returns an integer, for which the decimal representation as a string is the solution to the PoW:
// binstr(sha256(prefix + str(i))).startswith("0"*difficulty)
// @arg prefix The prefix for hashing
// @arg difficulty The number of leading 0 bits wanted
// @ret The solution to the PoW.
func Solve(prefix string, difficulty int) int {
var i int
var ss string
for {
sum := sha256.Sum256([]byte(fmt.Sprintf("%s%v", s.Prefix, i)))
ss = toBinString(sum)
if isValid(ss, s.Difficulty) {
sum := sha256.Sum256([]byte(fmt.Sprintf("%s%v", prefix, i)))
if bits.LeadingZeros64(binary.BigEndian.Uint64(sum[:8])) >= difficulty {
break
}
i++
}
return i, ss
return i
}

func toBinString(s [sha256.Size]byte) string {
var ss string
for _, b := range s {
ss = fmt.Sprintf("%s%08b", ss, b)
func main() {
if len(os.Args) != 3 {
fmt.Printf("Usage: %s <prefix> <difficulty>\n", os.Args[0])
return
}
return ss
}

func isValid(ss string, d int) bool {
for i := range ss {
if i >= d {
break
}
if ss[i] != '0' {
return false
}
dif, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Printf("Difficulty is not a valid integer: %s\n", os.Args[2])
return
}
return true
i := Solve(os.Args[1], dif)
fmt.Println(i)
}