upd: essential/file updated
helper marker updated
This commit is contained in:
parent
b164dfb1e7
commit
bfd7224538
@ -0,0 +1,627 @@
|
|||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Description
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Name:
|
||||||
|
| - Marker
|
||||||
|
|
|
||||||
|
| Purpose:
|
||||||
|
| - Provide a unified utility for generating unique markers through
|
||||||
|
| multiple generation strategies using a single entry point.
|
||||||
|
| - Support time-based, random, and encoded marker generation while
|
||||||
|
| maintaining a consistent output structure, deterministic routing,
|
||||||
|
| and extensible architecture.
|
||||||
|
|
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Instruction
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Guideline:
|
||||||
|
| - Use the time type with an epoch timestamp and instance identifier
|
||||||
|
| to generate distributed time-based markers.
|
||||||
|
| - Use the random type with a desired length and character set to
|
||||||
|
| generate collision-resistant random markers.
|
||||||
|
| - Use the encoded type with source data, output length, character
|
||||||
|
| set, and optional salt to generate deterministic encoded markers.
|
||||||
|
| - Validate the marker type and all type-specific configuration
|
||||||
|
| values before processing.
|
||||||
|
| - Use the unified ObrimMarker entry point to execute marker
|
||||||
|
| generation.
|
||||||
|
|
|
||||||
|
| Example:
|
||||||
|
| - ObrimMarker("time", map[string]any{
|
||||||
|
| "epoch": int64(0),
|
||||||
|
| "instance": "instance-01",
|
||||||
|
| })
|
||||||
|
|
|
||||||
|
| - ObrimMarker("random", map[string]any{
|
||||||
|
| "length": 32,
|
||||||
|
| "charset": "abcdefghijklmnopqrstuvwxyz0123456789",
|
||||||
|
| })
|
||||||
|
|
|
||||||
|
| - ObrimMarker("encoded", map[string]any{
|
||||||
|
| "data": "source-data",
|
||||||
|
| "length": 32,
|
||||||
|
| "charset": "abcdefghijklmnopqrstuvwxyz0123456789",
|
||||||
|
| "salt": "optional-salt",
|
||||||
|
| })
|
||||||
|
|
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Credit
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Contributor:
|
||||||
|
| - Rajon Ahmed
|
||||||
|
| - Blockonite
|
||||||
|
|
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
package marker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Marker type identifiers.
|
||||||
|
obrimMarkerTypeTime = "time"
|
||||||
|
obrimMarkerTypeRandom = "random"
|
||||||
|
obrimMarkerTypeEncoded = "encoded"
|
||||||
|
|
||||||
|
// Default marker configuration values.
|
||||||
|
obrimMarkerDefaultEpoch int64 = 0
|
||||||
|
obrimMarkerDefaultCharset string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
obrimMarkerDefaultLength int = 32
|
||||||
|
|
||||||
|
// Marker result codes.
|
||||||
|
obrimMarkerSuccessTime = "SUCCESS_TIME_MARKER_GENERATED"
|
||||||
|
obrimMarkerSuccessRandom = "SUCCESS_RANDOM_MARKER_GENERATED"
|
||||||
|
obrimMarkerSuccessEncoded = "SUCCESS_ENCODED_MARKER_GENERATED"
|
||||||
|
|
||||||
|
// Marker failure codes.
|
||||||
|
obrimMarkerFailureInvalidType = "FAILURE_INVALID_TYPE"
|
||||||
|
obrimMarkerFailureInvalidConfig = "FAILURE_INVALID_CONFIG"
|
||||||
|
obrimMarkerFailureInvalidEpoch = "FAILURE_INVALID_EPOCH"
|
||||||
|
obrimMarkerFailureInvalidInstance = "FAILURE_INVALID_INSTANCE"
|
||||||
|
obrimMarkerFailureInvalidLength = "FAILURE_INVALID_LENGTH"
|
||||||
|
obrimMarkerFailureInvalidCharset = "FAILURE_INVALID_CHARSET"
|
||||||
|
obrimMarkerFailureEmptySource = "FAILURE_EMPTY_SOURCE"
|
||||||
|
obrimMarkerFailureInvalidEncodingConfig = "FAILURE_INVALID_ENCODING_CONFIG"
|
||||||
|
obrimMarkerFailureGenerationError = "FAILURE_GENERATION_ERROR"
|
||||||
|
)
|
||||||
|
|
||||||
|
type obrimMarkerOutput struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Payload any `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerTimePayload struct {
|
||||||
|
Marker string `json:"marker"`
|
||||||
|
Epoch int64 `json:"epoch"`
|
||||||
|
Instance string `json:"instance"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerRandomPayload struct {
|
||||||
|
Marker string `json:"marker"`
|
||||||
|
Length int `json:"length"`
|
||||||
|
Charset string `json:"charset"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerEncodedPayload struct {
|
||||||
|
Marker string `json:"marker"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Length int `json:"length"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerTimeConfig struct {
|
||||||
|
Epoch int64
|
||||||
|
Instance string
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerRandomConfig struct {
|
||||||
|
Length int
|
||||||
|
Charset string
|
||||||
|
}
|
||||||
|
|
||||||
|
type obrimMarkerEncodedConfig struct {
|
||||||
|
Data string
|
||||||
|
Length int
|
||||||
|
Charset string
|
||||||
|
Salt string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObrimMarker generates a marker using the requested generation strategy.
|
||||||
|
func ObrimMarker(typeName string, config map[string]any) map[string]any {
|
||||||
|
if code := obrimMarkerValidateInput(typeName, config); code != "" {
|
||||||
|
return obrimMarkerBuildOutput(false, code, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload, code := obrimMarkerRouteRequest(typeName, config)
|
||||||
|
if code != "" {
|
||||||
|
return obrimMarkerBuildOutput(false, code, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerBuildOutput(true, code, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerValidateInput validates the requested marker type and configuration.
|
||||||
|
func obrimMarkerValidateInput(typeName string, config map[string]any) string {
|
||||||
|
if config == nil {
|
||||||
|
return obrimMarkerFailureInvalidConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
switch typeName {
|
||||||
|
case obrimMarkerTypeTime:
|
||||||
|
if code := obrimMarkerValidateTime(config); code != "" {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
case obrimMarkerTypeRandom:
|
||||||
|
if code := obrimMarkerValidateRandom(config); code != "" {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
case obrimMarkerTypeEncoded:
|
||||||
|
if code := obrimMarkerValidateEncoded(config); code != "" {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return obrimMarkerFailureInvalidType
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerRouteRequest routes the request to its type-specific workflow.
|
||||||
|
func obrimMarkerRouteRequest(typeName string, config map[string]any) (any, string) {
|
||||||
|
switch typeName {
|
||||||
|
case obrimMarkerTypeTime:
|
||||||
|
return obrimMarkerTime(config)
|
||||||
|
case obrimMarkerTypeRandom:
|
||||||
|
return obrimMarkerRandom(config)
|
||||||
|
case obrimMarkerTypeEncoded:
|
||||||
|
return obrimMarkerEncoded(config)
|
||||||
|
default:
|
||||||
|
return nil, obrimMarkerFailureInvalidType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerBuildOutput builds the standardized utility output.
|
||||||
|
func obrimMarkerBuildOutput(status bool, code string, payload any) map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"status": status,
|
||||||
|
"code": code,
|
||||||
|
"payload": payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerTime executes the time marker workflow.
|
||||||
|
func obrimMarkerTime(config map[string]any) (any, string) {
|
||||||
|
markerConfig, code := obrimMarkerTimeConfig(config)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
marker, code := obrimMarkerTimeGenerate(markerConfig)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerTimePayload{
|
||||||
|
Marker: marker,
|
||||||
|
Epoch: markerConfig.Epoch,
|
||||||
|
Instance: markerConfig.Instance,
|
||||||
|
}, obrimMarkerSuccessTime
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerValidateTime validates time marker configuration.
|
||||||
|
func obrimMarkerValidateTime(config map[string]any) string {
|
||||||
|
epoch := obrimMarkerDefaultEpoch
|
||||||
|
if value, exists := config["epoch"]; exists {
|
||||||
|
parsed, ok := obrimMarkerInt64(value)
|
||||||
|
if !ok || parsed < 0 {
|
||||||
|
return obrimMarkerFailureInvalidEpoch
|
||||||
|
}
|
||||||
|
epoch = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if epoch > time.Now().UnixNano() {
|
||||||
|
return obrimMarkerFailureInvalidEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
instance, exists := config["instance"]
|
||||||
|
if !exists {
|
||||||
|
return obrimMarkerFailureInvalidInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceValue, ok := instance.(string)
|
||||||
|
if !ok || strings.TrimSpace(instanceValue) == "" {
|
||||||
|
return obrimMarkerFailureInvalidInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerTimeConfig builds the normalized time marker configuration.
|
||||||
|
func obrimMarkerTimeConfig(config map[string]any) (obrimMarkerTimeConfig, string) {
|
||||||
|
epoch := obrimMarkerDefaultEpoch
|
||||||
|
if value, exists := config["epoch"]; exists {
|
||||||
|
parsed, ok := obrimMarkerInt64(value)
|
||||||
|
if !ok || parsed < 0 || parsed > time.Now().UnixNano() {
|
||||||
|
return obrimMarkerTimeConfig{}, obrimMarkerFailureInvalidEpoch
|
||||||
|
}
|
||||||
|
epoch = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
instance, ok := config["instance"].(string)
|
||||||
|
if !ok || strings.TrimSpace(instance) == "" {
|
||||||
|
return obrimMarkerTimeConfig{}, obrimMarkerFailureInvalidInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerTimeConfig{
|
||||||
|
Epoch: epoch,
|
||||||
|
Instance: strings.TrimSpace(instance),
|
||||||
|
}, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerTimeGenerate generates a distributed time-based marker.
|
||||||
|
func obrimMarkerTimeGenerate(config obrimMarkerTimeConfig) (string, string) {
|
||||||
|
now := time.Now().UnixNano()
|
||||||
|
elapsed := now - config.Epoch
|
||||||
|
|
||||||
|
if elapsed < 0 {
|
||||||
|
return "", obrimMarkerFailureInvalidEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
marker := fmt.Sprintf(
|
||||||
|
"%x-%s",
|
||||||
|
elapsed,
|
||||||
|
config.Instance,
|
||||||
|
)
|
||||||
|
|
||||||
|
return marker, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerRandom executes the random marker workflow.
|
||||||
|
func obrimMarkerRandom(config map[string]any) (any, string) {
|
||||||
|
markerConfig, code := obrimMarkerRandomConfig(config)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
marker, code := obrimMarkerRandomGenerate(markerConfig)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerRandomPayload{
|
||||||
|
Marker: marker,
|
||||||
|
Length: markerConfig.Length,
|
||||||
|
Charset: markerConfig.Charset,
|
||||||
|
}, obrimMarkerSuccessRandom
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerValidateRandom validates random marker configuration.
|
||||||
|
func obrimMarkerValidateRandom(config map[string]any) string {
|
||||||
|
length := obrimMarkerDefaultLength
|
||||||
|
if value, exists := config["length"]; exists {
|
||||||
|
parsed, ok := obrimMarkerInt(value)
|
||||||
|
if !ok || parsed <= 0 {
|
||||||
|
return obrimMarkerFailureInvalidLength
|
||||||
|
}
|
||||||
|
length = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if length <= 0 {
|
||||||
|
return obrimMarkerFailureInvalidLength
|
||||||
|
}
|
||||||
|
|
||||||
|
charset := obrimMarkerDefaultCharset
|
||||||
|
if value, exists := config["charset"]; exists {
|
||||||
|
parsed, ok := value.(string)
|
||||||
|
if !ok || parsed == "" {
|
||||||
|
return obrimMarkerFailureInvalidCharset
|
||||||
|
}
|
||||||
|
charset = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if charset == "" {
|
||||||
|
return obrimMarkerFailureInvalidCharset
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerRandomConfig builds the normalized random marker configuration.
|
||||||
|
func obrimMarkerRandomConfig(config map[string]any) (obrimMarkerRandomConfig, string) {
|
||||||
|
length := obrimMarkerDefaultLength
|
||||||
|
if value, exists := config["length"]; exists {
|
||||||
|
parsed, ok := obrimMarkerInt(value)
|
||||||
|
if !ok || parsed <= 0 {
|
||||||
|
return obrimMarkerRandomConfig{}, obrimMarkerFailureInvalidLength
|
||||||
|
}
|
||||||
|
length = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
charset := obrimMarkerDefaultCharset
|
||||||
|
if value, exists := config["charset"]; exists {
|
||||||
|
parsed, ok := value.(string)
|
||||||
|
if !ok || parsed == "" {
|
||||||
|
return obrimMarkerRandomConfig{}, obrimMarkerFailureInvalidCharset
|
||||||
|
}
|
||||||
|
charset = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if charset == "" {
|
||||||
|
return obrimMarkerRandomConfig{}, obrimMarkerFailureInvalidCharset
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerRandomConfig{
|
||||||
|
Length: length,
|
||||||
|
Charset: charset,
|
||||||
|
}, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerRandomGenerate generates a cryptographically secure random marker.
|
||||||
|
func obrimMarkerRandomGenerate(config obrimMarkerRandomConfig) (string, string) {
|
||||||
|
characters := []rune(config.Charset)
|
||||||
|
if len(characters) == 0 {
|
||||||
|
return "", obrimMarkerFailureInvalidCharset
|
||||||
|
}
|
||||||
|
|
||||||
|
randomBytes := make([]byte, config.Length)
|
||||||
|
if _, err := rand.Read(randomBytes); err != nil {
|
||||||
|
return "", obrimMarkerFailureGenerationError
|
||||||
|
}
|
||||||
|
|
||||||
|
marker := make([]rune, config.Length)
|
||||||
|
for index := range marker {
|
||||||
|
marker[index] = characters[int(randomBytes[index])%len(characters)]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(marker), ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerEncoded executes the encoded marker workflow.
|
||||||
|
func obrimMarkerEncoded(config map[string]any) (any, string) {
|
||||||
|
markerConfig, code := obrimMarkerEncodedConfig(config)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
marker, code := obrimMarkerEncodedGenerate(markerConfig)
|
||||||
|
if code != "" {
|
||||||
|
return nil, code
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerEncodedPayload{
|
||||||
|
Marker: marker,
|
||||||
|
Source: markerConfig.Data,
|
||||||
|
Length: markerConfig.Length,
|
||||||
|
}, obrimMarkerSuccessEncoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerValidateEncoded validates encoded marker configuration.
|
||||||
|
func obrimMarkerValidateEncoded(config map[string]any) string {
|
||||||
|
data, exists := config["data"]
|
||||||
|
if !exists {
|
||||||
|
return obrimMarkerFailureEmptySource
|
||||||
|
}
|
||||||
|
|
||||||
|
dataValue, ok := data.(string)
|
||||||
|
if !ok || strings.TrimSpace(dataValue) == "" {
|
||||||
|
return obrimMarkerFailureEmptySource
|
||||||
|
}
|
||||||
|
|
||||||
|
length := obrimMarkerDefaultLength
|
||||||
|
if value, exists := config["length"]; exists {
|
||||||
|
parsed, ok := obrimMarkerInt(value)
|
||||||
|
if !ok || parsed <= 0 {
|
||||||
|
return obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
length = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if length <= 0 {
|
||||||
|
return obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
charset := obrimMarkerDefaultCharset
|
||||||
|
if value, exists := config["charset"]; exists {
|
||||||
|
parsed, ok := value.(string)
|
||||||
|
if !ok || parsed == "" {
|
||||||
|
return obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
charset = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if charset == "" {
|
||||||
|
return obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
if value, exists := config["salt"]; exists {
|
||||||
|
if _, ok := value.(string); !ok {
|
||||||
|
return obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = length
|
||||||
|
_ = charset
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerEncodedConfig builds the normalized encoded marker configuration.
|
||||||
|
func obrimMarkerEncodedConfig(config map[string]any) (obrimMarkerEncodedConfig, string) {
|
||||||
|
data, ok := config["data"].(string)
|
||||||
|
if !ok || strings.TrimSpace(data) == "" {
|
||||||
|
return obrimMarkerEncodedConfig{}, obrimMarkerFailureEmptySource
|
||||||
|
}
|
||||||
|
|
||||||
|
length := obrimMarkerDefaultLength
|
||||||
|
if value, exists := config["length"]; exists {
|
||||||
|
parsed, valid := obrimMarkerInt(value)
|
||||||
|
if !valid || parsed <= 0 {
|
||||||
|
return obrimMarkerEncodedConfig{}, obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
length = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
charset := obrimMarkerDefaultCharset
|
||||||
|
if value, exists := config["charset"]; exists {
|
||||||
|
parsed, valid := value.(string)
|
||||||
|
if !valid || parsed == "" {
|
||||||
|
return obrimMarkerEncodedConfig{}, obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
charset = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
salt := ""
|
||||||
|
if value, exists := config["salt"]; exists {
|
||||||
|
parsed, valid := value.(string)
|
||||||
|
if !valid {
|
||||||
|
return obrimMarkerEncodedConfig{}, obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
salt = parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
return obrimMarkerEncodedConfig{
|
||||||
|
Data: data,
|
||||||
|
Length: length,
|
||||||
|
Charset: charset,
|
||||||
|
Salt: salt,
|
||||||
|
}, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerEncodedGenerate generates a deterministic encoded marker.
|
||||||
|
func obrimMarkerEncodedGenerate(config obrimMarkerEncodedConfig) (string, string) {
|
||||||
|
characters := []rune(config.Charset)
|
||||||
|
if len(characters) == 0 {
|
||||||
|
return "", obrimMarkerFailureInvalidEncodingConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
source := config.Data + config.Salt
|
||||||
|
digest := sha256.Sum256([]byte(source))
|
||||||
|
|
||||||
|
seed := binary.BigEndian.Uint64(digest[:8])
|
||||||
|
marker := make([]rune, config.Length)
|
||||||
|
|
||||||
|
for index := range marker {
|
||||||
|
seed = seed*6364136223846793005 + 1442695040888963407
|
||||||
|
marker[index] = characters[int(seed%uint64(len(characters)))]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(marker), ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerInt converts a supported value to int.
|
||||||
|
func obrimMarkerInt(value any) (int, bool) {
|
||||||
|
switch parsed := value.(type) {
|
||||||
|
case int:
|
||||||
|
return parsed, true
|
||||||
|
case int8:
|
||||||
|
return int(parsed), true
|
||||||
|
case int16:
|
||||||
|
return int(parsed), true
|
||||||
|
case int32:
|
||||||
|
return int(parsed), true
|
||||||
|
case int64:
|
||||||
|
return int(parsed), true
|
||||||
|
case uint:
|
||||||
|
return int(parsed), true
|
||||||
|
case uint8:
|
||||||
|
return int(parsed), true
|
||||||
|
case uint16:
|
||||||
|
return int(parsed), true
|
||||||
|
case uint32:
|
||||||
|
return int(parsed), true
|
||||||
|
case uint64:
|
||||||
|
if uint64(int(parsed)) != parsed {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int(parsed), true
|
||||||
|
case float32:
|
||||||
|
if float32(int(parsed)) != parsed {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int(parsed), true
|
||||||
|
case float64:
|
||||||
|
if float64(int(parsed)) != parsed {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int(parsed), true
|
||||||
|
case string:
|
||||||
|
converted, err := strconv.Atoi(parsed)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return converted, true
|
||||||
|
default:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// obrimMarkerInt64 converts a supported value to int64.
|
||||||
|
func obrimMarkerInt64(value any) (int64, bool) {
|
||||||
|
switch parsed := value.(type) {
|
||||||
|
case int:
|
||||||
|
return int64(parsed), true
|
||||||
|
case int8:
|
||||||
|
return int64(parsed), true
|
||||||
|
case int16:
|
||||||
|
return int64(parsed), true
|
||||||
|
case int32:
|
||||||
|
return int64(parsed), true
|
||||||
|
case int64:
|
||||||
|
return parsed, true
|
||||||
|
case uint:
|
||||||
|
if uint64(int64(parsed)) != uint64(parsed) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int64(parsed), true
|
||||||
|
case uint8:
|
||||||
|
return int64(parsed), true
|
||||||
|
case uint16:
|
||||||
|
return int64(parsed), true
|
||||||
|
case uint32:
|
||||||
|
return int64(parsed), true
|
||||||
|
case uint64:
|
||||||
|
if parsed > uint64(^uint64(0)>>1) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int64(parsed), true
|
||||||
|
case float32:
|
||||||
|
if float32(int64(parsed)) != parsed {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int64(parsed), true
|
||||||
|
case float64:
|
||||||
|
if float64(int64(parsed)) != parsed {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return int64(parsed), true
|
||||||
|
case string:
|
||||||
|
converted, err := strconv.ParseInt(parsed, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return converted, true
|
||||||
|
default:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user