diff --git a/docs/advanced/scraper_deterrence.md b/docs/advanced/scraper_deterrence.md index 0ec9f0724..e20e3f6c6 100644 --- a/docs/advanced/scraper_deterrence.md +++ b/docs/advanced/scraper_deterrence.md @@ -1,9 +1,9 @@ # Scraper Deterrence GoToSocial provides an optional proof-of-work based scraper and automated HTTP client deterrence that can be enabled on profile and status web views. The way -it works is that it generates a unique but deterministic challenge for each incoming HTTP request based on client information and current time, that-is a hex encoded SHA256 hash, and asks the client to find an addition to a portion of this that will generate a hex encoded SHA256 hash with a pre-determined number of leading '0' characters. This is served to the client as a minimal holding page with a single JavaScript worker that computes a solution to this. +it works is that it generates a unique but deterministic challenge for each incoming HTTP request based on client information and current time, that-is a hex encoded SHA256 hash. It then asks the client to find an integer addition to a portion of this that will generate an expected encoded hash result. This is served to the client as a minimal holding page with a single JavaScript worker that computes a solution to this. -The number of required leading '0' characters can be configured to your liking, where higher values take longer to solve, and lower values take less. But this is not exact, as the challenges themselves are random, so you can only effect the **average amount of time** it may take. If your challenges take too long to solve, you may deter users from accessing your web pages. And conversely, the longer it takes for a solution to be found, the more you'll be incurring costs for scrapers (and in some cases, causing their operation to time-out). That balance is up to you to configure, hence why this is an advanced feature. +The number of hash encode rounds the client is required to complete may be configured, where high values will take the client longer to find a solution and vice-versa. We also instill a certain amount of jitter to make it harder for scrapers to "game" the algorithm. If your challenges take too long to solve, you may deter users from accessing your web pages. And conversely, the longer it takes for a solution to be found, the more you'll be incurring costs for scrapers (and in some cases, causing their operation to time-out). That balance is up to you to configure, hence why this is an advanced feature. Once a solution to this challenge has been provided, by refreshing the page with the solution in the query parameter, GoToSocial will verify this solution and on success will return the expected profile / status page with a cookie that provides challenge-less access to the instance for up-to the next hour. diff --git a/example/config.yaml b/example/config.yaml index 2026f1a15..b41c0b06f 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -1307,10 +1307,9 @@ advanced-header-filter-mode: "" advanced-scraper-deterrence-enabled: false # Uint. Allows tweaking the difficulty of the proof-of-work algorithm -# used in the scraper deterrence. This determines how many leading '0' -# characters are required to be generated in each solution. Higher -# values will on-average take longer to find solutions for, and the -# inverse is also true. +# used in the scraper deterrence. This determines roughly how many hash +# encode rounds we require the client to complete to find a solution. +# Higher values will take longer to find solutions for, and vice-versa. # # The downside is that if your deterrence takes too long to solve, # it may deter some users from viewing your web status / profile page. @@ -1321,6 +1320,6 @@ advanced-scraper-deterrence-enabled: false # For more details please check the documentation at: # https://docs.gotosocial.org/en/latest/advanced/scraper_deterrence # -# Examples: [3, 4, 5] -# Default: 4 -advanced-scraper-deterrence-difficulty: 4 +# Examples: [50000, 100000, 500000] +# Default: 100000 +advanced-scraper-deterrence-difficulty: 100000 diff --git a/go.mod b/go.mod index 13851d066..a1fdd8847 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( code.superseriousbusiness.org/exif-terminator v0.11.0 code.superseriousbusiness.org/httpsig v1.4.0 code.superseriousbusiness.org/oauth2/v4 v4.8.0 + codeberg.org/gruf/go-bitutil v1.1.0 codeberg.org/gruf/go-bytesize v1.0.3 codeberg.org/gruf/go-byteutil v1.3.0 codeberg.org/gruf/go-cache/v3 v3.6.1 diff --git a/go.sum b/go.sum index 7c60aa200..132586b68 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ code.superseriousbusiness.org/httpsig v1.4.0 h1:g9+KQMoTG0oR0II5gYb5pVVdNjbc7Cii code.superseriousbusiness.org/httpsig v1.4.0/go.mod h1:i2AKpj/WbA/o/UTvia9TAREzt0jP1AH3T1Uxjyhdzlw= code.superseriousbusiness.org/oauth2/v4 v4.8.0 h1:4LVXoPJXKgmDfwDegzBQPNpsdleMaL6YmDgFi6UDgEE= code.superseriousbusiness.org/oauth2/v4 v4.8.0/go.mod h1:+RLRBXPkjP/VhIC/46dcZkx3t5IvBSJYOjVCPgeWors= +codeberg.org/gruf/go-bitutil v1.1.0 h1:U1Q+A1mtnPk+npqYrlRBc9ar2C5hYiBd17l1Wrp2Bt8= +codeberg.org/gruf/go-bitutil v1.1.0/go.mod h1:rGibFevYTQfYKcPv0Df5KpG8n5xC3AfD4d/UgYeoNy0= codeberg.org/gruf/go-bytesize v1.0.3 h1:Tz8tCxhPLeyM5VryuBNjUHgKmLj4Bx9RbPaUSA3qg6g= codeberg.org/gruf/go-bytesize v1.0.3/go.mod h1:n/GU8HzL9f3UNp/mUKyr1qVmTlj7+xacpp0OHfkvLPs= codeberg.org/gruf/go-byteutil v1.3.0 h1:nRqJnCcRQ7xbfU6azw7zOzJrSMDIJHBqX6FL9vEMYmU= diff --git a/internal/config/config.go b/internal/config/config.go index 5b8da9703..f051ab005 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -280,6 +280,6 @@ type ThrottlingConfig struct { } type ScraperDeterrenceConfig struct { - Enabled bool `name:"enabled" usage:"Enable proof-of-work based scraper deterrence on profile / status pages"` - Difficulty uint8 `name:"difficulty" usage:"The proof-of-work difficulty, which determines how many leading zeros to try solve in hash solutions."` + Enabled bool `name:"enabled" usage:"Enable proof-of-work based scraper deterrence on profile / status pages"` + Difficulty uint32 `name:"difficulty" usage:"The proof-of-work difficulty, which determines roughly how many hash-encode rounds required of each client."` } diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 8372e4b00..ad124e90f 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -149,7 +149,7 @@ var Defaults = Configuration{ ScraperDeterrence: ScraperDeterrenceConfig{ Enabled: false, - Difficulty: 4, + Difficulty: 100000, }, }, diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go index 269aa7abc..38f33c67e 100644 --- a/internal/config/helpers.gen.go +++ b/internal/config/helpers.gen.go @@ -144,7 +144,7 @@ func (cfg *Configuration) RegisterFlags(flags *pflag.FlagSet) { flags.Int("advanced-throttling-multiplier", cfg.Advanced.Throttling.Multiplier, "Multiplier to use per cpu for http request throttling. 0 or less turns throttling off.") flags.Duration("advanced-throttling-retry-after", cfg.Advanced.Throttling.RetryAfter, "Retry-After duration response to send for throttled requests.") flags.Bool("advanced-scraper-deterrence-enabled", cfg.Advanced.ScraperDeterrence.Enabled, "Enable proof-of-work based scraper deterrence on profile / status pages") - flags.Uint8("advanced-scraper-deterrence-difficulty", cfg.Advanced.ScraperDeterrence.Difficulty, "The proof-of-work difficulty, which determines how many leading zeros to try solve in hash solutions.") + flags.Uint32("advanced-scraper-deterrence-difficulty", cfg.Advanced.ScraperDeterrence.Difficulty, "The proof-of-work difficulty, which determines how many leading zeros to try solve in hash solutions.") flags.StringSlice("http-client-allow-ips", cfg.HTTPClient.AllowIPs, "") flags.StringSlice("http-client-block-ips", cfg.HTTPClient.BlockIPs, "") flags.Duration("http-client-timeout", cfg.HTTPClient.Timeout, "") @@ -1356,9 +1356,9 @@ func (cfg *Configuration) UnmarshalMap(cfgmap map[string]any) error { if ival, ok := cfgmap["advanced-scraper-deterrence-difficulty"]; ok { var err error - cfg.Advanced.ScraperDeterrence.Difficulty, err = cast.ToUint8E(ival) + cfg.Advanced.ScraperDeterrence.Difficulty, err = cast.ToUint32E(ival) if err != nil { - return fmt.Errorf("error casting %#v -> uint8 for 'advanced-scraper-deterrence-difficulty': %w", ival, err) + return fmt.Errorf("error casting %#v -> uint32 for 'advanced-scraper-deterrence-difficulty': %w", ival, err) } } @@ -4799,7 +4799,7 @@ func AdvancedScraperDeterrenceDifficultyFlag() string { } // GetAdvancedScraperDeterrenceDifficulty safely fetches the Configuration value for state's 'Advanced.ScraperDeterrence.Difficulty' field -func (st *ConfigState) GetAdvancedScraperDeterrenceDifficulty() (v uint8) { +func (st *ConfigState) GetAdvancedScraperDeterrenceDifficulty() (v uint32) { st.mutex.RLock() v = st.config.Advanced.ScraperDeterrence.Difficulty st.mutex.RUnlock() @@ -4807,7 +4807,7 @@ func (st *ConfigState) GetAdvancedScraperDeterrenceDifficulty() (v uint8) { } // SetAdvancedScraperDeterrenceDifficulty safely sets the Configuration value for state's 'Advanced.ScraperDeterrence.Difficulty' field -func (st *ConfigState) SetAdvancedScraperDeterrenceDifficulty(v uint8) { +func (st *ConfigState) SetAdvancedScraperDeterrenceDifficulty(v uint32) { st.mutex.Lock() defer st.mutex.Unlock() st.config.Advanced.ScraperDeterrence.Difficulty = v @@ -4815,12 +4815,12 @@ func (st *ConfigState) SetAdvancedScraperDeterrenceDifficulty(v uint8) { } // GetAdvancedScraperDeterrenceDifficulty safely fetches the value for global configuration 'Advanced.ScraperDeterrence.Difficulty' field -func GetAdvancedScraperDeterrenceDifficulty() uint8 { +func GetAdvancedScraperDeterrenceDifficulty() uint32 { return global.GetAdvancedScraperDeterrenceDifficulty() } // SetAdvancedScraperDeterrenceDifficulty safely sets the value for global configuration 'Advanced.ScraperDeterrence.Difficulty' field -func SetAdvancedScraperDeterrenceDifficulty(v uint8) { +func SetAdvancedScraperDeterrenceDifficulty(v uint32) { global.SetAdvancedScraperDeterrenceDifficulty(v) } diff --git a/internal/middleware/nollamas.go b/internal/middleware/nollamas.go index 914469a24..6191ebe3b 100644 --- a/internal/middleware/nollamas.go +++ b/internal/middleware/nollamas.go @@ -26,6 +26,7 @@ import ( "hash" "io" "net/http" + "strconv" "time" apimodel "code.superseriousbusiness.org/gotosocial/internal/api/model" @@ -35,6 +36,7 @@ import ( "code.superseriousbusiness.org/gotosocial/internal/gtserror" "code.superseriousbusiness.org/gotosocial/internal/log" "code.superseriousbusiness.org/gotosocial/internal/oauth" + "codeberg.org/gruf/go-bitutil" "codeberg.org/gruf/go-byteutil" "github.com/gin-gonic/gin" ) @@ -60,49 +62,79 @@ func NoLLaMas( return func(*gin.Context) {} } - seed := make([]byte, 32) + var seed [32]byte // Read random data for the token seed. - _, err := io.ReadFull(rand.Reader, seed) + _, err := io.ReadFull(rand.Reader, seed[:]) if err != nil { panic(err) } // Configure nollamas. var nollamas nollamas - nollamas.seed = seed + nollamas.entropy = seed nollamas.ttl = time.Hour - nollamas.diff = config.GetAdvancedScraperDeterrenceDifficulty() + nollamas.rounds = config.GetAdvancedScraperDeterrenceDifficulty() nollamas.getInstanceV1 = getInstanceV1 nollamas.policy = cookiePolicy return nollamas.Serve } +// i.e. hash slice length. +const hashLen = sha256.Size + +// i.e. hex.EncodedLen(hashLen). +const encodedHashLen = 2 * hashLen + // hashWithBufs encompasses a hash along // with the necessary buffers to generate // a hashsum and then encode that sum. type hashWithBufs struct { hash hash.Hash - hbuf []byte - ebuf []byte + hbuf [hashLen]byte + ebuf [encodedHashLen]byte +} + +// write is a passthrough to hash.Hash{}.Write(). +func (h *hashWithBufs) write(b []byte) { + _, _ = h.hash.Write(b) +} + +// writeString is a passthrough to hash.Hash{}.Write([]byte(s)). +func (h *hashWithBufs) writeString(s string) { + _, _ = h.hash.Write(byteutil.S2B(s)) +} + +// EncodedSum returns the hex encoded sum of hash.Sum(). +func (h *hashWithBufs) EncodedSum() string { + _ = h.hash.Sum(h.hbuf[:0]) + hex.Encode(h.ebuf[:], h.hbuf[:]) + return string(h.ebuf[:]) +} + +// Reset will reset hash and buffers. +func (h *hashWithBufs) Reset() { + h.ebuf = [encodedHashLen]byte{} + h.hbuf = [hashLen]byte{} + h.hash.Reset() } type nollamas struct { // our instance cookie policy. policy apiutil.CookiePolicy - // unique token seed + // unique entropy // to prevent hashes // being guessable - seed []byte + entropy [32]byte // success cookie TTL ttl time.Duration - // algorithm difficulty knobs. - // diff determines the number - // of leading zeroes required. - diff uint8 + // rounds determines roughly how + // many hash-encode rounds each + // client is required to complete. + rounds uint32 // extra fields required for // our template rendering. @@ -134,18 +166,8 @@ func (m *nollamas) Serve(c *gin.Context) { return } - // i.e. outputted hash slice length. - const hashLen = sha256.Size - - // i.e. hex.EncodedLen(hashLen). - const encodedHashLen = 2 * hashLen - - // Prepare hash + buffers. - hash := hashWithBufs{ - hash: sha256.New(), - hbuf: make([]byte, 0, hashLen), - ebuf: make([]byte, encodedHashLen), - } + // Prepare new hash with buffers. + hash := hashWithBufs{hash: sha256.New()} // Extract client fingerprint data. userAgent := c.GetHeader("User-Agent") @@ -153,15 +175,7 @@ func (m *nollamas) Serve(c *gin.Context) { // Generate a unique token for this request, // only valid for a period of now +- m.ttl. - token := m.token(&hash, userAgent, clientIP) - - // For unique challenge string just use a - // single portion of their 'success' token. - // SHA256 is not yet cracked, this is not an - // application of a hash requiring serious - // cryptographic security and it rotates on - // a TTL basis, so it should be fine. - challenge := token[:len(token)/4] + token := m.getToken(&hash, userAgent, clientIP) // Check for a provided success token. cookie, _ := c.Cookie("gts-nollamas") @@ -169,8 +183,8 @@ func (m *nollamas) Serve(c *gin.Context) { // Check whether passed cookie // is the expected success token. if subtle.ConstantTimeCompare( - byteutil.S2B(token), byteutil.S2B(cookie), + byteutil.S2B(token), ) == 1 { // They passed us a valid, expected @@ -185,10 +199,15 @@ func (m *nollamas) Serve(c *gin.Context) { // handlers from being called. c.Abort() + // Generate challenge for this unique (yet deterministic) token, + // returning seed, wanted 'challenge' result and expected solution. + seed, challenge, solution := m.getChallenge(&hash, token) + // Prepare new log entry. l := log.WithContext(ctx). WithField("userAgent", userAgent). - WithField("challenge", challenge) + WithField("seed", seed). + WithField("rounds", solution) // Extract and parse query. query := c.Request.URL.Query() @@ -196,32 +215,28 @@ func (m *nollamas) Serve(c *gin.Context) { // Check query to see if an in-progress // challenge solution has been provided. nonce := query.Get("nollamas_solution") - if nonce == "" || len(nonce) > 20 { + if nonce == "" { - // noting that here, 20 is - // max integer string len. - // - // An invalid solution string, just - // present them with new challenge. + // No solution given, likely new client! + // Simply present them with challenge. + m.renderChallenge(c, seed, challenge) l.Info("posing new challenge") - m.renderChallenge(c, challenge) return } - // Reset the hash. - hash.hash.Reset() + // Check nonce matches expected. + if subtle.ConstantTimeCompare( + byteutil.S2B(solution), + byteutil.S2B(nonce), + ) != 1 { - // Check challenge+nonce as possible solution. - if !m.checkChallenge(&hash, challenge, nonce) { - - // They failed challenge, - // re-present challenge page. - l.Info("invalid solution provided") - m.renderChallenge(c, challenge) + // Their nonce failed, re-challenge them. + m.renderChallenge(c, challenge, solution) + l.Infof("invalid solution provided: %s", nonce) return } - l.Infof("challenge passed: %s", nonce) + l.Info("challenge passed") // Drop solution query and encode. query.Del("nollamas_solution") @@ -233,7 +248,7 @@ func (m *nollamas) Serve(c *gin.Context) { c.Redirect(http.StatusTemporaryRedirect, c.Request.URL.RequestURI()) } -func (m *nollamas) renderChallenge(c *gin.Context, challenge string) { +func (m *nollamas) renderChallenge(c *gin.Context, seed, challenge string) { // Fetch current instance information for templating vars. instance, errWithCode := m.getInstanceV1(c.Request.Context()) if errWithCode != nil { @@ -252,8 +267,8 @@ func (m *nollamas) renderChallenge(c *gin.Context, challenge string) { "/assets/Fork-Awesome/css/fork-awesome.min.css", }, Extra: map[string]any{ - "challenge": challenge, - "difficulty": m.diff, + "seed": seed, + "challenge": challenge, }, Javascript: []apiutil.JavascriptEntry{ { @@ -264,23 +279,25 @@ func (m *nollamas) renderChallenge(c *gin.Context, challenge string) { }) } -func (m *nollamas) token(hash *hashWithBufs, userAgent, clientIP string) string { - // Use our unique seed to seed hash, +// getToken generates a unique yet deterministic token for given HTTP request +// details, seeded by runtime generated entropy data and ttl rounded timestamp. +func (m *nollamas) getToken(hash *hashWithBufs, userAgent, clientIP string) string { + + // Reset before + // using hash. + hash.Reset() + + // Use our unique entropy to seed hash, // to ensure we have cryptographically // unique, yet deterministic, tokens // generated for a given http client. - hash.hash.Write(m.seed) - - // Include difficulty level in - // hash input data so if config - // changes then token invalidates. - hash.hash.Write([]byte{m.diff}) + hash.write(m.entropy[:]) // Also seed the generated input with // current time rounded to TTL, so our // single comparison handles expiries. now := time.Now().Round(m.ttl).Unix() - hash.hash.Write([]byte{ + hash.write([]byte{ byte(now >> 56), byte(now >> 48), byte(now >> 40), @@ -291,37 +308,78 @@ func (m *nollamas) token(hash *hashWithBufs, userAgent, clientIP string) string byte(now), }) - // Finally, append unique client request data. - hash.hash.Write(byteutil.S2B(userAgent)) - hash.hash.Write(byteutil.S2B(clientIP)) + // Append client request data. + hash.writeString(userAgent) + hash.writeString(clientIP) - // Return hex encoded hash output. - hash.hbuf = hash.hash.Sum(hash.hbuf[:0]) - hex.Encode(hash.ebuf, hash.hbuf) - return string(hash.ebuf) + // Return hex encoded hash. + return hash.EncodedSum() } -func (m *nollamas) checkChallenge(hash *hashWithBufs, challenge, nonce string) bool { - // Hash and encode input challenge with - // proposed nonce as a possible solution. - hash.hash.Write(byteutil.S2B(challenge)) - hash.hash.Write(byteutil.S2B(nonce)) - hash.hbuf = hash.hash.Sum(hash.hbuf[:0]) - hex.Encode(hash.ebuf, hash.hbuf) - solution := hash.ebuf +// getChallenge prepares a new challenge given the deterministic input token for this request. +// it will return an input seed string, a challenge string which is the end result the client +// should be looking for, and the solution for this such that challenge = hex(sha256(seed + solution)). +// the solution will always be a string-encoded 64bit integer calculated from m.rounds + random jitter. +func (m *nollamas) getChallenge(hash *hashWithBufs, token string) (seed, challenge, solution string) { - // Compiler bound-check hint. - if len(solution) < int(m.diff) { - panic(gtserror.New("BCE")) + // For their unique seed string just use a + // single portion of their 'success' token. + // SHA256 is not yet cracked, this is not an + // application of a hash requiring serious + // cryptographic security and it rotates on + // a TTL basis, so it should be fine. + seed = token[:len(token)/4] + + // BEFORE resetting the hash, get the last + // two bytes of NON-hex-encoded data from + // token generation to use for random jitter. + // This is taken from the end of the hash as + // this is the "unseen" end part of token. + // + // (if we used hex-encoded data it would + // only ever be '0-9' or 'a-z' ASCII chars). + // + // Security-wise, same applies as-above. + jitter := int16(hash.hbuf[len(hash.hbuf)-2]) | + int16(hash.hbuf[len(hash.hbuf)-1])<<8 + + var rounds int64 + switch { + // For some small percentage of + // clients we purposely low-ball + // their rounds required, to make + // it so gaming it with a starting + // nonce value may suddenly fail. + case jitter%37 == 0: + rounds = int64(m.rounds/10) + int64(jitter/10) + case jitter%31 == 0: + rounds = int64(m.rounds/5) + int64(jitter/5) + case jitter%29 == 0: + rounds = int64(m.rounds/3) + int64(jitter/3) + case jitter%13 == 0: + rounds = int64(m.rounds/2) + int64(jitter/2) + + // Determine an appropriate number of hash rounds + // we want the client to perform on input seed. This + // is determined as configured m.rounds +- jitter. + // This will be the 'solution' to create 'challenge'. + default: + rounds = int64(m.rounds) + int64(jitter) //nolint:gosec } - // Check that the first 'diff' - // many chars are indeed zeroes. - for i := range m.diff { - if solution[i] != '0' { - return false - } - } + // Encode (positive) determined hash rounds as string. + solution = strconv.FormatInt(bitutil.Abs64(rounds), 10) - return true + // Reset before + // using hash. + hash.Reset() + + // Calculate the expected result + // of hex(sha256(seed + solution)), + // i.e. the proposed 'challenge'. + hash.writeString(seed) + hash.writeString(solution) + challenge = hash.EncodedSum() + + return } diff --git a/internal/middleware/nollamas_test.go b/internal/middleware/nollamas_test.go index ffe8cbbc8..f6b8e0e02 100644 --- a/internal/middleware/nollamas_test.go +++ b/internal/middleware/nollamas_test.go @@ -95,41 +95,39 @@ func testNoLLaMasMiddleware(t *testing.T, e *gin.Engine, userAgent string) { panic(err) } + var seed string var challenge string - var difficulty uint64 // Parse output body and find the challenge / difficulty. for _, line := range strings.Split(string(b), "\n") { line = strings.TrimSpace(line) switch { + case strings.HasPrefix(line, "data-nollamas-seed=\""): + line = line[20:] + line = line[:len(line)-1] + seed = line case strings.HasPrefix(line, "data-nollamas-challenge=\""): line = line[25:] line = line[:len(line)-1] challenge = line - case strings.HasPrefix(line, "data-nollamas-difficulty=\""): - line = line[26:] - line = line[:len(line)-1] - var err error - difficulty, err = strconv.ParseUint(line, 10, 8) - assert.NoError(t, err) } } // Ensure valid posed challenge. - assert.NotZero(t, difficulty) assert.NotEmpty(t, challenge) + assert.NotEmpty(t, seed) // Prepare a test request for gin engine. r = httptest.NewRequest("GET", "/", nil) r.Header.Set("User-Agent", userAgent) rw = httptest.NewRecorder() - // Now compute and set solution query paramater. - solution := computeSolution(challenge, difficulty) - r.URL.RawQuery = "nollamas_solution=" + solution - + t.Logf("seed=%s", seed) t.Logf("challenge=%s", challenge) - t.Logf("difficulty=%d", difficulty) + + // Now compute and set solution query paramater. + solution := computeSolution(seed, challenge) + r.URL.RawQuery = "nollamas_solution=" + solution t.Logf("solution=%s", solution) // Pass req through @@ -152,17 +150,14 @@ func testNoLLaMasMiddleware(t *testing.T, e *gin.Engine, userAgent string) { } // computeSolution does the functional equivalent of our nollamas workerTask.js. -func computeSolution(challenge string, diff uint64) string { -outer: +func computeSolution(seed, challenge string) string { for i := 0; ; i++ { solution := strconv.Itoa(i) - combined := challenge + solution + combined := seed + solution hash := sha256.Sum256(byteutil.S2B(combined)) encoded := hex.EncodeToString(hash[:]) - for i := range diff { - if encoded[i] != '0' { - continue outer - } + if encoded != challenge { + continue } return solution } diff --git a/test/envparsing.sh b/test/envparsing.sh index f6a6dcc9a..4fe13b6ac 100755 --- a/test/envparsing.sh +++ b/test/envparsing.sh @@ -20,7 +20,7 @@ EXPECT=$(cat << "EOF" "127.0.0.1/32" ], "advanced-rate-limit-requests": 6969, - "advanced-scraper-deterrence-difficulty": 5, + "advanced-scraper-deterrence-difficulty": 500000, "advanced-scraper-deterrence-enabled": true, "advanced-sender-multiplier": -1, "advanced-throttling-multiplier": -1, @@ -309,7 +309,7 @@ GTS_SYSLOG_ADDRESS='127.0.0.1:6969' \ GTS_ADVANCED_COOKIES_SAMESITE='strict' \ GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS="192.0.2.0/24,127.0.0.1/32" \ GTS_ADVANCED_RATE_LIMIT_REQUESTS=6969 \ -GTS_ADVANCED_SCRAPER_DETERRENCE_DIFFICULTY=5 \ +GTS_ADVANCED_SCRAPER_DETERRENCE_DIFFICULTY=500000 \ GTS_ADVANCED_SCRAPER_DETERRENCE_ENABLED=true \ GTS_ADVANCED_SENDER_MULTIPLIER=-1 \ GTS_ADVANCED_THROTTLING_MULTIPLIER=-1 \ diff --git a/testrig/config.go b/testrig/config.go index 558e5a54c..e7a594996 100644 --- a/testrig/config.go +++ b/testrig/config.go @@ -178,7 +178,7 @@ func testDefaults() config.Configuration { ScraperDeterrence: config.ScraperDeterrenceConfig{ Enabled: envBool("GTS_ADVANCED_SCRAPER_DETERRENCE_ENABLED", false), - Difficulty: uint8(envInt("GTS_ADVANCED_SCRAPER_DETERRENCE_DIFFICULTY", 4)), //nolint + Difficulty: uint32(envInt("GTS_ADVANCED_SCRAPER_DETERRENCE_DIFFICULTY", 100000)), //nolint }, }, diff --git a/vendor/codeberg.org/gruf/go-bitutil/LICENSE b/vendor/codeberg.org/gruf/go-bitutil/LICENSE new file mode 100644 index 000000000..e4163ae35 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2022 gruf + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/codeberg.org/gruf/go-bitutil/README.md b/vendor/codeberg.org/gruf/go-bitutil/README.md new file mode 100644 index 000000000..a71c1aa0b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/README.md @@ -0,0 +1,3 @@ +# go-bitutil + +This library provides helpful methods and types for performing typical bitwise operations on integers, e.g. packing/unpacking, bit flags. \ No newline at end of file diff --git a/vendor/codeberg.org/gruf/go-bitutil/abs.go b/vendor/codeberg.org/gruf/go-bitutil/abs.go new file mode 100644 index 000000000..f4ce8ad75 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/abs.go @@ -0,0 +1,29 @@ +package bitutil + +// Abs8 returns the absolute value of i (calculated without branching). +func Abs8(i int8) int8 { + const bits = 8 + u := uint64(i >> (bits - 1)) + return (i ^ int8(u)) + int8(u&1) +} + +// Abs16 returns the absolute value of i (calculated without branching). +func Abs16(i int16) int16 { + const bits = 16 + u := uint64(i >> (bits - 1)) + return (i ^ int16(u)) + int16(u&1) +} + +// Abs32 returns the absolute value of i (calculated without branching). +func Abs32(i int32) int32 { + const bits = 32 + u := uint64(i >> (bits - 1)) + return (i ^ int32(u)) + int32(u&1) +} + +// Abs64 returns the absolute value of i (calculated without branching). +func Abs64(i int64) int64 { + const bits = 64 + u := uint64(i >> (bits - 1)) + return (i ^ int64(u)) + int64(u&1) +} diff --git a/vendor/codeberg.org/gruf/go-bitutil/flag.go b/vendor/codeberg.org/gruf/go-bitutil/flag.go new file mode 100644 index 000000000..6a5b20d11 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/flag.go @@ -0,0 +1,3744 @@ +package bitutil + +import ( + "unsafe" +) + +// Flags8 is a type-casted unsigned integer with helper +// methods for easily managing up to 8 bit-flags. +type Flags8 uint8 + +// Get will fetch the flag bit value at index 'bit'. +func (f Flags8) Get(bit uint8) bool { + mask := Flags8(1) << bit + return (f&mask != 0) +} + +// Set will set the flag bit value at index 'bit'. +func (f Flags8) Set(bit uint8) Flags8 { + mask := Flags8(1) << bit + return f | mask +} + +// Unset will unset the flag bit value at index 'bit'. +func (f Flags8) Unset(bit uint8) Flags8 { + mask := Flags8(1) << bit + return f & ^mask +} + +// Get0 will fetch the flag bit value at index 0. +func (f Flags8) Get0() bool { + const mask = Flags8(1) << 0 + return (f&mask != 0) +} + +// Set0 will set the flag bit value at index 0. +func (f Flags8) Set0() Flags8 { + const mask = Flags8(1) << 0 + return f | mask +} + +// Unset0 will unset the flag bit value at index 0. +func (f Flags8) Unset0() Flags8 { + const mask = Flags8(1) << 0 + return f & ^mask +} + +// Get1 will fetch the flag bit value at index 1. +func (f Flags8) Get1() bool { + const mask = Flags8(1) << 1 + return (f&mask != 0) +} + +// Set1 will set the flag bit value at index 1. +func (f Flags8) Set1() Flags8 { + const mask = Flags8(1) << 1 + return f | mask +} + +// Unset1 will unset the flag bit value at index 1. +func (f Flags8) Unset1() Flags8 { + const mask = Flags8(1) << 1 + return f & ^mask +} + +// Get2 will fetch the flag bit value at index 2. +func (f Flags8) Get2() bool { + const mask = Flags8(1) << 2 + return (f&mask != 0) +} + +// Set2 will set the flag bit value at index 2. +func (f Flags8) Set2() Flags8 { + const mask = Flags8(1) << 2 + return f | mask +} + +// Unset2 will unset the flag bit value at index 2. +func (f Flags8) Unset2() Flags8 { + const mask = Flags8(1) << 2 + return f & ^mask +} + +// Get3 will fetch the flag bit value at index 3. +func (f Flags8) Get3() bool { + const mask = Flags8(1) << 3 + return (f&mask != 0) +} + +// Set3 will set the flag bit value at index 3. +func (f Flags8) Set3() Flags8 { + const mask = Flags8(1) << 3 + return f | mask +} + +// Unset3 will unset the flag bit value at index 3. +func (f Flags8) Unset3() Flags8 { + const mask = Flags8(1) << 3 + return f & ^mask +} + +// Get4 will fetch the flag bit value at index 4. +func (f Flags8) Get4() bool { + const mask = Flags8(1) << 4 + return (f&mask != 0) +} + +// Set4 will set the flag bit value at index 4. +func (f Flags8) Set4() Flags8 { + const mask = Flags8(1) << 4 + return f | mask +} + +// Unset4 will unset the flag bit value at index 4. +func (f Flags8) Unset4() Flags8 { + const mask = Flags8(1) << 4 + return f & ^mask +} + +// Get5 will fetch the flag bit value at index 5. +func (f Flags8) Get5() bool { + const mask = Flags8(1) << 5 + return (f&mask != 0) +} + +// Set5 will set the flag bit value at index 5. +func (f Flags8) Set5() Flags8 { + const mask = Flags8(1) << 5 + return f | mask +} + +// Unset5 will unset the flag bit value at index 5. +func (f Flags8) Unset5() Flags8 { + const mask = Flags8(1) << 5 + return f & ^mask +} + +// Get6 will fetch the flag bit value at index 6. +func (f Flags8) Get6() bool { + const mask = Flags8(1) << 6 + return (f&mask != 0) +} + +// Set6 will set the flag bit value at index 6. +func (f Flags8) Set6() Flags8 { + const mask = Flags8(1) << 6 + return f | mask +} + +// Unset6 will unset the flag bit value at index 6. +func (f Flags8) Unset6() Flags8 { + const mask = Flags8(1) << 6 + return f & ^mask +} + +// Get7 will fetch the flag bit value at index 7. +func (f Flags8) Get7() bool { + const mask = Flags8(1) << 7 + return (f&mask != 0) +} + +// Set7 will set the flag bit value at index 7. +func (f Flags8) Set7() Flags8 { + const mask = Flags8(1) << 7 + return f | mask +} + +// Unset7 will unset the flag bit value at index 7. +func (f Flags8) Unset7() Flags8 { + const mask = Flags8(1) << 7 + return f & ^mask +} + +// String returns a human readable representation of Flags8. +func (f Flags8) String() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = 1 + (len("false ") * 8) - 1 + 1 + buf = make([]byte, prealloc) + + buf[i] = '{' + i++ + + val = f.Get0() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// GoString returns a more verbose human readable representation of Flags8. +func (f Flags8) GoString() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = len("bitutil.Flags8{") + (len("7=false ") * 8) - 1 + 1 + buf = make([]byte, prealloc) + + i += copy(buf[i:], "bitutil.Flags8{") + + val = f.Get0() + i += copy(buf[i:], "0=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], "1=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], "2=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], "3=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], "4=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], "5=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], "6=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], "7=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// Flags16 is a type-casted unsigned integer with helper +// methods for easily managing up to 16 bit-flags. +type Flags16 uint16 + +// Get will fetch the flag bit value at index 'bit'. +func (f Flags16) Get(bit uint8) bool { + mask := Flags16(1) << bit + return (f&mask != 0) +} + +// Set will set the flag bit value at index 'bit'. +func (f Flags16) Set(bit uint8) Flags16 { + mask := Flags16(1) << bit + return f | mask +} + +// Unset will unset the flag bit value at index 'bit'. +func (f Flags16) Unset(bit uint8) Flags16 { + mask := Flags16(1) << bit + return f & ^mask +} + +// Get0 will fetch the flag bit value at index 0. +func (f Flags16) Get0() bool { + const mask = Flags16(1) << 0 + return (f&mask != 0) +} + +// Set0 will set the flag bit value at index 0. +func (f Flags16) Set0() Flags16 { + const mask = Flags16(1) << 0 + return f | mask +} + +// Unset0 will unset the flag bit value at index 0. +func (f Flags16) Unset0() Flags16 { + const mask = Flags16(1) << 0 + return f & ^mask +} + +// Get1 will fetch the flag bit value at index 1. +func (f Flags16) Get1() bool { + const mask = Flags16(1) << 1 + return (f&mask != 0) +} + +// Set1 will set the flag bit value at index 1. +func (f Flags16) Set1() Flags16 { + const mask = Flags16(1) << 1 + return f | mask +} + +// Unset1 will unset the flag bit value at index 1. +func (f Flags16) Unset1() Flags16 { + const mask = Flags16(1) << 1 + return f & ^mask +} + +// Get2 will fetch the flag bit value at index 2. +func (f Flags16) Get2() bool { + const mask = Flags16(1) << 2 + return (f&mask != 0) +} + +// Set2 will set the flag bit value at index 2. +func (f Flags16) Set2() Flags16 { + const mask = Flags16(1) << 2 + return f | mask +} + +// Unset2 will unset the flag bit value at index 2. +func (f Flags16) Unset2() Flags16 { + const mask = Flags16(1) << 2 + return f & ^mask +} + +// Get3 will fetch the flag bit value at index 3. +func (f Flags16) Get3() bool { + const mask = Flags16(1) << 3 + return (f&mask != 0) +} + +// Set3 will set the flag bit value at index 3. +func (f Flags16) Set3() Flags16 { + const mask = Flags16(1) << 3 + return f | mask +} + +// Unset3 will unset the flag bit value at index 3. +func (f Flags16) Unset3() Flags16 { + const mask = Flags16(1) << 3 + return f & ^mask +} + +// Get4 will fetch the flag bit value at index 4. +func (f Flags16) Get4() bool { + const mask = Flags16(1) << 4 + return (f&mask != 0) +} + +// Set4 will set the flag bit value at index 4. +func (f Flags16) Set4() Flags16 { + const mask = Flags16(1) << 4 + return f | mask +} + +// Unset4 will unset the flag bit value at index 4. +func (f Flags16) Unset4() Flags16 { + const mask = Flags16(1) << 4 + return f & ^mask +} + +// Get5 will fetch the flag bit value at index 5. +func (f Flags16) Get5() bool { + const mask = Flags16(1) << 5 + return (f&mask != 0) +} + +// Set5 will set the flag bit value at index 5. +func (f Flags16) Set5() Flags16 { + const mask = Flags16(1) << 5 + return f | mask +} + +// Unset5 will unset the flag bit value at index 5. +func (f Flags16) Unset5() Flags16 { + const mask = Flags16(1) << 5 + return f & ^mask +} + +// Get6 will fetch the flag bit value at index 6. +func (f Flags16) Get6() bool { + const mask = Flags16(1) << 6 + return (f&mask != 0) +} + +// Set6 will set the flag bit value at index 6. +func (f Flags16) Set6() Flags16 { + const mask = Flags16(1) << 6 + return f | mask +} + +// Unset6 will unset the flag bit value at index 6. +func (f Flags16) Unset6() Flags16 { + const mask = Flags16(1) << 6 + return f & ^mask +} + +// Get7 will fetch the flag bit value at index 7. +func (f Flags16) Get7() bool { + const mask = Flags16(1) << 7 + return (f&mask != 0) +} + +// Set7 will set the flag bit value at index 7. +func (f Flags16) Set7() Flags16 { + const mask = Flags16(1) << 7 + return f | mask +} + +// Unset7 will unset the flag bit value at index 7. +func (f Flags16) Unset7() Flags16 { + const mask = Flags16(1) << 7 + return f & ^mask +} + +// Get8 will fetch the flag bit value at index 8. +func (f Flags16) Get8() bool { + const mask = Flags16(1) << 8 + return (f&mask != 0) +} + +// Set8 will set the flag bit value at index 8. +func (f Flags16) Set8() Flags16 { + const mask = Flags16(1) << 8 + return f | mask +} + +// Unset8 will unset the flag bit value at index 8. +func (f Flags16) Unset8() Flags16 { + const mask = Flags16(1) << 8 + return f & ^mask +} + +// Get9 will fetch the flag bit value at index 9. +func (f Flags16) Get9() bool { + const mask = Flags16(1) << 9 + return (f&mask != 0) +} + +// Set9 will set the flag bit value at index 9. +func (f Flags16) Set9() Flags16 { + const mask = Flags16(1) << 9 + return f | mask +} + +// Unset9 will unset the flag bit value at index 9. +func (f Flags16) Unset9() Flags16 { + const mask = Flags16(1) << 9 + return f & ^mask +} + +// Get10 will fetch the flag bit value at index 10. +func (f Flags16) Get10() bool { + const mask = Flags16(1) << 10 + return (f&mask != 0) +} + +// Set10 will set the flag bit value at index 10. +func (f Flags16) Set10() Flags16 { + const mask = Flags16(1) << 10 + return f | mask +} + +// Unset10 will unset the flag bit value at index 10. +func (f Flags16) Unset10() Flags16 { + const mask = Flags16(1) << 10 + return f & ^mask +} + +// Get11 will fetch the flag bit value at index 11. +func (f Flags16) Get11() bool { + const mask = Flags16(1) << 11 + return (f&mask != 0) +} + +// Set11 will set the flag bit value at index 11. +func (f Flags16) Set11() Flags16 { + const mask = Flags16(1) << 11 + return f | mask +} + +// Unset11 will unset the flag bit value at index 11. +func (f Flags16) Unset11() Flags16 { + const mask = Flags16(1) << 11 + return f & ^mask +} + +// Get12 will fetch the flag bit value at index 12. +func (f Flags16) Get12() bool { + const mask = Flags16(1) << 12 + return (f&mask != 0) +} + +// Set12 will set the flag bit value at index 12. +func (f Flags16) Set12() Flags16 { + const mask = Flags16(1) << 12 + return f | mask +} + +// Unset12 will unset the flag bit value at index 12. +func (f Flags16) Unset12() Flags16 { + const mask = Flags16(1) << 12 + return f & ^mask +} + +// Get13 will fetch the flag bit value at index 13. +func (f Flags16) Get13() bool { + const mask = Flags16(1) << 13 + return (f&mask != 0) +} + +// Set13 will set the flag bit value at index 13. +func (f Flags16) Set13() Flags16 { + const mask = Flags16(1) << 13 + return f | mask +} + +// Unset13 will unset the flag bit value at index 13. +func (f Flags16) Unset13() Flags16 { + const mask = Flags16(1) << 13 + return f & ^mask +} + +// Get14 will fetch the flag bit value at index 14. +func (f Flags16) Get14() bool { + const mask = Flags16(1) << 14 + return (f&mask != 0) +} + +// Set14 will set the flag bit value at index 14. +func (f Flags16) Set14() Flags16 { + const mask = Flags16(1) << 14 + return f | mask +} + +// Unset14 will unset the flag bit value at index 14. +func (f Flags16) Unset14() Flags16 { + const mask = Flags16(1) << 14 + return f & ^mask +} + +// Get15 will fetch the flag bit value at index 15. +func (f Flags16) Get15() bool { + const mask = Flags16(1) << 15 + return (f&mask != 0) +} + +// Set15 will set the flag bit value at index 15. +func (f Flags16) Set15() Flags16 { + const mask = Flags16(1) << 15 + return f | mask +} + +// Unset15 will unset the flag bit value at index 15. +func (f Flags16) Unset15() Flags16 { + const mask = Flags16(1) << 15 + return f & ^mask +} + +// String returns a human readable representation of Flags16. +func (f Flags16) String() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = 1 + (len("false ") * 16) - 1 + 1 + buf = make([]byte, prealloc) + + buf[i] = '{' + i++ + + val = f.Get0() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// GoString returns a more verbose human readable representation of Flags16. +func (f Flags16) GoString() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = len("bitutil.Flags16{") + (len("15=false ") * 16) - 1 + 1 + buf = make([]byte, prealloc) + + i += copy(buf[i:], "bitutil.Flags16{") + + val = f.Get0() + i += copy(buf[i:], "0=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], "1=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], "2=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], "3=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], "4=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], "5=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], "6=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], "7=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], "8=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], "9=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], "10=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], "11=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], "12=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], "13=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], "14=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], "15=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// Flags32 is a type-casted unsigned integer with helper +// methods for easily managing up to 32 bit-flags. +type Flags32 uint32 + +// Get will fetch the flag bit value at index 'bit'. +func (f Flags32) Get(bit uint8) bool { + mask := Flags32(1) << bit + return (f&mask != 0) +} + +// Set will set the flag bit value at index 'bit'. +func (f Flags32) Set(bit uint8) Flags32 { + mask := Flags32(1) << bit + return f | mask +} + +// Unset will unset the flag bit value at index 'bit'. +func (f Flags32) Unset(bit uint8) Flags32 { + mask := Flags32(1) << bit + return f & ^mask +} + +// Get0 will fetch the flag bit value at index 0. +func (f Flags32) Get0() bool { + const mask = Flags32(1) << 0 + return (f&mask != 0) +} + +// Set0 will set the flag bit value at index 0. +func (f Flags32) Set0() Flags32 { + const mask = Flags32(1) << 0 + return f | mask +} + +// Unset0 will unset the flag bit value at index 0. +func (f Flags32) Unset0() Flags32 { + const mask = Flags32(1) << 0 + return f & ^mask +} + +// Get1 will fetch the flag bit value at index 1. +func (f Flags32) Get1() bool { + const mask = Flags32(1) << 1 + return (f&mask != 0) +} + +// Set1 will set the flag bit value at index 1. +func (f Flags32) Set1() Flags32 { + const mask = Flags32(1) << 1 + return f | mask +} + +// Unset1 will unset the flag bit value at index 1. +func (f Flags32) Unset1() Flags32 { + const mask = Flags32(1) << 1 + return f & ^mask +} + +// Get2 will fetch the flag bit value at index 2. +func (f Flags32) Get2() bool { + const mask = Flags32(1) << 2 + return (f&mask != 0) +} + +// Set2 will set the flag bit value at index 2. +func (f Flags32) Set2() Flags32 { + const mask = Flags32(1) << 2 + return f | mask +} + +// Unset2 will unset the flag bit value at index 2. +func (f Flags32) Unset2() Flags32 { + const mask = Flags32(1) << 2 + return f & ^mask +} + +// Get3 will fetch the flag bit value at index 3. +func (f Flags32) Get3() bool { + const mask = Flags32(1) << 3 + return (f&mask != 0) +} + +// Set3 will set the flag bit value at index 3. +func (f Flags32) Set3() Flags32 { + const mask = Flags32(1) << 3 + return f | mask +} + +// Unset3 will unset the flag bit value at index 3. +func (f Flags32) Unset3() Flags32 { + const mask = Flags32(1) << 3 + return f & ^mask +} + +// Get4 will fetch the flag bit value at index 4. +func (f Flags32) Get4() bool { + const mask = Flags32(1) << 4 + return (f&mask != 0) +} + +// Set4 will set the flag bit value at index 4. +func (f Flags32) Set4() Flags32 { + const mask = Flags32(1) << 4 + return f | mask +} + +// Unset4 will unset the flag bit value at index 4. +func (f Flags32) Unset4() Flags32 { + const mask = Flags32(1) << 4 + return f & ^mask +} + +// Get5 will fetch the flag bit value at index 5. +func (f Flags32) Get5() bool { + const mask = Flags32(1) << 5 + return (f&mask != 0) +} + +// Set5 will set the flag bit value at index 5. +func (f Flags32) Set5() Flags32 { + const mask = Flags32(1) << 5 + return f | mask +} + +// Unset5 will unset the flag bit value at index 5. +func (f Flags32) Unset5() Flags32 { + const mask = Flags32(1) << 5 + return f & ^mask +} + +// Get6 will fetch the flag bit value at index 6. +func (f Flags32) Get6() bool { + const mask = Flags32(1) << 6 + return (f&mask != 0) +} + +// Set6 will set the flag bit value at index 6. +func (f Flags32) Set6() Flags32 { + const mask = Flags32(1) << 6 + return f | mask +} + +// Unset6 will unset the flag bit value at index 6. +func (f Flags32) Unset6() Flags32 { + const mask = Flags32(1) << 6 + return f & ^mask +} + +// Get7 will fetch the flag bit value at index 7. +func (f Flags32) Get7() bool { + const mask = Flags32(1) << 7 + return (f&mask != 0) +} + +// Set7 will set the flag bit value at index 7. +func (f Flags32) Set7() Flags32 { + const mask = Flags32(1) << 7 + return f | mask +} + +// Unset7 will unset the flag bit value at index 7. +func (f Flags32) Unset7() Flags32 { + const mask = Flags32(1) << 7 + return f & ^mask +} + +// Get8 will fetch the flag bit value at index 8. +func (f Flags32) Get8() bool { + const mask = Flags32(1) << 8 + return (f&mask != 0) +} + +// Set8 will set the flag bit value at index 8. +func (f Flags32) Set8() Flags32 { + const mask = Flags32(1) << 8 + return f | mask +} + +// Unset8 will unset the flag bit value at index 8. +func (f Flags32) Unset8() Flags32 { + const mask = Flags32(1) << 8 + return f & ^mask +} + +// Get9 will fetch the flag bit value at index 9. +func (f Flags32) Get9() bool { + const mask = Flags32(1) << 9 + return (f&mask != 0) +} + +// Set9 will set the flag bit value at index 9. +func (f Flags32) Set9() Flags32 { + const mask = Flags32(1) << 9 + return f | mask +} + +// Unset9 will unset the flag bit value at index 9. +func (f Flags32) Unset9() Flags32 { + const mask = Flags32(1) << 9 + return f & ^mask +} + +// Get10 will fetch the flag bit value at index 10. +func (f Flags32) Get10() bool { + const mask = Flags32(1) << 10 + return (f&mask != 0) +} + +// Set10 will set the flag bit value at index 10. +func (f Flags32) Set10() Flags32 { + const mask = Flags32(1) << 10 + return f | mask +} + +// Unset10 will unset the flag bit value at index 10. +func (f Flags32) Unset10() Flags32 { + const mask = Flags32(1) << 10 + return f & ^mask +} + +// Get11 will fetch the flag bit value at index 11. +func (f Flags32) Get11() bool { + const mask = Flags32(1) << 11 + return (f&mask != 0) +} + +// Set11 will set the flag bit value at index 11. +func (f Flags32) Set11() Flags32 { + const mask = Flags32(1) << 11 + return f | mask +} + +// Unset11 will unset the flag bit value at index 11. +func (f Flags32) Unset11() Flags32 { + const mask = Flags32(1) << 11 + return f & ^mask +} + +// Get12 will fetch the flag bit value at index 12. +func (f Flags32) Get12() bool { + const mask = Flags32(1) << 12 + return (f&mask != 0) +} + +// Set12 will set the flag bit value at index 12. +func (f Flags32) Set12() Flags32 { + const mask = Flags32(1) << 12 + return f | mask +} + +// Unset12 will unset the flag bit value at index 12. +func (f Flags32) Unset12() Flags32 { + const mask = Flags32(1) << 12 + return f & ^mask +} + +// Get13 will fetch the flag bit value at index 13. +func (f Flags32) Get13() bool { + const mask = Flags32(1) << 13 + return (f&mask != 0) +} + +// Set13 will set the flag bit value at index 13. +func (f Flags32) Set13() Flags32 { + const mask = Flags32(1) << 13 + return f | mask +} + +// Unset13 will unset the flag bit value at index 13. +func (f Flags32) Unset13() Flags32 { + const mask = Flags32(1) << 13 + return f & ^mask +} + +// Get14 will fetch the flag bit value at index 14. +func (f Flags32) Get14() bool { + const mask = Flags32(1) << 14 + return (f&mask != 0) +} + +// Set14 will set the flag bit value at index 14. +func (f Flags32) Set14() Flags32 { + const mask = Flags32(1) << 14 + return f | mask +} + +// Unset14 will unset the flag bit value at index 14. +func (f Flags32) Unset14() Flags32 { + const mask = Flags32(1) << 14 + return f & ^mask +} + +// Get15 will fetch the flag bit value at index 15. +func (f Flags32) Get15() bool { + const mask = Flags32(1) << 15 + return (f&mask != 0) +} + +// Set15 will set the flag bit value at index 15. +func (f Flags32) Set15() Flags32 { + const mask = Flags32(1) << 15 + return f | mask +} + +// Unset15 will unset the flag bit value at index 15. +func (f Flags32) Unset15() Flags32 { + const mask = Flags32(1) << 15 + return f & ^mask +} + +// Get16 will fetch the flag bit value at index 16. +func (f Flags32) Get16() bool { + const mask = Flags32(1) << 16 + return (f&mask != 0) +} + +// Set16 will set the flag bit value at index 16. +func (f Flags32) Set16() Flags32 { + const mask = Flags32(1) << 16 + return f | mask +} + +// Unset16 will unset the flag bit value at index 16. +func (f Flags32) Unset16() Flags32 { + const mask = Flags32(1) << 16 + return f & ^mask +} + +// Get17 will fetch the flag bit value at index 17. +func (f Flags32) Get17() bool { + const mask = Flags32(1) << 17 + return (f&mask != 0) +} + +// Set17 will set the flag bit value at index 17. +func (f Flags32) Set17() Flags32 { + const mask = Flags32(1) << 17 + return f | mask +} + +// Unset17 will unset the flag bit value at index 17. +func (f Flags32) Unset17() Flags32 { + const mask = Flags32(1) << 17 + return f & ^mask +} + +// Get18 will fetch the flag bit value at index 18. +func (f Flags32) Get18() bool { + const mask = Flags32(1) << 18 + return (f&mask != 0) +} + +// Set18 will set the flag bit value at index 18. +func (f Flags32) Set18() Flags32 { + const mask = Flags32(1) << 18 + return f | mask +} + +// Unset18 will unset the flag bit value at index 18. +func (f Flags32) Unset18() Flags32 { + const mask = Flags32(1) << 18 + return f & ^mask +} + +// Get19 will fetch the flag bit value at index 19. +func (f Flags32) Get19() bool { + const mask = Flags32(1) << 19 + return (f&mask != 0) +} + +// Set19 will set the flag bit value at index 19. +func (f Flags32) Set19() Flags32 { + const mask = Flags32(1) << 19 + return f | mask +} + +// Unset19 will unset the flag bit value at index 19. +func (f Flags32) Unset19() Flags32 { + const mask = Flags32(1) << 19 + return f & ^mask +} + +// Get20 will fetch the flag bit value at index 20. +func (f Flags32) Get20() bool { + const mask = Flags32(1) << 20 + return (f&mask != 0) +} + +// Set20 will set the flag bit value at index 20. +func (f Flags32) Set20() Flags32 { + const mask = Flags32(1) << 20 + return f | mask +} + +// Unset20 will unset the flag bit value at index 20. +func (f Flags32) Unset20() Flags32 { + const mask = Flags32(1) << 20 + return f & ^mask +} + +// Get21 will fetch the flag bit value at index 21. +func (f Flags32) Get21() bool { + const mask = Flags32(1) << 21 + return (f&mask != 0) +} + +// Set21 will set the flag bit value at index 21. +func (f Flags32) Set21() Flags32 { + const mask = Flags32(1) << 21 + return f | mask +} + +// Unset21 will unset the flag bit value at index 21. +func (f Flags32) Unset21() Flags32 { + const mask = Flags32(1) << 21 + return f & ^mask +} + +// Get22 will fetch the flag bit value at index 22. +func (f Flags32) Get22() bool { + const mask = Flags32(1) << 22 + return (f&mask != 0) +} + +// Set22 will set the flag bit value at index 22. +func (f Flags32) Set22() Flags32 { + const mask = Flags32(1) << 22 + return f | mask +} + +// Unset22 will unset the flag bit value at index 22. +func (f Flags32) Unset22() Flags32 { + const mask = Flags32(1) << 22 + return f & ^mask +} + +// Get23 will fetch the flag bit value at index 23. +func (f Flags32) Get23() bool { + const mask = Flags32(1) << 23 + return (f&mask != 0) +} + +// Set23 will set the flag bit value at index 23. +func (f Flags32) Set23() Flags32 { + const mask = Flags32(1) << 23 + return f | mask +} + +// Unset23 will unset the flag bit value at index 23. +func (f Flags32) Unset23() Flags32 { + const mask = Flags32(1) << 23 + return f & ^mask +} + +// Get24 will fetch the flag bit value at index 24. +func (f Flags32) Get24() bool { + const mask = Flags32(1) << 24 + return (f&mask != 0) +} + +// Set24 will set the flag bit value at index 24. +func (f Flags32) Set24() Flags32 { + const mask = Flags32(1) << 24 + return f | mask +} + +// Unset24 will unset the flag bit value at index 24. +func (f Flags32) Unset24() Flags32 { + const mask = Flags32(1) << 24 + return f & ^mask +} + +// Get25 will fetch the flag bit value at index 25. +func (f Flags32) Get25() bool { + const mask = Flags32(1) << 25 + return (f&mask != 0) +} + +// Set25 will set the flag bit value at index 25. +func (f Flags32) Set25() Flags32 { + const mask = Flags32(1) << 25 + return f | mask +} + +// Unset25 will unset the flag bit value at index 25. +func (f Flags32) Unset25() Flags32 { + const mask = Flags32(1) << 25 + return f & ^mask +} + +// Get26 will fetch the flag bit value at index 26. +func (f Flags32) Get26() bool { + const mask = Flags32(1) << 26 + return (f&mask != 0) +} + +// Set26 will set the flag bit value at index 26. +func (f Flags32) Set26() Flags32 { + const mask = Flags32(1) << 26 + return f | mask +} + +// Unset26 will unset the flag bit value at index 26. +func (f Flags32) Unset26() Flags32 { + const mask = Flags32(1) << 26 + return f & ^mask +} + +// Get27 will fetch the flag bit value at index 27. +func (f Flags32) Get27() bool { + const mask = Flags32(1) << 27 + return (f&mask != 0) +} + +// Set27 will set the flag bit value at index 27. +func (f Flags32) Set27() Flags32 { + const mask = Flags32(1) << 27 + return f | mask +} + +// Unset27 will unset the flag bit value at index 27. +func (f Flags32) Unset27() Flags32 { + const mask = Flags32(1) << 27 + return f & ^mask +} + +// Get28 will fetch the flag bit value at index 28. +func (f Flags32) Get28() bool { + const mask = Flags32(1) << 28 + return (f&mask != 0) +} + +// Set28 will set the flag bit value at index 28. +func (f Flags32) Set28() Flags32 { + const mask = Flags32(1) << 28 + return f | mask +} + +// Unset28 will unset the flag bit value at index 28. +func (f Flags32) Unset28() Flags32 { + const mask = Flags32(1) << 28 + return f & ^mask +} + +// Get29 will fetch the flag bit value at index 29. +func (f Flags32) Get29() bool { + const mask = Flags32(1) << 29 + return (f&mask != 0) +} + +// Set29 will set the flag bit value at index 29. +func (f Flags32) Set29() Flags32 { + const mask = Flags32(1) << 29 + return f | mask +} + +// Unset29 will unset the flag bit value at index 29. +func (f Flags32) Unset29() Flags32 { + const mask = Flags32(1) << 29 + return f & ^mask +} + +// Get30 will fetch the flag bit value at index 30. +func (f Flags32) Get30() bool { + const mask = Flags32(1) << 30 + return (f&mask != 0) +} + +// Set30 will set the flag bit value at index 30. +func (f Flags32) Set30() Flags32 { + const mask = Flags32(1) << 30 + return f | mask +} + +// Unset30 will unset the flag bit value at index 30. +func (f Flags32) Unset30() Flags32 { + const mask = Flags32(1) << 30 + return f & ^mask +} + +// Get31 will fetch the flag bit value at index 31. +func (f Flags32) Get31() bool { + const mask = Flags32(1) << 31 + return (f&mask != 0) +} + +// Set31 will set the flag bit value at index 31. +func (f Flags32) Set31() Flags32 { + const mask = Flags32(1) << 31 + return f | mask +} + +// Unset31 will unset the flag bit value at index 31. +func (f Flags32) Unset31() Flags32 { + const mask = Flags32(1) << 31 + return f & ^mask +} + +// String returns a human readable representation of Flags32. +func (f Flags32) String() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = 1 + (len("false ") * 32) - 1 + 1 + buf = make([]byte, prealloc) + + buf[i] = '{' + i++ + + val = f.Get0() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get16() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get17() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get18() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get19() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get20() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get21() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get22() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get23() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get24() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get25() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get26() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get27() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get28() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get29() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get30() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get31() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// GoString returns a more verbose human readable representation of Flags32. +func (f Flags32) GoString() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = len("bitutil.Flags32{") + (len("31=false ") * 32) - 1 + 1 + buf = make([]byte, prealloc) + + i += copy(buf[i:], "bitutil.Flags32{") + + val = f.Get0() + i += copy(buf[i:], "0=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], "1=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], "2=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], "3=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], "4=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], "5=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], "6=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], "7=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], "8=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], "9=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], "10=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], "11=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], "12=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], "13=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], "14=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], "15=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get16() + i += copy(buf[i:], "16=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get17() + i += copy(buf[i:], "17=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get18() + i += copy(buf[i:], "18=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get19() + i += copy(buf[i:], "19=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get20() + i += copy(buf[i:], "20=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get21() + i += copy(buf[i:], "21=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get22() + i += copy(buf[i:], "22=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get23() + i += copy(buf[i:], "23=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get24() + i += copy(buf[i:], "24=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get25() + i += copy(buf[i:], "25=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get26() + i += copy(buf[i:], "26=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get27() + i += copy(buf[i:], "27=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get28() + i += copy(buf[i:], "28=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get29() + i += copy(buf[i:], "29=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get30() + i += copy(buf[i:], "30=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get31() + i += copy(buf[i:], "31=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// Flags64 is a type-casted unsigned integer with helper +// methods for easily managing up to 64 bit-flags. +type Flags64 uint64 + +// Get will fetch the flag bit value at index 'bit'. +func (f Flags64) Get(bit uint8) bool { + mask := Flags64(1) << bit + return (f&mask != 0) +} + +// Set will set the flag bit value at index 'bit'. +func (f Flags64) Set(bit uint8) Flags64 { + mask := Flags64(1) << bit + return f | mask +} + +// Unset will unset the flag bit value at index 'bit'. +func (f Flags64) Unset(bit uint8) Flags64 { + mask := Flags64(1) << bit + return f & ^mask +} + +// Get0 will fetch the flag bit value at index 0. +func (f Flags64) Get0() bool { + const mask = Flags64(1) << 0 + return (f&mask != 0) +} + +// Set0 will set the flag bit value at index 0. +func (f Flags64) Set0() Flags64 { + const mask = Flags64(1) << 0 + return f | mask +} + +// Unset0 will unset the flag bit value at index 0. +func (f Flags64) Unset0() Flags64 { + const mask = Flags64(1) << 0 + return f & ^mask +} + +// Get1 will fetch the flag bit value at index 1. +func (f Flags64) Get1() bool { + const mask = Flags64(1) << 1 + return (f&mask != 0) +} + +// Set1 will set the flag bit value at index 1. +func (f Flags64) Set1() Flags64 { + const mask = Flags64(1) << 1 + return f | mask +} + +// Unset1 will unset the flag bit value at index 1. +func (f Flags64) Unset1() Flags64 { + const mask = Flags64(1) << 1 + return f & ^mask +} + +// Get2 will fetch the flag bit value at index 2. +func (f Flags64) Get2() bool { + const mask = Flags64(1) << 2 + return (f&mask != 0) +} + +// Set2 will set the flag bit value at index 2. +func (f Flags64) Set2() Flags64 { + const mask = Flags64(1) << 2 + return f | mask +} + +// Unset2 will unset the flag bit value at index 2. +func (f Flags64) Unset2() Flags64 { + const mask = Flags64(1) << 2 + return f & ^mask +} + +// Get3 will fetch the flag bit value at index 3. +func (f Flags64) Get3() bool { + const mask = Flags64(1) << 3 + return (f&mask != 0) +} + +// Set3 will set the flag bit value at index 3. +func (f Flags64) Set3() Flags64 { + const mask = Flags64(1) << 3 + return f | mask +} + +// Unset3 will unset the flag bit value at index 3. +func (f Flags64) Unset3() Flags64 { + const mask = Flags64(1) << 3 + return f & ^mask +} + +// Get4 will fetch the flag bit value at index 4. +func (f Flags64) Get4() bool { + const mask = Flags64(1) << 4 + return (f&mask != 0) +} + +// Set4 will set the flag bit value at index 4. +func (f Flags64) Set4() Flags64 { + const mask = Flags64(1) << 4 + return f | mask +} + +// Unset4 will unset the flag bit value at index 4. +func (f Flags64) Unset4() Flags64 { + const mask = Flags64(1) << 4 + return f & ^mask +} + +// Get5 will fetch the flag bit value at index 5. +func (f Flags64) Get5() bool { + const mask = Flags64(1) << 5 + return (f&mask != 0) +} + +// Set5 will set the flag bit value at index 5. +func (f Flags64) Set5() Flags64 { + const mask = Flags64(1) << 5 + return f | mask +} + +// Unset5 will unset the flag bit value at index 5. +func (f Flags64) Unset5() Flags64 { + const mask = Flags64(1) << 5 + return f & ^mask +} + +// Get6 will fetch the flag bit value at index 6. +func (f Flags64) Get6() bool { + const mask = Flags64(1) << 6 + return (f&mask != 0) +} + +// Set6 will set the flag bit value at index 6. +func (f Flags64) Set6() Flags64 { + const mask = Flags64(1) << 6 + return f | mask +} + +// Unset6 will unset the flag bit value at index 6. +func (f Flags64) Unset6() Flags64 { + const mask = Flags64(1) << 6 + return f & ^mask +} + +// Get7 will fetch the flag bit value at index 7. +func (f Flags64) Get7() bool { + const mask = Flags64(1) << 7 + return (f&mask != 0) +} + +// Set7 will set the flag bit value at index 7. +func (f Flags64) Set7() Flags64 { + const mask = Flags64(1) << 7 + return f | mask +} + +// Unset7 will unset the flag bit value at index 7. +func (f Flags64) Unset7() Flags64 { + const mask = Flags64(1) << 7 + return f & ^mask +} + +// Get8 will fetch the flag bit value at index 8. +func (f Flags64) Get8() bool { + const mask = Flags64(1) << 8 + return (f&mask != 0) +} + +// Set8 will set the flag bit value at index 8. +func (f Flags64) Set8() Flags64 { + const mask = Flags64(1) << 8 + return f | mask +} + +// Unset8 will unset the flag bit value at index 8. +func (f Flags64) Unset8() Flags64 { + const mask = Flags64(1) << 8 + return f & ^mask +} + +// Get9 will fetch the flag bit value at index 9. +func (f Flags64) Get9() bool { + const mask = Flags64(1) << 9 + return (f&mask != 0) +} + +// Set9 will set the flag bit value at index 9. +func (f Flags64) Set9() Flags64 { + const mask = Flags64(1) << 9 + return f | mask +} + +// Unset9 will unset the flag bit value at index 9. +func (f Flags64) Unset9() Flags64 { + const mask = Flags64(1) << 9 + return f & ^mask +} + +// Get10 will fetch the flag bit value at index 10. +func (f Flags64) Get10() bool { + const mask = Flags64(1) << 10 + return (f&mask != 0) +} + +// Set10 will set the flag bit value at index 10. +func (f Flags64) Set10() Flags64 { + const mask = Flags64(1) << 10 + return f | mask +} + +// Unset10 will unset the flag bit value at index 10. +func (f Flags64) Unset10() Flags64 { + const mask = Flags64(1) << 10 + return f & ^mask +} + +// Get11 will fetch the flag bit value at index 11. +func (f Flags64) Get11() bool { + const mask = Flags64(1) << 11 + return (f&mask != 0) +} + +// Set11 will set the flag bit value at index 11. +func (f Flags64) Set11() Flags64 { + const mask = Flags64(1) << 11 + return f | mask +} + +// Unset11 will unset the flag bit value at index 11. +func (f Flags64) Unset11() Flags64 { + const mask = Flags64(1) << 11 + return f & ^mask +} + +// Get12 will fetch the flag bit value at index 12. +func (f Flags64) Get12() bool { + const mask = Flags64(1) << 12 + return (f&mask != 0) +} + +// Set12 will set the flag bit value at index 12. +func (f Flags64) Set12() Flags64 { + const mask = Flags64(1) << 12 + return f | mask +} + +// Unset12 will unset the flag bit value at index 12. +func (f Flags64) Unset12() Flags64 { + const mask = Flags64(1) << 12 + return f & ^mask +} + +// Get13 will fetch the flag bit value at index 13. +func (f Flags64) Get13() bool { + const mask = Flags64(1) << 13 + return (f&mask != 0) +} + +// Set13 will set the flag bit value at index 13. +func (f Flags64) Set13() Flags64 { + const mask = Flags64(1) << 13 + return f | mask +} + +// Unset13 will unset the flag bit value at index 13. +func (f Flags64) Unset13() Flags64 { + const mask = Flags64(1) << 13 + return f & ^mask +} + +// Get14 will fetch the flag bit value at index 14. +func (f Flags64) Get14() bool { + const mask = Flags64(1) << 14 + return (f&mask != 0) +} + +// Set14 will set the flag bit value at index 14. +func (f Flags64) Set14() Flags64 { + const mask = Flags64(1) << 14 + return f | mask +} + +// Unset14 will unset the flag bit value at index 14. +func (f Flags64) Unset14() Flags64 { + const mask = Flags64(1) << 14 + return f & ^mask +} + +// Get15 will fetch the flag bit value at index 15. +func (f Flags64) Get15() bool { + const mask = Flags64(1) << 15 + return (f&mask != 0) +} + +// Set15 will set the flag bit value at index 15. +func (f Flags64) Set15() Flags64 { + const mask = Flags64(1) << 15 + return f | mask +} + +// Unset15 will unset the flag bit value at index 15. +func (f Flags64) Unset15() Flags64 { + const mask = Flags64(1) << 15 + return f & ^mask +} + +// Get16 will fetch the flag bit value at index 16. +func (f Flags64) Get16() bool { + const mask = Flags64(1) << 16 + return (f&mask != 0) +} + +// Set16 will set the flag bit value at index 16. +func (f Flags64) Set16() Flags64 { + const mask = Flags64(1) << 16 + return f | mask +} + +// Unset16 will unset the flag bit value at index 16. +func (f Flags64) Unset16() Flags64 { + const mask = Flags64(1) << 16 + return f & ^mask +} + +// Get17 will fetch the flag bit value at index 17. +func (f Flags64) Get17() bool { + const mask = Flags64(1) << 17 + return (f&mask != 0) +} + +// Set17 will set the flag bit value at index 17. +func (f Flags64) Set17() Flags64 { + const mask = Flags64(1) << 17 + return f | mask +} + +// Unset17 will unset the flag bit value at index 17. +func (f Flags64) Unset17() Flags64 { + const mask = Flags64(1) << 17 + return f & ^mask +} + +// Get18 will fetch the flag bit value at index 18. +func (f Flags64) Get18() bool { + const mask = Flags64(1) << 18 + return (f&mask != 0) +} + +// Set18 will set the flag bit value at index 18. +func (f Flags64) Set18() Flags64 { + const mask = Flags64(1) << 18 + return f | mask +} + +// Unset18 will unset the flag bit value at index 18. +func (f Flags64) Unset18() Flags64 { + const mask = Flags64(1) << 18 + return f & ^mask +} + +// Get19 will fetch the flag bit value at index 19. +func (f Flags64) Get19() bool { + const mask = Flags64(1) << 19 + return (f&mask != 0) +} + +// Set19 will set the flag bit value at index 19. +func (f Flags64) Set19() Flags64 { + const mask = Flags64(1) << 19 + return f | mask +} + +// Unset19 will unset the flag bit value at index 19. +func (f Flags64) Unset19() Flags64 { + const mask = Flags64(1) << 19 + return f & ^mask +} + +// Get20 will fetch the flag bit value at index 20. +func (f Flags64) Get20() bool { + const mask = Flags64(1) << 20 + return (f&mask != 0) +} + +// Set20 will set the flag bit value at index 20. +func (f Flags64) Set20() Flags64 { + const mask = Flags64(1) << 20 + return f | mask +} + +// Unset20 will unset the flag bit value at index 20. +func (f Flags64) Unset20() Flags64 { + const mask = Flags64(1) << 20 + return f & ^mask +} + +// Get21 will fetch the flag bit value at index 21. +func (f Flags64) Get21() bool { + const mask = Flags64(1) << 21 + return (f&mask != 0) +} + +// Set21 will set the flag bit value at index 21. +func (f Flags64) Set21() Flags64 { + const mask = Flags64(1) << 21 + return f | mask +} + +// Unset21 will unset the flag bit value at index 21. +func (f Flags64) Unset21() Flags64 { + const mask = Flags64(1) << 21 + return f & ^mask +} + +// Get22 will fetch the flag bit value at index 22. +func (f Flags64) Get22() bool { + const mask = Flags64(1) << 22 + return (f&mask != 0) +} + +// Set22 will set the flag bit value at index 22. +func (f Flags64) Set22() Flags64 { + const mask = Flags64(1) << 22 + return f | mask +} + +// Unset22 will unset the flag bit value at index 22. +func (f Flags64) Unset22() Flags64 { + const mask = Flags64(1) << 22 + return f & ^mask +} + +// Get23 will fetch the flag bit value at index 23. +func (f Flags64) Get23() bool { + const mask = Flags64(1) << 23 + return (f&mask != 0) +} + +// Set23 will set the flag bit value at index 23. +func (f Flags64) Set23() Flags64 { + const mask = Flags64(1) << 23 + return f | mask +} + +// Unset23 will unset the flag bit value at index 23. +func (f Flags64) Unset23() Flags64 { + const mask = Flags64(1) << 23 + return f & ^mask +} + +// Get24 will fetch the flag bit value at index 24. +func (f Flags64) Get24() bool { + const mask = Flags64(1) << 24 + return (f&mask != 0) +} + +// Set24 will set the flag bit value at index 24. +func (f Flags64) Set24() Flags64 { + const mask = Flags64(1) << 24 + return f | mask +} + +// Unset24 will unset the flag bit value at index 24. +func (f Flags64) Unset24() Flags64 { + const mask = Flags64(1) << 24 + return f & ^mask +} + +// Get25 will fetch the flag bit value at index 25. +func (f Flags64) Get25() bool { + const mask = Flags64(1) << 25 + return (f&mask != 0) +} + +// Set25 will set the flag bit value at index 25. +func (f Flags64) Set25() Flags64 { + const mask = Flags64(1) << 25 + return f | mask +} + +// Unset25 will unset the flag bit value at index 25. +func (f Flags64) Unset25() Flags64 { + const mask = Flags64(1) << 25 + return f & ^mask +} + +// Get26 will fetch the flag bit value at index 26. +func (f Flags64) Get26() bool { + const mask = Flags64(1) << 26 + return (f&mask != 0) +} + +// Set26 will set the flag bit value at index 26. +func (f Flags64) Set26() Flags64 { + const mask = Flags64(1) << 26 + return f | mask +} + +// Unset26 will unset the flag bit value at index 26. +func (f Flags64) Unset26() Flags64 { + const mask = Flags64(1) << 26 + return f & ^mask +} + +// Get27 will fetch the flag bit value at index 27. +func (f Flags64) Get27() bool { + const mask = Flags64(1) << 27 + return (f&mask != 0) +} + +// Set27 will set the flag bit value at index 27. +func (f Flags64) Set27() Flags64 { + const mask = Flags64(1) << 27 + return f | mask +} + +// Unset27 will unset the flag bit value at index 27. +func (f Flags64) Unset27() Flags64 { + const mask = Flags64(1) << 27 + return f & ^mask +} + +// Get28 will fetch the flag bit value at index 28. +func (f Flags64) Get28() bool { + const mask = Flags64(1) << 28 + return (f&mask != 0) +} + +// Set28 will set the flag bit value at index 28. +func (f Flags64) Set28() Flags64 { + const mask = Flags64(1) << 28 + return f | mask +} + +// Unset28 will unset the flag bit value at index 28. +func (f Flags64) Unset28() Flags64 { + const mask = Flags64(1) << 28 + return f & ^mask +} + +// Get29 will fetch the flag bit value at index 29. +func (f Flags64) Get29() bool { + const mask = Flags64(1) << 29 + return (f&mask != 0) +} + +// Set29 will set the flag bit value at index 29. +func (f Flags64) Set29() Flags64 { + const mask = Flags64(1) << 29 + return f | mask +} + +// Unset29 will unset the flag bit value at index 29. +func (f Flags64) Unset29() Flags64 { + const mask = Flags64(1) << 29 + return f & ^mask +} + +// Get30 will fetch the flag bit value at index 30. +func (f Flags64) Get30() bool { + const mask = Flags64(1) << 30 + return (f&mask != 0) +} + +// Set30 will set the flag bit value at index 30. +func (f Flags64) Set30() Flags64 { + const mask = Flags64(1) << 30 + return f | mask +} + +// Unset30 will unset the flag bit value at index 30. +func (f Flags64) Unset30() Flags64 { + const mask = Flags64(1) << 30 + return f & ^mask +} + +// Get31 will fetch the flag bit value at index 31. +func (f Flags64) Get31() bool { + const mask = Flags64(1) << 31 + return (f&mask != 0) +} + +// Set31 will set the flag bit value at index 31. +func (f Flags64) Set31() Flags64 { + const mask = Flags64(1) << 31 + return f | mask +} + +// Unset31 will unset the flag bit value at index 31. +func (f Flags64) Unset31() Flags64 { + const mask = Flags64(1) << 31 + return f & ^mask +} + +// Get32 will fetch the flag bit value at index 32. +func (f Flags64) Get32() bool { + const mask = Flags64(1) << 32 + return (f&mask != 0) +} + +// Set32 will set the flag bit value at index 32. +func (f Flags64) Set32() Flags64 { + const mask = Flags64(1) << 32 + return f | mask +} + +// Unset32 will unset the flag bit value at index 32. +func (f Flags64) Unset32() Flags64 { + const mask = Flags64(1) << 32 + return f & ^mask +} + +// Get33 will fetch the flag bit value at index 33. +func (f Flags64) Get33() bool { + const mask = Flags64(1) << 33 + return (f&mask != 0) +} + +// Set33 will set the flag bit value at index 33. +func (f Flags64) Set33() Flags64 { + const mask = Flags64(1) << 33 + return f | mask +} + +// Unset33 will unset the flag bit value at index 33. +func (f Flags64) Unset33() Flags64 { + const mask = Flags64(1) << 33 + return f & ^mask +} + +// Get34 will fetch the flag bit value at index 34. +func (f Flags64) Get34() bool { + const mask = Flags64(1) << 34 + return (f&mask != 0) +} + +// Set34 will set the flag bit value at index 34. +func (f Flags64) Set34() Flags64 { + const mask = Flags64(1) << 34 + return f | mask +} + +// Unset34 will unset the flag bit value at index 34. +func (f Flags64) Unset34() Flags64 { + const mask = Flags64(1) << 34 + return f & ^mask +} + +// Get35 will fetch the flag bit value at index 35. +func (f Flags64) Get35() bool { + const mask = Flags64(1) << 35 + return (f&mask != 0) +} + +// Set35 will set the flag bit value at index 35. +func (f Flags64) Set35() Flags64 { + const mask = Flags64(1) << 35 + return f | mask +} + +// Unset35 will unset the flag bit value at index 35. +func (f Flags64) Unset35() Flags64 { + const mask = Flags64(1) << 35 + return f & ^mask +} + +// Get36 will fetch the flag bit value at index 36. +func (f Flags64) Get36() bool { + const mask = Flags64(1) << 36 + return (f&mask != 0) +} + +// Set36 will set the flag bit value at index 36. +func (f Flags64) Set36() Flags64 { + const mask = Flags64(1) << 36 + return f | mask +} + +// Unset36 will unset the flag bit value at index 36. +func (f Flags64) Unset36() Flags64 { + const mask = Flags64(1) << 36 + return f & ^mask +} + +// Get37 will fetch the flag bit value at index 37. +func (f Flags64) Get37() bool { + const mask = Flags64(1) << 37 + return (f&mask != 0) +} + +// Set37 will set the flag bit value at index 37. +func (f Flags64) Set37() Flags64 { + const mask = Flags64(1) << 37 + return f | mask +} + +// Unset37 will unset the flag bit value at index 37. +func (f Flags64) Unset37() Flags64 { + const mask = Flags64(1) << 37 + return f & ^mask +} + +// Get38 will fetch the flag bit value at index 38. +func (f Flags64) Get38() bool { + const mask = Flags64(1) << 38 + return (f&mask != 0) +} + +// Set38 will set the flag bit value at index 38. +func (f Flags64) Set38() Flags64 { + const mask = Flags64(1) << 38 + return f | mask +} + +// Unset38 will unset the flag bit value at index 38. +func (f Flags64) Unset38() Flags64 { + const mask = Flags64(1) << 38 + return f & ^mask +} + +// Get39 will fetch the flag bit value at index 39. +func (f Flags64) Get39() bool { + const mask = Flags64(1) << 39 + return (f&mask != 0) +} + +// Set39 will set the flag bit value at index 39. +func (f Flags64) Set39() Flags64 { + const mask = Flags64(1) << 39 + return f | mask +} + +// Unset39 will unset the flag bit value at index 39. +func (f Flags64) Unset39() Flags64 { + const mask = Flags64(1) << 39 + return f & ^mask +} + +// Get40 will fetch the flag bit value at index 40. +func (f Flags64) Get40() bool { + const mask = Flags64(1) << 40 + return (f&mask != 0) +} + +// Set40 will set the flag bit value at index 40. +func (f Flags64) Set40() Flags64 { + const mask = Flags64(1) << 40 + return f | mask +} + +// Unset40 will unset the flag bit value at index 40. +func (f Flags64) Unset40() Flags64 { + const mask = Flags64(1) << 40 + return f & ^mask +} + +// Get41 will fetch the flag bit value at index 41. +func (f Flags64) Get41() bool { + const mask = Flags64(1) << 41 + return (f&mask != 0) +} + +// Set41 will set the flag bit value at index 41. +func (f Flags64) Set41() Flags64 { + const mask = Flags64(1) << 41 + return f | mask +} + +// Unset41 will unset the flag bit value at index 41. +func (f Flags64) Unset41() Flags64 { + const mask = Flags64(1) << 41 + return f & ^mask +} + +// Get42 will fetch the flag bit value at index 42. +func (f Flags64) Get42() bool { + const mask = Flags64(1) << 42 + return (f&mask != 0) +} + +// Set42 will set the flag bit value at index 42. +func (f Flags64) Set42() Flags64 { + const mask = Flags64(1) << 42 + return f | mask +} + +// Unset42 will unset the flag bit value at index 42. +func (f Flags64) Unset42() Flags64 { + const mask = Flags64(1) << 42 + return f & ^mask +} + +// Get43 will fetch the flag bit value at index 43. +func (f Flags64) Get43() bool { + const mask = Flags64(1) << 43 + return (f&mask != 0) +} + +// Set43 will set the flag bit value at index 43. +func (f Flags64) Set43() Flags64 { + const mask = Flags64(1) << 43 + return f | mask +} + +// Unset43 will unset the flag bit value at index 43. +func (f Flags64) Unset43() Flags64 { + const mask = Flags64(1) << 43 + return f & ^mask +} + +// Get44 will fetch the flag bit value at index 44. +func (f Flags64) Get44() bool { + const mask = Flags64(1) << 44 + return (f&mask != 0) +} + +// Set44 will set the flag bit value at index 44. +func (f Flags64) Set44() Flags64 { + const mask = Flags64(1) << 44 + return f | mask +} + +// Unset44 will unset the flag bit value at index 44. +func (f Flags64) Unset44() Flags64 { + const mask = Flags64(1) << 44 + return f & ^mask +} + +// Get45 will fetch the flag bit value at index 45. +func (f Flags64) Get45() bool { + const mask = Flags64(1) << 45 + return (f&mask != 0) +} + +// Set45 will set the flag bit value at index 45. +func (f Flags64) Set45() Flags64 { + const mask = Flags64(1) << 45 + return f | mask +} + +// Unset45 will unset the flag bit value at index 45. +func (f Flags64) Unset45() Flags64 { + const mask = Flags64(1) << 45 + return f & ^mask +} + +// Get46 will fetch the flag bit value at index 46. +func (f Flags64) Get46() bool { + const mask = Flags64(1) << 46 + return (f&mask != 0) +} + +// Set46 will set the flag bit value at index 46. +func (f Flags64) Set46() Flags64 { + const mask = Flags64(1) << 46 + return f | mask +} + +// Unset46 will unset the flag bit value at index 46. +func (f Flags64) Unset46() Flags64 { + const mask = Flags64(1) << 46 + return f & ^mask +} + +// Get47 will fetch the flag bit value at index 47. +func (f Flags64) Get47() bool { + const mask = Flags64(1) << 47 + return (f&mask != 0) +} + +// Set47 will set the flag bit value at index 47. +func (f Flags64) Set47() Flags64 { + const mask = Flags64(1) << 47 + return f | mask +} + +// Unset47 will unset the flag bit value at index 47. +func (f Flags64) Unset47() Flags64 { + const mask = Flags64(1) << 47 + return f & ^mask +} + +// Get48 will fetch the flag bit value at index 48. +func (f Flags64) Get48() bool { + const mask = Flags64(1) << 48 + return (f&mask != 0) +} + +// Set48 will set the flag bit value at index 48. +func (f Flags64) Set48() Flags64 { + const mask = Flags64(1) << 48 + return f | mask +} + +// Unset48 will unset the flag bit value at index 48. +func (f Flags64) Unset48() Flags64 { + const mask = Flags64(1) << 48 + return f & ^mask +} + +// Get49 will fetch the flag bit value at index 49. +func (f Flags64) Get49() bool { + const mask = Flags64(1) << 49 + return (f&mask != 0) +} + +// Set49 will set the flag bit value at index 49. +func (f Flags64) Set49() Flags64 { + const mask = Flags64(1) << 49 + return f | mask +} + +// Unset49 will unset the flag bit value at index 49. +func (f Flags64) Unset49() Flags64 { + const mask = Flags64(1) << 49 + return f & ^mask +} + +// Get50 will fetch the flag bit value at index 50. +func (f Flags64) Get50() bool { + const mask = Flags64(1) << 50 + return (f&mask != 0) +} + +// Set50 will set the flag bit value at index 50. +func (f Flags64) Set50() Flags64 { + const mask = Flags64(1) << 50 + return f | mask +} + +// Unset50 will unset the flag bit value at index 50. +func (f Flags64) Unset50() Flags64 { + const mask = Flags64(1) << 50 + return f & ^mask +} + +// Get51 will fetch the flag bit value at index 51. +func (f Flags64) Get51() bool { + const mask = Flags64(1) << 51 + return (f&mask != 0) +} + +// Set51 will set the flag bit value at index 51. +func (f Flags64) Set51() Flags64 { + const mask = Flags64(1) << 51 + return f | mask +} + +// Unset51 will unset the flag bit value at index 51. +func (f Flags64) Unset51() Flags64 { + const mask = Flags64(1) << 51 + return f & ^mask +} + +// Get52 will fetch the flag bit value at index 52. +func (f Flags64) Get52() bool { + const mask = Flags64(1) << 52 + return (f&mask != 0) +} + +// Set52 will set the flag bit value at index 52. +func (f Flags64) Set52() Flags64 { + const mask = Flags64(1) << 52 + return f | mask +} + +// Unset52 will unset the flag bit value at index 52. +func (f Flags64) Unset52() Flags64 { + const mask = Flags64(1) << 52 + return f & ^mask +} + +// Get53 will fetch the flag bit value at index 53. +func (f Flags64) Get53() bool { + const mask = Flags64(1) << 53 + return (f&mask != 0) +} + +// Set53 will set the flag bit value at index 53. +func (f Flags64) Set53() Flags64 { + const mask = Flags64(1) << 53 + return f | mask +} + +// Unset53 will unset the flag bit value at index 53. +func (f Flags64) Unset53() Flags64 { + const mask = Flags64(1) << 53 + return f & ^mask +} + +// Get54 will fetch the flag bit value at index 54. +func (f Flags64) Get54() bool { + const mask = Flags64(1) << 54 + return (f&mask != 0) +} + +// Set54 will set the flag bit value at index 54. +func (f Flags64) Set54() Flags64 { + const mask = Flags64(1) << 54 + return f | mask +} + +// Unset54 will unset the flag bit value at index 54. +func (f Flags64) Unset54() Flags64 { + const mask = Flags64(1) << 54 + return f & ^mask +} + +// Get55 will fetch the flag bit value at index 55. +func (f Flags64) Get55() bool { + const mask = Flags64(1) << 55 + return (f&mask != 0) +} + +// Set55 will set the flag bit value at index 55. +func (f Flags64) Set55() Flags64 { + const mask = Flags64(1) << 55 + return f | mask +} + +// Unset55 will unset the flag bit value at index 55. +func (f Flags64) Unset55() Flags64 { + const mask = Flags64(1) << 55 + return f & ^mask +} + +// Get56 will fetch the flag bit value at index 56. +func (f Flags64) Get56() bool { + const mask = Flags64(1) << 56 + return (f&mask != 0) +} + +// Set56 will set the flag bit value at index 56. +func (f Flags64) Set56() Flags64 { + const mask = Flags64(1) << 56 + return f | mask +} + +// Unset56 will unset the flag bit value at index 56. +func (f Flags64) Unset56() Flags64 { + const mask = Flags64(1) << 56 + return f & ^mask +} + +// Get57 will fetch the flag bit value at index 57. +func (f Flags64) Get57() bool { + const mask = Flags64(1) << 57 + return (f&mask != 0) +} + +// Set57 will set the flag bit value at index 57. +func (f Flags64) Set57() Flags64 { + const mask = Flags64(1) << 57 + return f | mask +} + +// Unset57 will unset the flag bit value at index 57. +func (f Flags64) Unset57() Flags64 { + const mask = Flags64(1) << 57 + return f & ^mask +} + +// Get58 will fetch the flag bit value at index 58. +func (f Flags64) Get58() bool { + const mask = Flags64(1) << 58 + return (f&mask != 0) +} + +// Set58 will set the flag bit value at index 58. +func (f Flags64) Set58() Flags64 { + const mask = Flags64(1) << 58 + return f | mask +} + +// Unset58 will unset the flag bit value at index 58. +func (f Flags64) Unset58() Flags64 { + const mask = Flags64(1) << 58 + return f & ^mask +} + +// Get59 will fetch the flag bit value at index 59. +func (f Flags64) Get59() bool { + const mask = Flags64(1) << 59 + return (f&mask != 0) +} + +// Set59 will set the flag bit value at index 59. +func (f Flags64) Set59() Flags64 { + const mask = Flags64(1) << 59 + return f | mask +} + +// Unset59 will unset the flag bit value at index 59. +func (f Flags64) Unset59() Flags64 { + const mask = Flags64(1) << 59 + return f & ^mask +} + +// Get60 will fetch the flag bit value at index 60. +func (f Flags64) Get60() bool { + const mask = Flags64(1) << 60 + return (f&mask != 0) +} + +// Set60 will set the flag bit value at index 60. +func (f Flags64) Set60() Flags64 { + const mask = Flags64(1) << 60 + return f | mask +} + +// Unset60 will unset the flag bit value at index 60. +func (f Flags64) Unset60() Flags64 { + const mask = Flags64(1) << 60 + return f & ^mask +} + +// Get61 will fetch the flag bit value at index 61. +func (f Flags64) Get61() bool { + const mask = Flags64(1) << 61 + return (f&mask != 0) +} + +// Set61 will set the flag bit value at index 61. +func (f Flags64) Set61() Flags64 { + const mask = Flags64(1) << 61 + return f | mask +} + +// Unset61 will unset the flag bit value at index 61. +func (f Flags64) Unset61() Flags64 { + const mask = Flags64(1) << 61 + return f & ^mask +} + +// Get62 will fetch the flag bit value at index 62. +func (f Flags64) Get62() bool { + const mask = Flags64(1) << 62 + return (f&mask != 0) +} + +// Set62 will set the flag bit value at index 62. +func (f Flags64) Set62() Flags64 { + const mask = Flags64(1) << 62 + return f | mask +} + +// Unset62 will unset the flag bit value at index 62. +func (f Flags64) Unset62() Flags64 { + const mask = Flags64(1) << 62 + return f & ^mask +} + +// Get63 will fetch the flag bit value at index 63. +func (f Flags64) Get63() bool { + const mask = Flags64(1) << 63 + return (f&mask != 0) +} + +// Set63 will set the flag bit value at index 63. +func (f Flags64) Set63() Flags64 { + const mask = Flags64(1) << 63 + return f | mask +} + +// Unset63 will unset the flag bit value at index 63. +func (f Flags64) Unset63() Flags64 { + const mask = Flags64(1) << 63 + return f & ^mask +} + +// String returns a human readable representation of Flags64. +func (f Flags64) String() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = 1 + (len("false ") * 64) - 1 + 1 + buf = make([]byte, prealloc) + + buf[i] = '{' + i++ + + val = f.Get0() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get16() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get17() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get18() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get19() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get20() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get21() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get22() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get23() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get24() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get25() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get26() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get27() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get28() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get29() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get30() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get31() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get32() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get33() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get34() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get35() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get36() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get37() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get38() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get39() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get40() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get41() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get42() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get43() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get44() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get45() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get46() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get47() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get48() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get49() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get50() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get51() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get52() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get53() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get54() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get55() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get56() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get57() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get58() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get59() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get60() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get61() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get62() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get63() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// GoString returns a more verbose human readable representation of Flags64. +func (f Flags64) GoString() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = len("bitutil.Flags64{") + (len("63=false ") * 64) - 1 + 1 + buf = make([]byte, prealloc) + + i += copy(buf[i:], "bitutil.Flags64{") + + val = f.Get0() + i += copy(buf[i:], "0=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get1() + i += copy(buf[i:], "1=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get2() + i += copy(buf[i:], "2=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get3() + i += copy(buf[i:], "3=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get4() + i += copy(buf[i:], "4=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get5() + i += copy(buf[i:], "5=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get6() + i += copy(buf[i:], "6=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get7() + i += copy(buf[i:], "7=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get8() + i += copy(buf[i:], "8=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get9() + i += copy(buf[i:], "9=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get10() + i += copy(buf[i:], "10=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get11() + i += copy(buf[i:], "11=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get12() + i += copy(buf[i:], "12=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get13() + i += copy(buf[i:], "13=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get14() + i += copy(buf[i:], "14=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get15() + i += copy(buf[i:], "15=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get16() + i += copy(buf[i:], "16=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get17() + i += copy(buf[i:], "17=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get18() + i += copy(buf[i:], "18=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get19() + i += copy(buf[i:], "19=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get20() + i += copy(buf[i:], "20=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get21() + i += copy(buf[i:], "21=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get22() + i += copy(buf[i:], "22=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get23() + i += copy(buf[i:], "23=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get24() + i += copy(buf[i:], "24=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get25() + i += copy(buf[i:], "25=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get26() + i += copy(buf[i:], "26=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get27() + i += copy(buf[i:], "27=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get28() + i += copy(buf[i:], "28=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get29() + i += copy(buf[i:], "29=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get30() + i += copy(buf[i:], "30=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get31() + i += copy(buf[i:], "31=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get32() + i += copy(buf[i:], "32=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get33() + i += copy(buf[i:], "33=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get34() + i += copy(buf[i:], "34=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get35() + i += copy(buf[i:], "35=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get36() + i += copy(buf[i:], "36=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get37() + i += copy(buf[i:], "37=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get38() + i += copy(buf[i:], "38=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get39() + i += copy(buf[i:], "39=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get40() + i += copy(buf[i:], "40=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get41() + i += copy(buf[i:], "41=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get42() + i += copy(buf[i:], "42=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get43() + i += copy(buf[i:], "43=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get44() + i += copy(buf[i:], "44=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get45() + i += copy(buf[i:], "45=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get46() + i += copy(buf[i:], "46=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get47() + i += copy(buf[i:], "47=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get48() + i += copy(buf[i:], "48=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get49() + i += copy(buf[i:], "49=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get50() + i += copy(buf[i:], "50=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get51() + i += copy(buf[i:], "51=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get52() + i += copy(buf[i:], "52=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get53() + i += copy(buf[i:], "53=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get54() + i += copy(buf[i:], "54=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get55() + i += copy(buf[i:], "55=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get56() + i += copy(buf[i:], "56=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get57() + i += copy(buf[i:], "57=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get58() + i += copy(buf[i:], "58=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get59() + i += copy(buf[i:], "59=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get60() + i += copy(buf[i:], "60=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get61() + i += copy(buf[i:], "61=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get62() + i += copy(buf[i:], "62=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + val = f.Get63() + i += copy(buf[i:], "63=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +func bool2str(b bool) string { + if b { + return "true" + } + return "false" +} diff --git a/vendor/codeberg.org/gruf/go-bitutil/flag.tpl b/vendor/codeberg.org/gruf/go-bitutil/flag.tpl new file mode 100644 index 000000000..ac00bfa97 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/flag.tpl @@ -0,0 +1,117 @@ +package bitutil + +import ( + "strings" + "unsafe" +) + +{{ range $idx, $size := . }} + +// Flags{{ $size.Size }} is a type-casted unsigned integer with helper +// methods for easily managing up to {{ $size.Size }} bit-flags. +type Flags{{ $size.Size }} uint{{ $size.Size }} + +// Get will fetch the flag bit value at index 'bit'. +func (f Flags{{ $size.Size }}) Get(bit uint8) bool { + mask := Flags{{ $size.Size }}(1) << bit + return (f & mask != 0) +} + +// Set will set the flag bit value at index 'bit'. +func (f Flags{{ $size.Size }}) Set(bit uint8) Flags{{ $size.Size }} { + mask := Flags{{ $size.Size }}(1) << bit + return f | mask +} + +// Unset will unset the flag bit value at index 'bit'. +func (f Flags{{ $size.Size }}) Unset(bit uint8) Flags{{ $size.Size }} { + mask := Flags{{ $size.Size }}(1) << bit + return f & ^mask +} + +{{ range $idx := $size.Bits }} + +// Get{{ $idx }} will fetch the flag bit value at index {{ $idx }}. +func (f Flags{{ $size.Size }}) Get{{ $idx }}() bool { + const mask = Flags{{ $size.Size }}(1) << {{ $idx }} + return (f & mask != 0) +} + +// Set{{ $idx }} will set the flag bit value at index {{ $idx }}. +func (f Flags{{ $size.Size }}) Set{{ $idx }}() Flags{{ $size.Size }} { + const mask = Flags{{ $size.Size }}(1) << {{ $idx }} + return f | mask +} + +// Unset{{ $idx }} will unset the flag bit value at index {{ $idx }}. +func (f Flags{{ $size.Size }}) Unset{{ $idx }}() Flags{{ $size.Size }} { + const mask = Flags{{ $size.Size }}(1) << {{ $idx }} + return f & ^mask +} + +{{ end }} + +// String returns a human readable representation of Flags{{ $size.Size }}. +func (f Flags{{ $size.Size }}) String() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = 1+(len("false ")*{{ $size.Size }})-1+1 + buf = make([]byte, prealloc) + + buf[i] = '{' + i++ + + {{ range $idx := .Bits }} + val = f.Get{{ $idx }}() + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + {{ end }} + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +// GoString returns a more verbose human readable representation of Flags{{ $size.Size }}. +func (f Flags{{ $size.Size }})GoString() string { + var ( + i int + val bool + buf []byte + ) + + // Make a prealloc est. based on longest-possible value + const prealloc = len("bitutil.Flags{{ $size.Size }}{")+(len("{{ sub $size.Size 1 }}=false ")*{{ $size.Size }})-1+1 + buf = make([]byte, prealloc) + + i += copy(buf[i:], "bitutil.Flags{{ $size.Size }}{") + + {{ range $idx := .Bits }} + val = f.Get{{ $idx }}() + i += copy(buf[i:], "{{ $idx }}=") + i += copy(buf[i:], bool2str(val)) + buf[i] = ' ' + i++ + {{ end }} + + buf[i-1] = '}' + buf = buf[:i] + + return *(*string)(unsafe.Pointer(&buf)) +} + +{{ end }} + +func bool2str(b bool) string { + if b { + return "true" + } + return "false" +} \ No newline at end of file diff --git a/vendor/codeberg.org/gruf/go-bitutil/flag_test.tpl b/vendor/codeberg.org/gruf/go-bitutil/flag_test.tpl new file mode 100644 index 000000000..e85cc2dff --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/flag_test.tpl @@ -0,0 +1,98 @@ +package bitutil_test + +import ( + "strings" + "testing" + + "codeberg.org/gruf/go-bytes" +) + +{{ range $idx, $size := . }} + +func TestFlags{{ $size.Size }}Get(t *testing.T) { + var mask, flags bitutil.Flags{{ $size.Size }} + + {{ range $idx := $size.Bits }} + + mask = bitutil.Flags{{ $size.Size }}(1) << {{ $idx }} + + flags = 0 + + flags |= mask + if !flags.Get({{ $idx }}) { + t.Error("failed .Get() set Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + flags = ^bitutil.Flags{{ $size.Size }}(0) + + flags &= ^mask + if flags.Get({{ $idx }}) { + t.Error("failed .Get() unset Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + flags = 0 + + flags |= mask + if !flags.Get{{ $idx }}() { + t.Error("failed .Get{{ $idx }}() set Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + flags = ^bitutil.Flags{{ $size.Size }}(0) + + flags &= ^mask + if flags.Get{{ $idx }}() { + t.Error("failed .Get{{ $idx }}() unset Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + {{ end }} +} + +func TestFlags{{ $size.Size }}Set(t *testing.T) { + var mask, flags bitutil.Flags{{ $size.Size }} + + {{ range $idx := $size.Bits }} + + mask = bitutil.Flags{{ $size.Size }}(1) << {{ $idx }} + + flags = 0 + + flags = flags.Set({{ $idx }}) + if flags & mask == 0 { + t.Error("failed .Set() Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + flags = 0 + + flags = flags.Set{{ $idx }}() + if flags & mask == 0 { + t.Error("failed .Set{{ $idx }}() Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + {{ end }} +} + +func TestFlags{{ $size.Size }}Unset(t *testing.T) { + var mask, flags bitutil.Flags{{ $size.Size }} + + {{ range $idx := $size.Bits }} + + mask = bitutil.Flags{{ $size.Size }}(1) << {{ $idx }} + + flags = ^bitutil.Flags{{ $size.Size }}(0) + + flags = flags.Unset({{ $idx }}) + if flags & mask != 0 { + t.Error("failed .Unset() Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + flags = ^bitutil.Flags{{ $size.Size }}(0) + + flags = flags.Unset{{ $idx }}() + if flags & mask != 0 { + t.Error("failed .Unset{{ $idx }}() Flags{{ $size.Size }} bit at index {{ $idx }}") + } + + {{ end }} +} + +{{ end }} \ No newline at end of file diff --git a/vendor/codeberg.org/gruf/go-bitutil/pack.go b/vendor/codeberg.org/gruf/go-bitutil/pack.go new file mode 100644 index 000000000..2a57d3294 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/pack.go @@ -0,0 +1,85 @@ +package bitutil + +// PackInt8s will pack two signed 8bit integers into an unsigned 16bit integer. +func PackInt8s(i1, i2 int8) uint16 { + const bits = 8 + const mask = (1 << bits) - 1 + return uint16(i1)<> bits), int8(i & mask) +} + +// PackInt16s will pack two signed 16bit integers into an unsigned 32bit integer. +func PackInt16s(i1, i2 int16) uint32 { + const bits = 16 + const mask = (1 << bits) - 1 + return uint32(i1)<> bits), int16(i & mask) +} + +// PackInt32s will pack two signed 32bit integers into an unsigned 64bit integer. +func PackInt32s(i1, i2 int32) uint64 { + const bits = 32 + const mask = (1 << bits) - 1 + return uint64(i1)<> bits), int32(i & mask) +} + +// PackUint8s will pack two unsigned 8bit integers into an unsigned 16bit integer. +func PackUint8s(u1, u2 uint8) uint16 { + const bits = 8 + const mask = (1 << bits) - 1 + return uint16(u1)<> bits), uint8(u & mask) +} + +// PackUint16s will pack two unsigned 16bit integers into an unsigned 32bit integer. +func PackUint16s(u1, u2 uint16) uint32 { + const bits = 16 + const mask = (1 << bits) - 1 + return uint32(u1)<> bits), uint16(u & mask) +} + +// PackUint32s will pack two unsigned 32bit integers into an unsigned 64bit integer. +func PackUint32s(u1, u2 uint32) uint64 { + const bits = 32 + const mask = (1 << bits) - 1 + return uint64(u1)<> bits), uint32(u & mask) +} diff --git a/vendor/codeberg.org/gruf/go-bitutil/test.tpl b/vendor/codeberg.org/gruf/go-bitutil/test.tpl new file mode 100644 index 000000000..4e659d81f --- /dev/null +++ b/vendor/codeberg.org/gruf/go-bitutil/test.tpl @@ -0,0 +1,60 @@ +package atomics_test + +import ( + "atomic" + "unsafe" + "testing" + + "codeberg.org/gruf/go-atomics" +) + +func Test{{ .Name }}StoreLoad(t *testing.T) { + for _, test := range {{ .Name }}Tests { + val := atomics.New{{ .Name }}() + + val.Store(test.V1) + + if !({{ call .Compare "val.Load()" "test.V1" }}) { + t.Fatalf("failed testing .Store and .Load: expect=%v actual=%v", val.Load(), test.V1) + } + + val.Store(test.V2) + + if !({{ call .Compare "val.Load()" "test.V2" }}) { + t.Fatalf("failed testing .Store and .Load: expect=%v actual=%v", val.Load(), test.V2) + } + } +} + +func Test{{ .Name }}CAS(t *testing.T) { + for _, test := range {{ .Name }}Tests { + val := atomics.New{{ .Name }}() + + val.Store(test.V1) + + if val.CAS(test.V2, test.V1) { + t.Fatalf("failed testing negative .CAS: test=%+v state=%v", test, val.Load()) + } + + if !val.CAS(test.V1, test.V2) { + t.Fatalf("failed testing positive .CAS: test=%+v state=%v", test, val.Load()) + } + } +} + +func Test{{ .Name }}Swap(t *testing.T) { + for _, test := range {{ .Name }}Tests { + val := atomics.New{{ .Name }}() + + val.Store(test.V1) + + if !({{ call .Compare "val.Swap(test.V2)" "test.V1" }}) { + t.Fatal("failed testing .Swap") + } + + if !({{ call .Compare "val.Swap(test.V1)" "test.V2" }}) { + t.Fatal("failed testing .Swap") + } + } +} + diff --git a/vendor/modules.txt b/vendor/modules.txt index 1e12dc9e5..e101ac4c6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -215,6 +215,9 @@ code.superseriousbusiness.org/oauth2/v4/generates code.superseriousbusiness.org/oauth2/v4/manage code.superseriousbusiness.org/oauth2/v4/models code.superseriousbusiness.org/oauth2/v4/server +# codeberg.org/gruf/go-bitutil v1.1.0 +## explicit; go 1.19 +codeberg.org/gruf/go-bitutil # codeberg.org/gruf/go-bytesize v1.0.3 ## explicit; go 1.17 codeberg.org/gruf/go-bytesize diff --git a/web/source/nollamas/index.js b/web/source/nollamas/index.js index 4e162182c..e8ae0a75c 100644 --- a/web/source/nollamas/index.js +++ b/web/source/nollamas/index.js @@ -43,18 +43,18 @@ document.addEventListener("DOMContentLoaded", function() { // Read the challenge and difficulty from // data attributes on the nollamas section. + const seed = nollamas.dataset.nollamasSeed; const challenge = nollamas.dataset.nollamasChallenge; - const difficulty = nollamas.dataset.nollamasDifficulty; - console.log("challenge:", challenge); // eslint-disable-line no-console - console.log("difficulty:", difficulty); // eslint-disable-line no-console + console.log("seed:", seed); // eslint-disable-line no-console + console.log("challenge:", challenge); // eslint-disable-line no-console // Prepare the worker with task function. const worker = new Worker("/assets/dist/nollamasworker.js"); const startTime = performance.now(); worker.postMessage({ challenge: challenge, - difficulty: difficulty, + seed: seed, }); // Set the main worker function. diff --git a/web/source/nollamasworker/index.js b/web/source/nollamasworker/index.js index 2762b125e..3c9b043c2 100644 --- a/web/source/nollamasworker/index.js +++ b/web/source/nollamasworker/index.js @@ -19,32 +19,22 @@ import sha256 from "./sha256"; -let compute = async function(challengeStr, diffStr) { +let compute = async function(seedStr, challengeStr) { const textEncoder = new TextEncoder(); - // Get difficulty1 as number and generate - // expected zero ASCII prefix to check for. - const diff1 = parseInt(diffStr, 10); - const zeros = "0".repeat(diff1); - - // Calculate hex encoded prefix required to check solution, where we - // need diff1 no. chars in hex, and hex encoding doubles input length. - const prefixLen = diff1 / 2 + (diff1 % 2 != 0 ? 2 : 0); - let nonce = 0; while (true) { // eslint-disable-line no-constant-condition // Create possible solution string from challenge string + nonce. - const solution = textEncoder.encode(challengeStr + nonce.toString()); + const solution = textEncoder.encode(seedStr + nonce.toString()); - // Generate SHA256 hashsum of solution string, and hex encode the - // necessary prefix length we need to check for a valid solution. - const prefixArray = Array.from(sha256(solution).slice(0, prefixLen)); - const prefixHex = prefixArray.map(b => b.toString(16).padStart(2, "0")).join(""); + // Generate hex encoded SHA256 hashsum of solution. + const hashArray = Array.from(sha256(solution)); + const hashAsHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join(""); - // Check if the hex encoded hash has - // difficulty defined zeroes prefix. - if (prefixHex.startsWith(zeros)) { + // Check whether hex encoded + // solution matches challenge. + if (hashAsHex == challengeStr) { return nonce; } @@ -56,11 +46,8 @@ let compute = async function(challengeStr, diffStr) { onmessage = async function(e) { console.log('worker started'); // eslint-disable-line no-console - const challenge = e.data.challenge; - const difficulty = e.data.difficulty; - - // Compute the nonce that produces solution with args. - let nonce = await compute(challenge, difficulty); + // Compute nonce value that produces 'challenge' for seed. + let nonce = await compute(e.data.seed, e.data.challenge); // Post the solution nonce back to caller. postMessage({ nonce: nonce, done: true }); diff --git a/web/template/nollamas.tmpl b/web/template/nollamas.tmpl index a02fd92f7..a7511e7ae 100644 --- a/web/template/nollamas.tmpl +++ b/web/template/nollamas.tmpl @@ -20,8 +20,8 @@ {{- with . }}

Checking you're not a creepy crawler...