github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/uuid/uuid.go (about)

     1  package uuid
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"encoding/hex"
     7  
     8  	"github.com/v2fly/v2ray-core/v5/common"
     9  	"github.com/v2fly/v2ray-core/v5/common/errors"
    10  )
    11  
    12  var byteGroups = []int{8, 4, 4, 4, 12}
    13  
    14  type UUID [16]byte
    15  
    16  // String returns the string representation of this UUID.
    17  func (u *UUID) String() string {
    18  	bytes := u.Bytes()
    19  	result := hex.EncodeToString(bytes[0 : byteGroups[0]/2])
    20  	start := byteGroups[0] / 2
    21  	for i := 1; i < len(byteGroups); i++ {
    22  		nBytes := byteGroups[i] / 2
    23  		result += "-"
    24  		result += hex.EncodeToString(bytes[start : start+nBytes])
    25  		start += nBytes
    26  	}
    27  	return result
    28  }
    29  
    30  // Bytes returns the bytes representation of this UUID.
    31  func (u *UUID) Bytes() []byte {
    32  	return u[:]
    33  }
    34  
    35  // Equals returns true if this UUID equals another UUID by value.
    36  func (u *UUID) Equals(another *UUID) bool {
    37  	if u == nil && another == nil {
    38  		return true
    39  	}
    40  	if u == nil || another == nil {
    41  		return false
    42  	}
    43  	return bytes.Equal(u.Bytes(), another.Bytes())
    44  }
    45  
    46  // New creates a UUID with random value.
    47  func New() UUID {
    48  	var uuid UUID
    49  	common.Must2(rand.Read(uuid.Bytes()))
    50  	return uuid
    51  }
    52  
    53  // ParseBytes converts a UUID in byte form to object.
    54  func ParseBytes(b []byte) (UUID, error) {
    55  	var uuid UUID
    56  	if len(b) != 16 {
    57  		return uuid, errors.New("invalid UUID: ", b)
    58  	}
    59  	copy(uuid[:], b)
    60  	return uuid, nil
    61  }
    62  
    63  // ParseString converts a UUID in string form to object.
    64  func ParseString(str string) (UUID, error) {
    65  	var uuid UUID
    66  
    67  	text := []byte(str)
    68  	if len(text) < 32 {
    69  		return uuid, errors.New("invalid UUID: ", str)
    70  	}
    71  
    72  	b := uuid.Bytes()
    73  
    74  	for _, byteGroup := range byteGroups {
    75  		if text[0] == '-' {
    76  			text = text[1:]
    77  		}
    78  
    79  		if _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup]); err != nil {
    80  			return uuid, err
    81  		}
    82  
    83  		text = text[byteGroup:]
    84  		b = b[byteGroup/2:]
    85  	}
    86  
    87  	return uuid, nil
    88  }