github.com/EagleQL/Xray-core@v1.4.3/common/uuid/uuid.go (about)

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