mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 13:51:35 +01:00 
			
		
		
		
	* Dropped unused codekit config * Integrated dynamic and static bindata for public * Ignore public bindata * Add a general generate make task * Integrated flexible public assets into web command * Updated vendoring, added all missiong govendor deps * Made the linter happy with the bindata and dynamic code * Moved public bindata definition to modules directory * Ignoring the new bindata path now * Updated to the new public modules import path * Updated public bindata command and drop the new prefix
		
			
				
	
	
		
			147 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package uuid
 | |
| 
 | |
| /***************
 | |
|  * Date: 14/02/14
 | |
|  * Time: 7:44 PM
 | |
|  ***************/
 | |
| 
 | |
| import (
 | |
| 	"crypto/md5"
 | |
| 	"crypto/rand"
 | |
| 	"crypto/sha1"
 | |
| 	"encoding/binary"
 | |
| 	"log"
 | |
| 	seed "math/rand"
 | |
| 	"net"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	length = 16
 | |
| 
 | |
| 	// 3F used by RFC4122 although 1F works for all
 | |
| 	variantSet = 0x3F
 | |
| 
 | |
| 	// rather than using 0xC0 we use 0xE0 to retrieve the variant
 | |
| 	// The result is the same for all other variants
 | |
| 	// 0x80 and 0xA0 are used to identify RFC4122 compliance
 | |
| 	variantGet = 0xE0
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// nodeID is the default Namespace node
 | |
| 	nodeId = []byte{
 | |
| 		// 00.192.79.212.48.200
 | |
| 		0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
 | |
| 	}
 | |
| 	// The following standard UUIDs are for use with V3 or V5 UUIDs.
 | |
| 	NamespaceDNS  = &Struct{0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, nodeId, length}
 | |
| 	NamespaceURL  = &Struct{0x6ba7b811, 0x9dad, 0x11d1, 0x80, 0xb4, nodeId, length}
 | |
| 	NamespaceOID  = &Struct{0x6ba7b812, 0x9dad, 0x11d1, 0x80, 0xb4, nodeId, length}
 | |
| 	NamespaceX500 = &Struct{0x6ba7b814, 0x9dad, 0x11d1, 0x80, 0xb4, nodeId, length}
 | |
| 
 | |
| 	state State
 | |
| )
 | |
| 
 | |
| func init() {
 | |
| 	seed.Seed((int64(timestamp())^int64(gregorianToUNIXOffset))*0x6ba7b814<<0x6ba7b812 | 1391463463)
 | |
| 	state = State{
 | |
| 		randomNode:     true,
 | |
| 		randomSequence: true,
 | |
| 		past:           Timestamp((1391463463 * 10000000) + (100 * 10) + gregorianToUNIXOffset),
 | |
| 		node:           nodeId,
 | |
| 		sequence:       uint16(seed.Int()) & 0x3FFF,
 | |
| 		saver:          nil,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // NewV1 will generate a new RFC4122 version 1 UUID
 | |
| func NewV1() UUID {
 | |
| 	state.Lock()
 | |
| 	defer state.Unlock()
 | |
| 	now := currentUUIDTimestamp()
 | |
| 	state.read(now, currentUUIDNodeId())
 | |
| 	state.persist()
 | |
| 	return formatV1(now, uint16(1), ReservedRFC4122, state.node)
 | |
| }
 | |
| 
 | |
| // NewV3 will generate a new RFC4122 version 3 UUID
 | |
| // V3 is based on the MD5 hash of a namespace identifier UUID and
 | |
| // any type which implements the UniqueName interface for the name.
 | |
| // For strings and slices cast to a Name type
 | |
| func NewV3(pNs UUID, pName UniqueName) UUID {
 | |
| 	o := new(Array)
 | |
| 	// Set all bits to MD5 hash generated from namespace and name.
 | |
| 	Digest(o, pNs, pName, md5.New())
 | |
| 	o.setRFC4122Variant()
 | |
| 	o.setVersion(3)
 | |
| 	return o
 | |
| }
 | |
| 
 | |
| // NewV4 will generate a new RFC4122 version 4 UUID
 | |
| // A cryptographically secure random UUID.
 | |
| func NewV4() UUID {
 | |
| 	o := new(Array)
 | |
| 	// Read random values (or pseudo-randomly) into Array type.
 | |
| 	_, err := rand.Read(o[:length])
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	o.setRFC4122Variant()
 | |
| 	o.setVersion(4)
 | |
| 	return o
 | |
| }
 | |
| 
 | |
| // NewV5 will generate a new RFC4122 version 5 UUID
 | |
| // Generate a UUID based on the SHA-1 hash of a namespace
 | |
| // identifier and a name.
 | |
| func NewV5(pNs UUID, pName UniqueName) UUID {
 | |
| 	o := new(Array)
 | |
| 	Digest(o, pNs, pName, sha1.New())
 | |
| 	o.setRFC4122Variant()
 | |
| 	o.setVersion(5)
 | |
| 	return o
 | |
| }
 | |
| 
 | |
| // either generates a random node when there is an error or gets
 | |
| // the pre initialised one
 | |
| func currentUUIDNodeId() (node net.HardwareAddr) {
 | |
| 	if state.randomNode {
 | |
| 		b := make([]byte, 16+6)
 | |
| 		_, err := rand.Read(b)
 | |
| 		if err != nil {
 | |
| 			log.Println("UUID.currentUUIDNodeId error:", err)
 | |
| 			node = nodeId
 | |
| 			return
 | |
| 		}
 | |
| 		h := sha1.New()
 | |
| 		h.Write(b)
 | |
| 		binary.Write(h, binary.LittleEndian, state.sequence)
 | |
| 		node = h.Sum(nil)[:6]
 | |
| 		if err != nil {
 | |
| 			log.Println("UUID.currentUUIDNodeId error:", err)
 | |
| 			node = nodeId
 | |
| 			return
 | |
| 		}
 | |
| 		// Mark as randomly generated
 | |
| 		node[0] |= 0x01
 | |
| 	} else {
 | |
| 		node = state.node
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // Unmarshal data into struct for V1 UUIDs
 | |
| func formatV1(pNow Timestamp, pVersion uint16, pVariant byte, pNode []byte) UUID {
 | |
| 	o := new(Struct)
 | |
| 	o.timeLow = uint32(pNow & 0xFFFFFFFF)
 | |
| 	o.timeMid = uint16((pNow >> 32) & 0xFFFF)
 | |
| 	o.timeHiAndVersion = uint16((pNow >> 48) & 0x0FFF)
 | |
| 	o.timeHiAndVersion |= uint16(pVersion << 12)
 | |
| 	o.sequenceLow = byte(state.sequence & 0xFF)
 | |
| 	o.sequenceHiAndVariant = byte((state.sequence & 0x3F00) >> 8)
 | |
| 	o.sequenceHiAndVariant |= pVariant
 | |
| 	o.node = pNode
 | |
| 	o.size = length
 | |
| 	return o
 | |
| }
 |