366 lines
8.7 KiB
Go
366 lines
8.7 KiB
Go
package marker
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"math"
|
|
"strings"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// Purpose: Supported marker generation types.
|
|
const (
|
|
obrimMarkerTypeTime = "time"
|
|
obrimMarkerTypeRandom = "random"
|
|
obrimMarkerTypeEncoded = "encoded"
|
|
)
|
|
|
|
// Purpose: Default random marker length.
|
|
const obrimMarkerDefaultRandomLength = 16
|
|
|
|
// Purpose: Default encoded marker length.
|
|
const obrimMarkerDefaultEncodedLength = 16
|
|
|
|
// Purpose: Default character set used for marker generation.
|
|
const obrimMarkerDefaultCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
|
|
// Purpose: Sequence counter used to improve uniqueness for time markers.
|
|
var obrimMarkerSequence uint64
|
|
|
|
// Purpose: Standardized utility response structure.
|
|
type obrimMarkerResponse struct {
|
|
Status bool `json:"status"`
|
|
Code string `json:"code"`
|
|
Payload any `json:"payload"`
|
|
}
|
|
|
|
// Purpose: Time marker payload structure.
|
|
type obrimMarkerTimePayload struct {
|
|
Marker string `json:"marker"`
|
|
Epoch int64 `json:"epoch"`
|
|
Instance string `json:"instance"`
|
|
}
|
|
|
|
// Purpose: Random marker payload structure.
|
|
type obrimMarkerRandomPayload struct {
|
|
Marker string `json:"marker"`
|
|
Length int `json:"length"`
|
|
Charset string `json:"charset"`
|
|
}
|
|
|
|
// Purpose: Encoded marker payload structure.
|
|
type obrimMarkerEncodedPayload struct {
|
|
Marker string `json:"marker"`
|
|
Source string `json:"source"`
|
|
Length int `json:"length"`
|
|
}
|
|
|
|
// Purpose: Generate markers using the selected marker strategy.
|
|
func ObrimMarker(markerType string, config map[string]any) map[string]any {
|
|
obrimMarkerLog("initialization", markerType)
|
|
|
|
if config == nil {
|
|
config = map[string]any{}
|
|
}
|
|
|
|
if err := obrimMarkerValidateType(markerType); err != nil {
|
|
obrimMarkerLog("validation_failure", err.Error())
|
|
return obrimMarkerBuildResponse(false, "FAILED_INVALID_TYPE", nil)
|
|
}
|
|
|
|
response := obrimMarkerRoute(markerType, config)
|
|
|
|
if status, ok := response["status"].(bool); ok && status {
|
|
obrimMarkerLog("success", markerType)
|
|
} else {
|
|
obrimMarkerLog("failure", markerType)
|
|
}
|
|
|
|
return response
|
|
}
|
|
|
|
// Purpose: Validate supported marker generation types.
|
|
func obrimMarkerValidateType(markerType string) error {
|
|
switch strings.ToLower(strings.TrimSpace(markerType)) {
|
|
case obrimMarkerTypeTime,
|
|
obrimMarkerTypeRandom,
|
|
obrimMarkerTypeEncoded:
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("unsupported marker type")
|
|
}
|
|
}
|
|
|
|
// Purpose: Route execution to the selected marker generation workflow.
|
|
func obrimMarkerRoute(markerType string, config map[string]any) map[string]any {
|
|
switch strings.ToLower(strings.TrimSpace(markerType)) {
|
|
case obrimMarkerTypeTime:
|
|
return obrimMarkerTime(config)
|
|
|
|
case obrimMarkerTypeRandom:
|
|
return obrimMarkerRandom(config)
|
|
|
|
case obrimMarkerTypeEncoded:
|
|
return obrimMarkerEncoded(config)
|
|
|
|
default:
|
|
return obrimMarkerBuildResponse(false, "FAILED_INVALID_TYPE", nil)
|
|
}
|
|
}
|
|
|
|
// Purpose: Build standardized success and error responses.
|
|
func obrimMarkerBuildResponse(status bool, code string, payload any) map[string]any {
|
|
return map[string]any{
|
|
"status": status,
|
|
"code": code,
|
|
"payload": payload,
|
|
}
|
|
}
|
|
|
|
// Purpose: Generate time-based unique markers.
|
|
func obrimMarkerTime(config map[string]any) map[string]any {
|
|
epoch, instance, err := obrimMarkerValidateTime(config)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_TIME_VALIDATION", nil)
|
|
}
|
|
|
|
marker, err := obrimMarkerTimeGenerate(epoch, instance)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_TIME_GENERATION", nil)
|
|
}
|
|
|
|
payload := obrimMarkerTimePayload{
|
|
Marker: marker,
|
|
Epoch: epoch,
|
|
Instance: instance,
|
|
}
|
|
|
|
return obrimMarkerBuildResponse(true, "SUCCESS_TIME_GENERATED", payload)
|
|
}
|
|
|
|
// Purpose: Validate time marker configuration parameters.
|
|
func obrimMarkerValidateTime(config map[string]any) (int64, string, error) {
|
|
epoch := int64(0)
|
|
instance := ""
|
|
|
|
if value, exists := config["epoch"]; exists {
|
|
switch v := value.(type) {
|
|
case int64:
|
|
epoch = v
|
|
case int:
|
|
epoch = int64(v)
|
|
case float64:
|
|
epoch = int64(v)
|
|
default:
|
|
return 0, "", fmt.Errorf("invalid epoch")
|
|
}
|
|
|
|
if epoch < 0 {
|
|
return 0, "", fmt.Errorf("invalid epoch")
|
|
}
|
|
}
|
|
|
|
if value, exists := config["instance"]; exists {
|
|
instance, _ = value.(string)
|
|
}
|
|
|
|
if strings.TrimSpace(instance) == "" {
|
|
instance = "default"
|
|
}
|
|
|
|
return epoch, instance, nil
|
|
}
|
|
|
|
// Purpose: Produce the final time-based marker value.
|
|
func obrimMarkerTimeGenerate(epoch int64, instance string) (string, error) {
|
|
now := time.Now().UnixMilli()
|
|
|
|
if epoch > now {
|
|
return "", fmt.Errorf("epoch exceeds current time")
|
|
}
|
|
|
|
timestamp := now - epoch
|
|
|
|
sequence := atomic.AddUint64(&obrimMarkerSequence, 1)
|
|
|
|
return fmt.Sprintf(
|
|
"%X-%s-%X",
|
|
timestamp,
|
|
strings.ToUpper(instance),
|
|
sequence,
|
|
), nil
|
|
}
|
|
|
|
// Purpose: Generate random collision-resistant markers.
|
|
func obrimMarkerRandom(config map[string]any) map[string]any {
|
|
length, charset, err := obrimMarkerValidateRandom(config)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_RANDOM_VALIDATION", nil)
|
|
}
|
|
|
|
marker, err := obrimMarkerRandomGenerate(length, charset)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_RANDOM_GENERATION", nil)
|
|
}
|
|
|
|
payload := obrimMarkerRandomPayload{
|
|
Marker: marker,
|
|
Length: length,
|
|
Charset: charset,
|
|
}
|
|
|
|
return obrimMarkerBuildResponse(true, "SUCCESS_RANDOM_GENERATED", payload)
|
|
}
|
|
|
|
// Purpose: Validate random marker configuration parameters.
|
|
func obrimMarkerValidateRandom(config map[string]any) (int, string, error) {
|
|
length := obrimMarkerDefaultRandomLength
|
|
charset := obrimMarkerDefaultCharset
|
|
|
|
if value, exists := config["length"]; exists {
|
|
switch v := value.(type) {
|
|
case int:
|
|
length = v
|
|
case int64:
|
|
length = int(v)
|
|
case float64:
|
|
length = int(v)
|
|
default:
|
|
return 0, "", fmt.Errorf("invalid length")
|
|
}
|
|
}
|
|
|
|
if value, exists := config["charset"]; exists {
|
|
if text, ok := value.(string); ok {
|
|
charset = text
|
|
}
|
|
}
|
|
|
|
if length <= 0 {
|
|
return 0, "", fmt.Errorf("invalid length")
|
|
}
|
|
|
|
if len(charset) == 0 {
|
|
return 0, "", fmt.Errorf("invalid charset")
|
|
}
|
|
|
|
return length, charset, nil
|
|
}
|
|
|
|
// Purpose: Produce the final random marker value.
|
|
func obrimMarkerRandomGenerate(length int, charset string) (string, error) {
|
|
buffer := make([]byte, length)
|
|
|
|
for index := 0; index < length; index++ {
|
|
randomValue := make([]byte, 8)
|
|
|
|
if _, err := rand.Read(randomValue); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
position := binary.BigEndian.Uint64(randomValue) % uint64(len(charset))
|
|
buffer[index] = charset[position]
|
|
}
|
|
|
|
return string(buffer), nil
|
|
}
|
|
|
|
// Purpose: Generate deterministic encoded markers.
|
|
func obrimMarkerEncoded(config map[string]any) map[string]any {
|
|
data, length, charset, salt, err := obrimMarkerValidateEncoded(config)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_ENCODED_VALIDATION", nil)
|
|
}
|
|
|
|
marker, err := obrimMarkerEncodedGenerate(data, length, charset, salt)
|
|
if err != nil {
|
|
return obrimMarkerBuildResponse(false, "FAILED_ENCODED_GENERATION", nil)
|
|
}
|
|
|
|
payload := obrimMarkerEncodedPayload{
|
|
Marker: marker,
|
|
Source: data,
|
|
Length: length,
|
|
}
|
|
|
|
return obrimMarkerBuildResponse(true, "SUCCESS_ENCODED_GENERATED", payload)
|
|
}
|
|
|
|
// Purpose: Validate encoded marker configuration parameters.
|
|
func obrimMarkerValidateEncoded(config map[string]any) (string, int, string, string, error) {
|
|
data := ""
|
|
length := obrimMarkerDefaultEncodedLength
|
|
charset := obrimMarkerDefaultCharset
|
|
salt := ""
|
|
|
|
if value, exists := config["data"]; exists {
|
|
data, _ = value.(string)
|
|
}
|
|
|
|
if strings.TrimSpace(data) == "" {
|
|
return "", 0, "", "", fmt.Errorf("missing data")
|
|
}
|
|
|
|
if value, exists := config["length"]; exists {
|
|
switch v := value.(type) {
|
|
case int:
|
|
length = v
|
|
case int64:
|
|
length = int(v)
|
|
case float64:
|
|
length = int(v)
|
|
default:
|
|
return "", 0, "", "", fmt.Errorf("invalid length")
|
|
}
|
|
}
|
|
|
|
if value, exists := config["charset"]; exists {
|
|
if text, ok := value.(string); ok {
|
|
charset = text
|
|
}
|
|
}
|
|
|
|
if value, exists := config["salt"]; exists {
|
|
salt, _ = value.(string)
|
|
}
|
|
|
|
if length <= 0 {
|
|
return "", 0, "", "", fmt.Errorf("invalid length")
|
|
}
|
|
|
|
if len(charset) == 0 {
|
|
return "", 0, "", "", fmt.Errorf("invalid charset")
|
|
}
|
|
|
|
return data, length, charset, salt, nil
|
|
}
|
|
|
|
// Purpose: Produce the final encoded marker value.
|
|
func obrimMarkerEncodedGenerate(
|
|
data string,
|
|
length int,
|
|
charset string,
|
|
salt string,
|
|
) (string, error) {
|
|
hash := sha256.Sum256([]byte(data + salt))
|
|
|
|
output := make([]byte, length)
|
|
|
|
for index := 0; index < length; index++ {
|
|
hashIndex := index % len(hash)
|
|
position := int(math.Abs(float64(hash[hashIndex]))) % len(charset)
|
|
output[index] = charset[position]
|
|
}
|
|
|
|
return string(output), nil
|
|
}
|
|
|
|
// Purpose: Log utility lifecycle events.
|
|
func obrimMarkerLog(event string, message string) {
|
|
_ = event
|
|
_ = message
|
|
}
|