AJ ONeal
4 years ago
3 changed files with 180 additions and 0 deletions
@ -0,0 +1,144 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"os" |
||||
|
"strconv" |
||||
|
"time" |
||||
|
|
||||
|
"git.rootprojects.org/root/hashcash" |
||||
|
) |
||||
|
|
||||
|
func help() { |
||||
|
fmt.Println("Usage:") |
||||
|
fmt.Println("\thashcash new [subject *] [expires in 5m] [difficulty 10]") |
||||
|
fmt.Println("\thashcash parse <hashcash>") |
||||
|
fmt.Println("\thashcash solve <hashcash>") |
||||
|
fmt.Println("\thashcash verify <hashcash> [subject *]") |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
args := os.Args[:] |
||||
|
|
||||
|
if len(args) < 2 { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
switch args[1] { |
||||
|
case "new": |
||||
|
var subject string |
||||
|
if len(args) > 3 { |
||||
|
subject = args[2] |
||||
|
} |
||||
|
|
||||
|
var difficulty int |
||||
|
if len(args) > 4 { |
||||
|
var err error |
||||
|
difficulty, err = strconv.Atoi(args[3]) |
||||
|
if nil != err { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var expIn time.Duration |
||||
|
if len(args) > 5 { |
||||
|
var err error |
||||
|
expIn, err = time.ParseDuration(args[4]) |
||||
|
if nil != err { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
} |
||||
|
} else { |
||||
|
expIn = 5 * time.Minute |
||||
|
} |
||||
|
|
||||
|
h := hashcash.New(hashcash.Hashcash{ |
||||
|
Subject: subject, |
||||
|
Difficulty: difficulty, |
||||
|
ExpiresAt: time.Now().Add(expIn), |
||||
|
}) |
||||
|
|
||||
|
fmt.Println(h.String()) |
||||
|
return |
||||
|
case "parse": |
||||
|
var token string |
||||
|
if 3 != len(args) { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
token = args[2] |
||||
|
h, err := hashcash.Parse(token) |
||||
|
if nil != err { |
||||
|
fmt.Fprintf(os.Stderr, "%s\n", err) |
||||
|
return |
||||
|
} |
||||
|
b, _ := json.MarshalIndent(h, "", " ") |
||||
|
fmt.Println(string(b)) |
||||
|
return |
||||
|
case "solve": |
||||
|
var token string |
||||
|
if 3 != len(args) { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
token = args[2] |
||||
|
h, err := hashcash.Parse(token) |
||||
|
if nil != err { |
||||
|
fmt.Fprintf(os.Stderr, "%s\n", err) |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
err = h.Solve(22) |
||||
|
if nil != err { |
||||
|
fmt.Fprintf(os.Stderr, "%s\n", err) |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
fmt.Println(h.String()) |
||||
|
return |
||||
|
case "verify": |
||||
|
var token string |
||||
|
if len(args) < 3 { |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
return |
||||
|
} |
||||
|
token = args[2] |
||||
|
h, err := hashcash.Parse(token) |
||||
|
if nil != err { |
||||
|
fmt.Fprintf(os.Stderr, "%s\n", err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
subject := "*" |
||||
|
if len(args) > 3 { |
||||
|
subject = args[3] |
||||
|
} |
||||
|
|
||||
|
err = h.Verify(subject) |
||||
|
if nil != err { |
||||
|
fmt.Fprintf(os.Stderr, "%s\n", err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
var duration string |
||||
|
dur := h.ExpiresAt.Sub(time.Now()) |
||||
|
if dur > 365*24*time.Hour { |
||||
|
duration = "...a long, long time" |
||||
|
} else { |
||||
|
duration = dur.Truncate(time.Second).String() |
||||
|
} |
||||
|
fmt.Println("valid for", duration) |
||||
|
return |
||||
|
default: |
||||
|
help() |
||||
|
os.Exit(1) |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue