Files
charon/main.go
T

108 lines
2.5 KiB
Go

package main
import (
"crypto"
_ "crypto/sha1"
"encoding/hex"
"fmt"
"math/rand"
"time"
)
func main() {
g := Generator{
Difficulty: 26,
}
c := g.RandomChallenge()
fmt.Println(c.String())
fmt.Println(c.Solve().String())
}
type Challenge struct {
Input [48]byte
Date [20]byte
Difficulty byte
Solution int64
}
type Generator struct {
Difficulty byte
}
func (g *Generator) RandomChallenge() Challenge {
bytes := make([]byte, 48)
for i, _ := range bytes {
bytes[i] = byte(rand.Int())
}
today := time.Now().UTC()
date := today.Format("2006-01-02")
hash := crypto.SHA1.New().Sum([]byte(date))
return Challenge{
Input: [48]byte(bytes),
Date: [20]byte(hash),
Difficulty: g.Difficulty,
}
}
// using a lookup table for this is super goofy but i'm lazy and it's 6am
var prefixLookup = []int{
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
}
func (c Challenge) Solve() Challenge {
bytes := make([]byte, 76)
bytes = append(bytes, c.Input[:]...)
bytes = append(bytes, c.Date[:]...)
for {
for i := range 8 {
bytes[75-i] = byte(c.Solution >> (i * 8))
}
sum := make([]byte, 20)
hash := crypto.SHA1.New()
hash.Write(bytes)
sum = hash.Sum(nil)
count := 0
for _, c := range sum {
p := prefixLookup[c]
count += p
if p != 8 {
break
}
}
if c.Solution%20000000 == 0 {
println(c.Solution)
}
if count >= int(c.Difficulty) {
println(c.Solution)
break
}
c.Solution++
}
return c
}
func (c Challenge) String() string {
bytes := make([]byte, 0)
bytes = append(bytes, c.Input[:]...)
bytes = append(bytes, c.Date[:]...)
bytes = append(bytes, make([]byte, 8)...)
bytes[68] = c.Difficulty
for i := range 7 {
bytes[75-i] = byte(c.Solution >> (i * 8))
}
return hex.EncodeToString(bytes)
}