func NewV5(ns UUID, name string) UUID {
	u := newFromHash(sha1.New(), ns, name)
	u.SetVersion(5)
	u.SetVariant()
	return u
}
NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
package uuid
import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"database/sql/driver"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"hash"
	"net"
	"os"
	"sync"
	"time"
)
const (
	VariantNCS = iota
	VariantRFC4122
	VariantMicrosoft
	VariantFuture
)
const (
	DomainPerson = iota
	DomainGroup
	DomainOrg
)
const epochStart = 122192928000000000
const dash byte = '-'
var (
	storageMutex  sync.Mutex
	storageOnce   sync.Once
	epochFunc     = unixTimeFunc
	clockSequence uint16
	lastTime      uint64
	hardwareAddr  [6]byte
	posixUID      = uint32(os.Getuid())
	posixGID      = uint32(os.Getgid())
)
var (
	urnPrefix  = []byte("urn:uuid:")
	byteGroups = []int{8, 4, 4, 4, 12}
)
func initClockSequence() {
	buf := make([]byte, 2)
	safeRandom(buf)
	clockSequence = binary.BigEndian.Uint16(buf)
}
func initHardwareAddr() {
	interfaces, err := net.Interfaces()
	if err == nil {
		for _, iface := range interfaces {
			if len(iface.HardwareAddr) >= 6 {
				copy(hardwareAddr[:], iface.HardwareAddr)
				return
			}
		}
	}
	safeRandom(hardwareAddr[:])
	hardwareAddr[0] |= 0x01
}
func initStorage() {
	initClockSequence()
	initHardwareAddr()
}
func safeRandom(dest []byte) {
	if _, err := rand.Read(dest); err != nil {
		panic(err)
	}
}
func unixTimeFunc() uint64 {
	return epochStart + uint64(time.Now().UnixNano()/100)
}
type UUID [16]byte
var Nil = UUID{}
var (
	NamespaceDNS, _  = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
	NamespaceURL, _  = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
	NamespaceOID, _  = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
	NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
)
func And(u1 UUID, u2 UUID) UUID {
	u := UUID{}
	for i := 0; i < 16; i++ {
		u[i] = u1[i] & u2[i]
	}
	return u
}
func Or(u1 UUID, u2 UUID) UUID {
	u := UUID{}
	for i := 0; i < 16; i++ {
		u[i] = u1[i] | u2[i]
	}
	return u
}
func Equal(u1 UUID, u2 UUID) bool {
	return bytes.Equal(u1[:], u2[:])
}
func (u UUID) Version() uint {
	return uint(u[6] >> 4)
}
func (u UUID) Variant() uint {
	switch {
	case (u[8] & 0x80) == 0x00:
		return VariantNCS
	case (u[8]&0xc0)|0x80 == 0x80:
		return VariantRFC4122
	case (u[8]&0xe0)|0xc0 == 0xc0:
		return VariantMicrosoft
	}
	return VariantFuture
}
func (u UUID) Bytes() []byte {
	return u[:]
}
func (u UUID) String() string {
	buf := make([]byte, 36)
	hex.Encode(buf[0:8], u[0:4])
	buf[8] = dash
	hex.Encode(buf[9:13], u[4:6])
	buf[13] = dash
	hex.Encode(buf[14:18], u[6:8])
	buf[18] = dash
	hex.Encode(buf[19:23], u[8:10])
	buf[23] = dash
	hex.Encode(buf[24:], u[10:])
	return string(buf)
}
func (u *UUID) SetVersion(v byte) {
	u[6] = (u[6] & 0x0f) | (v << 4)
}
func (u *UUID) SetVariant() {
	u[8] = (u[8] & 0xbf) | 0x80
}
func (u UUID) MarshalText() (text []byte, err error) {
	text = []byte(u.String())
	return
}
func (u *UUID) UnmarshalText(text []byte) (err error) {
	if len(text) < 32 {
		err = fmt.Errorf("uuid: invalid UUID string: %s", text)
		return
	}
	if bytes.Equal(text[:9], urnPrefix) {
		text = text[9:]
	} else if text[0] == '{' {
		text = text[1:]
	}
	b := u[:]
	for _, byteGroup := range byteGroups {
		if text[0] == '-' {
			text = text[1:]
		}
		_, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
		if err != nil {
			return
		}
		text = text[byteGroup:]
		b = b[byteGroup/2:]
	}
	return
}
func (u UUID) MarshalBinary() (data []byte, err error) {
	data = u.Bytes()
	return
}
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
	if len(data) != 16 {
		err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
		return
	}
	copy(u[:], data)
	return
}
func (u UUID) Value() (driver.Value, error) {
	return u.String(), nil
}
func (u *UUID) Scan(src interface{}) error {
	switch src := src.(type) {
	case []byte:
		if len(src) == 16 {
			return u.UnmarshalBinary(src)
		}
		return u.UnmarshalText(src)
	case string:
		return u.UnmarshalText([]byte(src))
	}
	return fmt.Errorf("uuid: cannot convert %T to UUID", src)
}
func FromBytes(input []byte) (u UUID, err error) {
	err = u.UnmarshalBinary(input)
	return
}
func FromBytesOrNil(input []byte) UUID {
	uuid, err := FromBytes(input)
	if err != nil {
		return Nil
	}
	return uuid
}
func FromString(input string) (u UUID, err error) {
	err = u.UnmarshalText([]byte(input))
	return
}
func FromStringOrNil(input string) UUID {
	uuid, err := FromString(input)
	if err != nil {
		return Nil
	}
	return uuid
}
func getStorage() (uint64, uint16, []byte) {
	storageOnce.Do(initStorage)
	storageMutex.Lock()
	defer storageMutex.Unlock()
	timeNow := epochFunc()
	if timeNow <= lastTime {
		clockSequence++
	}
	lastTime = timeNow
	return timeNow, clockSequence, hardwareAddr[:]
}
func NewV1() UUID {
	u := UUID{}
	timeNow, clockSeq, hardwareAddr := getStorage()
	binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSeq)
	copy(u[10:], hardwareAddr)
	u.SetVersion(1)
	u.SetVariant()
	return u
}
func NewV2(domain byte) UUID {
	u := UUID{}
	timeNow, clockSeq, hardwareAddr := getStorage()
	switch domain {
	case DomainPerson:
		binary.BigEndian.PutUint32(u[0:], posixUID)
	case DomainGroup:
		binary.BigEndian.PutUint32(u[0:], posixGID)
	}
	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSeq)
	u[9] = domain
	copy(u[10:], hardwareAddr)
	u.SetVersion(2)
	u.SetVariant()
	return u
}
func NewV3(ns UUID, name string) UUID {
	u := newFromHash(md5.New(), ns, name)
	u.SetVersion(3)
	u.SetVariant()
	return u
}
func NewV4() UUID {
	u := UUID{}
	safeRandom(u[:])
	u.SetVersion(4)
	u.SetVariant()
	return u
}