diff options
Diffstat (limited to 'src/gobang.go')
-rw-r--r-- | src/gobang.go | 143 |
1 files changed, 97 insertions, 46 deletions
diff --git a/src/gobang.go b/src/gobang.go index 4775dfc..dc0d9bc 100644 --- a/src/gobang.go +++ b/src/gobang.go @@ -33,9 +33,14 @@ const ( LevelDebug logLevel = 4 ) -const lengthUUID = 16 + +const ( + uuidDashCount = 4 + uuidByteCount = 16 + uuidEncodedLength = (uuidByteCount * 2) + uuidDashCount +) type UUID struct { - bytes [lengthUUID]byte + bytes [uuidByteCount]byte } type Gauge struct { @@ -54,7 +59,7 @@ type CopyResult struct { const maxInt = int((^uint(0)) >> 1) const ( - scrypt_N = 32768 + scrypt_N = 1 << 15 scrypt_r = 8 scrypt_p = 1 scryptSaltMinLength = 32 @@ -62,7 +67,6 @@ const ( ) - // Private variables // lastV7time is the last time we returned stored as: @@ -125,7 +129,7 @@ func _PBKDF2Key( hashLen := prf.Size() numBlocks := (keyLen + hashLen - 1) / hashLen - var buf [4]byte + var buffer [4]byte dk := make([]byte, 0, numBlocks*hashLen) U := make([]byte, hashLen) for block := 1; block <= numBlocks; block++ { @@ -134,11 +138,11 @@ func _PBKDF2Key( // U_1 = PRF(password, salt || uint(i)) prf.Reset() prf.Write(salt) - buf[0] = byte(block >> 24) - buf[1] = byte(block >> 16) - buf[2] = byte(block >> 8) - buf[3] = byte(block >> 0) - prf.Write(buf[:4]) + buffer[0] = byte(block >> 24) + buffer[1] = byte(block >> 16) + buffer[2] = byte(block >> 8) + buffer[3] = byte(block >> 0) + prf.Write(buffer[:4]) dk = prf.Sum(dk) T := dk[len(dk) - hashLen:] copy(U, T) @@ -380,16 +384,27 @@ func scrypt( return _PBKDF2Key(password, b, 1, keyLen, sha256.New), nil } -func Salt() []byte { - var buf [scryptSaltMinLength]byte - _, err := io.ReadFull(rand.Reader, buf[:]) +func Random(length int) []byte { + buffer := make([]byte, length) + _, err := io.ReadFull(rand.Reader, buffer) FatalIf(err) - return buf[:] + return buffer +} + +func Salt() []byte { + return Random(scryptSaltMinLength) } 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) + hash, err := scrypt( + password, + salt, + scrypt_N, + scrypt_r, + scrypt_p, + scryptDesiredLength, + ) FatalIf(err) return hash } @@ -410,42 +425,43 @@ func getV7Time(nano int64) (int64, int64) { timeMutex.Lock() defer timeMutex.Unlock() if now <= lastV7Time { - now = lastV7Time + 1 + now = lastV7Time + 1 milli = now >> 12 - seq = now & 0xfff + seq = now & 0xfff } lastV7Time = now return milli, seq } -func NewUUID() UUID { - var buf [lengthUUID]byte - _, err := io.ReadFull(rand.Reader, buf[7:]) - if err != nil { - panic(err) - } +func newUUIDFrom(randomBuffer [uuidByteCount]byte, now int64) UUID { + randomBuffer[6] = (randomBuffer[6] & 0x0f) | 0x40 // Version 4 + randomBuffer[8] = (randomBuffer[8] & 0x3f) | 0x80 // Variant is 10 - buf[6] = (buf[6] & 0x0f) | 0x40 // Version 4 - buf[8] = (buf[8] & 0x3f) | 0x80 // Variant is 10 + t, s := getV7Time(now) - t, s := getV7Time(time.Now().UnixNano()) + randomBuffer[0] = byte(t >> 40) + randomBuffer[1] = byte(t >> 32) + randomBuffer[2] = byte(t >> 24) + randomBuffer[3] = byte(t >> 16) + randomBuffer[4] = byte(t >> 8) + randomBuffer[5] = byte(t >> 0) - buf[0] = byte(t >> 40) - buf[1] = byte(t >> 32) - buf[2] = byte(t >> 24) - buf[3] = byte(t >> 16) - buf[4] = byte(t >> 8) - buf[5] = byte(t >> 0) + randomBuffer[6] = 0x70 | (0x0f & byte(s >> 8)) + randomBuffer[7] = byte(s) + return UUID { bytes: randomBuffer } +} + +func NewUUID() UUID { + var buffer [uuidByteCount]byte + _, err := io.ReadFull(rand.Reader, buffer[7:]) + FatalIf(err) - buf[6] = 0x70 | (0x0f & byte(s >> 8)) - buf[7] = byte(s) - return UUID { bytes: buf } + now := time.Now().UnixNano() + return newUUIDFrom(buffer, now) } -func (uuid UUID) ToString() string { - const dashCount = 4 - const encodedLength = (lengthUUID * 2) + dashCount - dst := [encodedLength]byte { +func (uuid UUID) String() string { + dst := [uuidEncodedLength]byte { 0, 0, 0, 0, 0, 0, 0, 0, '-', @@ -469,6 +485,37 @@ func (uuid UUID) ToString() string { return string(dst[:]) } +var ( + dashIndexes = []int { 8, 13, 18, 23 } + emptyUUID = UUID {} + badUUIDLengthError = errors.New("str isn't of the correct length") + badUUIDDashCountError = errors.New("Bad count of dashes in string") + badUUIDDashPositionError = errors.New("Bad char in string") +) +func ParseUUID(str string) (UUID, error) { + if len(str) != uuidEncodedLength { + return emptyUUID, badUUIDLengthError + } + + if strings.Count(str, "-") != uuidDashCount { + return emptyUUID, badUUIDDashCountError + } + + for _, idx := range dashIndexes { + if str[idx] != '-' { + return emptyUUID, badUUIDDashPositionError + } + } + + hexstr := strings.Join(strings.Split(str, "-"), "") + data, err := hex.DecodeString(hexstr) + if err != nil { + return emptyUUID, err + } + + return UUID { bytes: [uuidByteCount]byte(data) }, nil +} + func Debug(message string, type_ string, args ...any) { if level < LevelDebug { return @@ -478,7 +525,7 @@ func Debug(message string, type_ string, args ...any) { message, append( []any { - "id", NewUUID().ToString(), + "id", NewUUID(), "kind", "log", "type", type_, }, @@ -496,7 +543,7 @@ func Info(message string, type_ string, args ...any) { message, append( []any { - "id", NewUUID().ToString(), + "id", NewUUID(), "kind", "log", "type", type_, }, @@ -514,7 +561,7 @@ func Warning(message string, type_ string, args ...any) { message, append( []any { - "id", NewUUID().ToString(), + "id", NewUUID(), "kind", "log", "type", type_, }, @@ -532,7 +579,7 @@ func Error(message string, type_ string, args ...any) { message, append( []any { - "id", NewUUID().ToString(), + "id", NewUUID(), "kind", "log", "type", type_, }, @@ -550,7 +597,7 @@ func Metric(type_ string, label string, args ...any) { "_", append( []any { - "id", NewUUID().ToString(), + "id", NewUUID(), "kind", "metric", "type", type_, "label", label, @@ -636,7 +683,11 @@ func TestStart(name string) { func Testing(message string, body func()) { if showColour() { - fmt.Fprintf(os.Stderr, "\033[0;33mtesting\033[0m: %s... ", message) + fmt.Fprintf( + os.Stderr, + "\033[0;33mtesting\033[0m: %s... ", + message, + ) body() fmt.Fprint(os.Stderr, "\033[0;32mOK\033[0m.\n") } else { @@ -682,7 +733,7 @@ func setLoggerOutput(w io.Writer) { "info", "pid", os.Getpid(), "ppid", os.Getppid(), - "puuid", NewUUID().ToString(), + "puuid", NewUUID(), ), )) } |