summaryrefslogtreecommitdiff
path: root/src/gobang.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gobang.go')
-rw-r--r--src/gobang.go207
1 files changed, 128 insertions, 79 deletions
diff --git a/src/gobang.go b/src/gobang.go
index 4ce13ff..4775dfc 100644
--- a/src/gobang.go
+++ b/src/gobang.go
@@ -19,19 +19,18 @@ import (
"strings"
"sync"
"syscall"
- "testing"
"time"
)
-type LogLevel int8
+type logLevel int8
const (
- LevelNone LogLevel = 0
- LevelError LogLevel = 1
- LevelWarning LogLevel = 2
- LevelInfo LogLevel = 3
- LevelDebug LogLevel = 4
+ LevelNone logLevel = 0
+ LevelError logLevel = 1
+ LevelWarning logLevel = 2
+ LevelInfo logLevel = 3
+ LevelDebug logLevel = 4
)
const lengthUUID = 16
@@ -52,7 +51,15 @@ type CopyResult struct {
-const MaxInt = int((^uint(0)) >> 1)
+const maxInt = int((^uint(0)) >> 1)
+
+const (
+ scrypt_N = 32768
+ scrypt_r = 8
+ scrypt_p = 1
+ scryptSaltMinLength = 32
+ scryptDesiredLength = 32
+)
@@ -62,14 +69,17 @@ const MaxInt = int((^uint(0)) >> 1)
//
// 52 bits of time in milliseconds since epoch
// 12 bits of (fractional nanoseconds) >> 8
+
var lastV7Time int64
-var timeMu sync.Mutex
+var timeMutex sync.Mutex
+
+
+// Local variables
-// Global variables
var (
- Level LogLevel = LevelInfo
- EmitMetric bool = true
- Hostname string
+ level logLevel = LevelInfo
+ emitMetric bool = true
+ hostname string
)
@@ -104,7 +114,7 @@ var (
//
// Using a higher iteration count will increase the cost of an exhaustive
// search but will also make derivation proportionally slower.
-func PBKDF2Key(
+func _PBKDF2Key(
password []byte,
salt []byte,
iter int,
@@ -127,7 +137,7 @@ func PBKDF2Key(
buf[0] = byte(block >> 24)
buf[1] = byte(block >> 16)
buf[2] = byte(block >> 8)
- buf[3] = byte(block)
+ buf[3] = byte(block >> 0)
prf.Write(buf[:4])
dk = prf.Sum(dk)
T := dk[len(dk) - hashLen:]
@@ -341,7 +351,7 @@ func smix(b []byte, r int, N int, v []uint32, xy []uint32) {
// and p=1. The parameters N, r, and p should be increased as memory latency and
// CPU parallelism increases; consider setting N to the highest power of 2 you
// can derive within 100 milliseconds. Remember to get a good random salt.
-func Scrypt(
+func scrypt(
password []byte,
salt []byte,
N int,
@@ -353,35 +363,35 @@ func Scrypt(
return nil, errors.New("scrypt: N must be > 1 and a power of 2")
}
if ((uint64(r) * uint64(p)) >= (1 << 30)) ||
- r > MaxInt / 128 / p ||
- r > MaxInt / 256 ||
- N > MaxInt / 128 / r {
+ r > maxInt / 128 / p ||
+ r > maxInt / 256 ||
+ N > maxInt / 128 / r {
return nil, errors.New("scrypt: parameters are too large")
}
xy := make([]uint32, 64 * r)
v := make([]uint32, 32 * N * r)
- b := PBKDF2Key(password, salt, 1, p * 128 * r, sha256.New)
+ b := _PBKDF2Key(password, salt, 1, p * 128 * r, sha256.New)
for i := 0; i < p; i++ {
smix(b[i * 128 * r:], r, N, v, xy)
}
- return PBKDF2Key(password, b, 1, keyLen, sha256.New), nil
+ return _PBKDF2Key(password, b, 1, keyLen, sha256.New), nil
}
-func CopyData(
- c chan CopyResult,
- label string,
- from io.Reader,
- to io.WriteCloser,
-) {
- written, err := io.Copy(to, from)
- c <- CopyResult {
- Written: written,
- Err: err,
- Label: label,
- }
+func Salt() []byte {
+ var buf [scryptSaltMinLength]byte
+ _, err := io.ReadFull(rand.Reader, buf[:])
+ FatalIf(err)
+ return buf[:]
+}
+
+func Hash(password []byte, salt []byte) []byte{
+ Assert(len(salt) >= scryptSaltMinLength, "salt is too small")
+ hash, err := scrypt(password, salt, scrypt_N, scrypt_r, scrypt_p, scryptDesiredLength)
+ FatalIf(err)
+ return hash
}
// FIXME: finish rewriting
@@ -397,8 +407,8 @@ func getV7Time(nano int64) (int64, int64) {
seq := (nano - (milli * nanoPerMilli)) >> 8
now := milli << (12 + seq)
- timeMu.Lock()
- defer timeMu.Unlock()
+ timeMutex.Lock()
+ defer timeMutex.Unlock()
if now <= lastV7Time {
now = lastV7Time + 1
milli = now >> 12
@@ -460,7 +470,7 @@ func (uuid UUID) ToString() string {
}
func Debug(message string, type_ string, args ...any) {
- if Level < LevelDebug {
+ if level < LevelDebug {
return
}
@@ -478,7 +488,7 @@ func Debug(message string, type_ string, args ...any) {
}
func Info(message string, type_ string, args ...any) {
- if Level < LevelInfo {
+ if level < LevelInfo {
return
}
@@ -496,7 +506,7 @@ func Info(message string, type_ string, args ...any) {
}
func Warning(message string, type_ string, args ...any) {
- if Level < LevelWarning {
+ if level < LevelWarning {
return
}
@@ -514,7 +524,7 @@ func Warning(message string, type_ string, args ...any) {
}
func Error(message string, type_ string, args ...any) {
- if Level < LevelError {
+ if level < LevelError {
return
}
@@ -532,7 +542,7 @@ func Error(message string, type_ string, args ...any) {
}
func Metric(type_ string, label string, args ...any) {
- if !EmitMetric {
+ if !emitMetric {
return
}
@@ -602,35 +612,69 @@ func MakeCounter(label string) func(...any) {
}
}
-func ErrorIf(t *testing.T, err error) {
+func ErrorIf(err error) {
if err != nil {
- t.Errorf("Unexpected error: %#v\n", err)
+ fmt.Fprintf(os.Stderr, "Unexpected error: %#v\n", err)
+ os.Exit(1)
}
}
-func ErrorNil(t *testing.T, err error) {
+func ErrorNil(err error) {
if err == nil {
- t.Errorf("Expected error, got nil\n")
+ fmt.Fprintf(os.Stderr, "Expected error, got nil\n")
+ os.Exit(1)
+ }
+}
+
+func showColour() bool {
+ return os.Getenv("NO_COLOUR") == ""
+}
+
+func TestStart(name string) {
+ fmt.Fprintf(os.Stderr, "%s:\n", name)
+}
+
+func Testing(message string, body func()) {
+ if showColour() {
+ fmt.Fprintf(os.Stderr, "\033[0;33mtesting\033[0m: %s... ", message)
+ body()
+ fmt.Fprint(os.Stderr, "\033[0;32mOK\033[0m.\n")
+ } else {
+ fmt.Fprintf(os.Stderr, "testing: %s...", message)
+ body()
+ fmt.Fprint(os.Stderr, " OK.\n")
}
}
-func AssertEqual(t *testing.T, given any, expected any) {
+func AssertEqual(given any, expected any) {
if !reflect.DeepEqual(given, expected) {
- t.Errorf("given != expected\n")
- t.Errorf("given: %#v\n", given)
- t.Errorf("expected: %#v\n", expected)
+ if showColour() {
+ fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n")
+ } else {
+ fmt.Fprintf(os.Stderr, "ERR.\n")
+ }
+ fmt.Fprintf(os.Stderr, "given != expected\n")
+ fmt.Fprintf(os.Stderr, "given: %#v\n", given)
+ fmt.Fprintf(os.Stderr, "expected: %#v\n", expected)
+ os.Exit(1)
}
}
-func AssertEqualI(t *testing.T, i int, given any, expected any) {
+func AssertEqualI(i int, given any, expected any) {
if !reflect.DeepEqual(given, expected) {
- t.Errorf("given != expected (i = %d)\n", i)
- t.Errorf("given: %#v\n", given)
- t.Errorf("expected: %#v\n", expected)
+ if showColour() {
+ fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n")
+ } else {
+ fmt.Fprintf(os.Stderr, "ERR.\n")
+ }
+ fmt.Fprintf(os.Stderr, "given != expected (i = %d)\n", i)
+ fmt.Fprintf(os.Stderr, "given: %#v\n", given)
+ fmt.Fprintf(os.Stderr, "expected: %#v\n", expected)
+ os.Exit(1)
}
}
-func SetLoggerOutput(w io.Writer) {
+func setLoggerOutput(w io.Writer) {
slog.SetDefault(slog.New(slog.NewJSONHandler(w, &slog.HandlerOptions {
AddSource: true,
})).With(
@@ -643,47 +687,47 @@ func SetLoggerOutput(w io.Writer) {
))
}
-func LevelFromString(name string) (bool, LogLevel) {
- level := strings.ToUpper(name)
+func levelFromString(name string) (bool, logLevel) {
+ label := strings.ToUpper(name)
- if level == "NONE" {
+ if label == "NONE" {
return true, LevelNone
}
- if level == "ERROR" {
+ if label == "ERROR" {
return true, LevelError
}
- if level == "WARNING" {
+ if label == "WARNING" {
return true, LevelWarning
}
- if level == "INFO" {
+ if label == "INFO" {
return true, LevelInfo
}
- if level == "DEBUG" {
+ if label == "DEBUG" {
return true, LevelDebug
}
- return false, Level
+ return false, level
}
-func SetLogLevel() {
- ok, level := LevelFromString(os.Getenv("LOG_LEVEL"))
+func setLogLevel() {
+ ok, envLevel := levelFromString(os.Getenv("LOG_LEVEL"))
if ok {
- Level = level
+ level = envLevel
}
}
-func SetMetric() {
+func setMetric() {
if os.Getenv("NO_METRIC") != "" {
- EmitMetric = false
+ emitMetric = false
}
}
-func SetTraceback() {
+func setTraceback() {
if os.Getenv("GOTRACEBACK") == "" {
debug.SetTraceback("crash")
}
@@ -705,21 +749,26 @@ func FatalIf(err error) {
}
}
-func SetHostname() {
- var err error
- Hostname, err = os.Hostname()
- FatalIf(err)
+func Assert(condition bool, message string) {
+ if !condition {
+ Fatal(errors.New(message))
+ }
}
-func Init() {
- SetLoggerOutput(os.Stdout)
- SetLogLevel()
- SetMetric()
- SetTraceback()
- SetHostname()
+func Unreachable() {
+ Assert(false, "Unreachable code was reached")
}
+func setHostname() {
+ var err error
+ hostname, err = os.Hostname()
+ FatalIf(err)
+}
-func Main() {
- fmt.Println(NewUUID().ToString())
+func Init() {
+ setLoggerOutput(os.Stdout)
+ setLogLevel()
+ setMetric()
+ setTraceback()
+ setHostname()
}