Use google/uuid to instead satori/go.uuid (#11943)
Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
		
							parent
							
								
									03ba974481
								
							
						
					
					
						commit
						1dd3f19ee3
					
				
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -50,6 +50,7 @@ require ( | ||||||
| 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 | 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 | ||||||
| 	github.com/golang/protobuf v1.4.1 // indirect | 	github.com/golang/protobuf v1.4.1 // indirect | ||||||
| 	github.com/google/go-github/v24 v24.0.1 | 	github.com/google/go-github/v24 v24.0.1 | ||||||
|  | 	github.com/google/uuid v1.1.1 | ||||||
| 	github.com/gorilla/context v1.1.1 | 	github.com/gorilla/context v1.1.1 | ||||||
| 	github.com/hashicorp/go-retryablehttp v0.6.6 // indirect | 	github.com/hashicorp/go-retryablehttp v0.6.6 // indirect | ||||||
| 	github.com/huandu/xstrings v1.3.0 | 	github.com/huandu/xstrings v1.3.0 | ||||||
|  | @ -85,7 +86,6 @@ require ( | ||||||
| 	github.com/prometheus/procfs v0.0.4 // indirect | 	github.com/prometheus/procfs v0.0.4 // indirect | ||||||
| 	github.com/quasoft/websspi v1.0.0 | 	github.com/quasoft/websspi v1.0.0 | ||||||
| 	github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect | 	github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect | ||||||
| 	github.com/satori/go.uuid v1.2.0 |  | ||||||
| 	github.com/sergi/go-diff v1.1.0 | 	github.com/sergi/go-diff v1.1.0 | ||||||
| 	github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect | 	github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect | ||||||
| 	github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd | 	github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							|  | @ -580,8 +580,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq | ||||||
| github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | ||||||
| github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= | github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= | ||||||
| github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | ||||||
| github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= |  | ||||||
| github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= |  | ||||||
| github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | ||||||
| github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | ||||||
| github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA= | github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA= | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import ( | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| 	"xorm.io/xorm" | 	"xorm.io/xorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -97,7 +97,7 @@ func (a *Attachment) LinkedRepository() (*Repository, UnitType, error) { | ||||||
| 
 | 
 | ||||||
| // NewAttachment creates a new attachment object.
 | // NewAttachment creates a new attachment object.
 | ||||||
| func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) { | func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) { | ||||||
| 	attach.UUID = gouuid.NewV4().String() | 	attach.UUID = gouuid.New().String() | ||||||
| 
 | 
 | ||||||
| 	localPath := attach.LocalPath() | 	localPath := attach.LocalPath() | ||||||
| 	if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { | 	if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/dgrijalva/jwt-go" | 	"github.com/dgrijalva/jwt-go" | ||||||
| 	uuid "github.com/satori/go.uuid" | 	uuid "github.com/google/uuid" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| 	"golang.org/x/crypto/bcrypt" | 	"golang.org/x/crypto/bcrypt" | ||||||
| 	"xorm.io/xorm" | 	"xorm.io/xorm" | ||||||
|  | @ -174,7 +174,7 @@ func CreateOAuth2Application(opts CreateOAuth2ApplicationOptions) (*OAuth2Applic | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func createOAuth2Application(e Engine, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) { | func createOAuth2Application(e Engine, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) { | ||||||
| 	clientID := uuid.NewV4().String() | 	clientID := uuid.New().String() | ||||||
| 	app := &OAuth2Application{ | 	app := &OAuth2Application{ | ||||||
| 		UID:          opts.UserID, | 		UID:          opts.UserID, | ||||||
| 		Name:         opts.Name, | 		Name:         opts.Name, | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/generate" | 	"code.gitea.io/gitea/modules/generate" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // AccessToken represents a personal access token.
 | // AccessToken represents a personal access token.
 | ||||||
|  | @ -45,7 +45,7 @@ func NewAccessToken(t *AccessToken) error { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	t.TokenSalt = salt | 	t.TokenSalt = salt | ||||||
| 	t.Token = base.EncodeSha1(gouuid.NewV4().String()) | 	t.Token = base.EncodeSha1(gouuid.New().String()) | ||||||
| 	t.TokenHash = hashToken(t.Token, t.TokenSalt) | 	t.TokenHash = hashToken(t.Token, t.TokenSalt) | ||||||
| 	t.TokenLastEight = t.Token[len(t.Token)-8:] | 	t.TokenLastEight = t.Token[len(t.Token)-8:] | ||||||
| 	_, err = x.Insert(t) | 	_, err = x.Insert(t) | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -46,7 +46,7 @@ func (upload *Upload) LocalPath() string { | ||||||
| // NewUpload creates a new upload object.
 | // NewUpload creates a new upload object.
 | ||||||
| func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) { | func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) { | ||||||
| 	upload := &Upload{ | 	upload := &Upload{ | ||||||
| 		UUID: gouuid.NewV4().String(), | 		UUID: gouuid.New().String(), | ||||||
| 		Name: name, | 		Name: name, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ import ( | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // HookContentType is the content type of a web hook
 | // HookContentType is the content type of a web hook
 | ||||||
|  | @ -769,7 +769,7 @@ func createHookTask(e Engine, t *HookTask) error { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	t.UUID = gouuid.NewV4().String() | 	t.UUID = gouuid.New().String() | ||||||
| 	t.PayloadContent = string(data) | 	t.PayloadContent = string(data) | ||||||
| 	_, err = e.Insert(t) | 	_, err = e.Insert(t) | ||||||
| 	return err | 	return err | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 
 | 
 | ||||||
|  | 	uuid "github.com/google/uuid" | ||||||
| 	"github.com/lafriks/xormstore" | 	"github.com/lafriks/xormstore" | ||||||
| 	"github.com/markbates/goth" | 	"github.com/markbates/goth" | ||||||
| 	"github.com/markbates/goth/gothic" | 	"github.com/markbates/goth/gothic" | ||||||
|  | @ -25,7 +26,6 @@ import ( | ||||||
| 	"github.com/markbates/goth/providers/openidConnect" | 	"github.com/markbates/goth/providers/openidConnect" | ||||||
| 	"github.com/markbates/goth/providers/twitter" | 	"github.com/markbates/goth/providers/twitter" | ||||||
| 	"github.com/markbates/goth/providers/yandex" | 	"github.com/markbates/goth/providers/yandex" | ||||||
| 	uuid "github.com/satori/go.uuid" |  | ||||||
| 	"xorm.io/xorm" | 	"xorm.io/xorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -61,7 +61,7 @@ func Init(x *xorm.Engine) error { | ||||||
| 	gothic.Store = store | 	gothic.Store = store | ||||||
| 
 | 
 | ||||||
| 	gothic.SetState = func(req *http.Request) string { | 	gothic.SetState = func(req *http.Request) string { | ||||||
| 		return uuid.NewV4().String() | 		return uuid.New().String() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	gothic.GetProviderName = func(req *http.Request) (string, error) { | 	gothic.GetProviderName = func(req *http.Request) (string, error) { | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"gitea.com/macaron/macaron" | 	"gitea.com/macaron/macaron" | ||||||
| 	"gitea.com/macaron/session" | 	"gitea.com/macaron/session" | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Ensure the struct implements the interface.
 | // Ensure the struct implements the interface.
 | ||||||
|  | @ -92,7 +92,7 @@ func (r *ReverseProxy) newUser(ctx *macaron.Context) *models.User { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	email := gouuid.NewV4().String() + "@localhost" | 	email := gouuid.New().String() + "@localhost" | ||||||
| 	if setting.Service.EnableReverseProxyEmail { | 	if setting.Service.EnableReverseProxyEmail { | ||||||
| 		webAuthEmail := ctx.Req.Header.Get(setting.ReverseProxyAuthEmail) | 		webAuthEmail := ctx.Req.Header.Get(setting.ReverseProxyAuthEmail) | ||||||
| 		if len(webAuthEmail) > 0 { | 		if len(webAuthEmail) > 0 { | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ import ( | ||||||
| 	"gitea.com/macaron/macaron" | 	"gitea.com/macaron/macaron" | ||||||
| 	"gitea.com/macaron/session" | 	"gitea.com/macaron/session" | ||||||
| 
 | 
 | ||||||
|  | 	gouuid "github.com/google/uuid" | ||||||
| 	"github.com/quasoft/websspi" | 	"github.com/quasoft/websspi" | ||||||
| 	gouuid "github.com/satori/go.uuid" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -157,12 +157,12 @@ func (s *SSPI) shouldAuthenticate(ctx *macaron.Context) (shouldAuth bool) { | ||||||
| // newUser creates a new user object for the purpose of automatic registration
 | // newUser creates a new user object for the purpose of automatic registration
 | ||||||
| // and populates its name and email with the information present in request headers.
 | // and populates its name and email with the information present in request headers.
 | ||||||
| func (s *SSPI) newUser(ctx *macaron.Context, username string, cfg *models.SSPIConfig) (*models.User, error) { | func (s *SSPI) newUser(ctx *macaron.Context, username string, cfg *models.SSPIConfig) (*models.User, error) { | ||||||
| 	email := gouuid.NewV4().String() + "@localhost.localdomain" | 	email := gouuid.New().String() + "@localhost.localdomain" | ||||||
| 	user := &models.User{ | 	user := &models.User{ | ||||||
| 		Name:                         username, | 		Name:                         username, | ||||||
| 		Email:                        email, | 		Email:                        email, | ||||||
| 		KeepEmailPrivate:             true, | 		KeepEmailPrivate:             true, | ||||||
| 		Passwd:                       gouuid.NewV4().String(), | 		Passwd:                       gouuid.New().String(), | ||||||
| 		IsActive:                     cfg.AutoActivateUsers, | 		IsActive:                     cfg.AutoActivateUsers, | ||||||
| 		Language:                     cfg.DefaultLanguage, | 		Language:                     cfg.DefaultLanguage, | ||||||
| 		UseCustomAvatar:              true, | 		UseCustomAvatar:              true, | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/google/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  | @ -260,7 +260,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { | ||||||
| 
 | 
 | ||||||
| 		for _, asset := range release.Assets { | 		for _, asset := range release.Assets { | ||||||
| 			var attach = models.Attachment{ | 			var attach = models.Attachment{ | ||||||
| 				UUID:          gouuid.NewV4().String(), | 				UUID:          gouuid.New().String(), | ||||||
| 				Name:          asset.Name, | 				Name:          asset.Name, | ||||||
| 				DownloadCount: int64(*asset.DownloadCount), | 				DownloadCount: int64(*asset.DownloadCount), | ||||||
| 				Size:          int64(*asset.Size), | 				Size:          int64(*asset.Size), | ||||||
|  |  | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | language: go | ||||||
|  | 
 | ||||||
|  | go: | ||||||
|  |   - 1.4.3 | ||||||
|  |   - 1.5.3 | ||||||
|  |   - tip | ||||||
|  | 
 | ||||||
|  | script: | ||||||
|  |   - go test -v ./... | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | # How to contribute | ||||||
|  | 
 | ||||||
|  | We definitely welcome patches and contribution to this project! | ||||||
|  | 
 | ||||||
|  | ### Legal requirements | ||||||
|  | 
 | ||||||
|  | In order to protect both you and ourselves, you will need to sign the | ||||||
|  | [Contributor License Agreement](https://cla.developers.google.com/clas). | ||||||
|  | 
 | ||||||
|  | You may have already signed it for other Google projects. | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | Paul Borman <borman@google.com> | ||||||
|  | bmatsuo | ||||||
|  | shawnps | ||||||
|  | theory | ||||||
|  | jboverfelt | ||||||
|  | dsymonds | ||||||
|  | cd1 | ||||||
|  | wallclockbuilder | ||||||
|  | dansouza | ||||||
|  | @ -0,0 +1,27 @@ | ||||||
|  | Copyright (c) 2009,2014 Google Inc. All rights reserved. | ||||||
|  | 
 | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are | ||||||
|  | met: | ||||||
|  | 
 | ||||||
|  |    * Redistributions of source code must retain the above copyright | ||||||
|  | notice, this list of conditions and the following disclaimer. | ||||||
|  |    * Redistributions in binary form must reproduce the above | ||||||
|  | copyright notice, this list of conditions and the following disclaimer | ||||||
|  | in the documentation and/or other materials provided with the | ||||||
|  | distribution. | ||||||
|  |    * Neither the name of Google Inc. nor the names of its | ||||||
|  | contributors may be used to endorse or promote products derived from | ||||||
|  | this software without specific prior written permission. | ||||||
|  | 
 | ||||||
|  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||||
|  | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||||
|  | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||||
|  | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||||
|  | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||||
|  | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||||
|  | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | @ -0,0 +1,19 @@ | ||||||
|  | # uuid  | ||||||
|  | The uuid package generates and inspects UUIDs based on | ||||||
|  | [RFC 4122](http://tools.ietf.org/html/rfc4122) | ||||||
|  | and DCE 1.1: Authentication and Security Services.  | ||||||
|  | 
 | ||||||
|  | This package is based on the github.com/pborman/uuid package (previously named | ||||||
|  | code.google.com/p/go-uuid).  It differs from these earlier packages in that | ||||||
|  | a UUID is a 16 byte array rather than a byte slice.  One loss due to this | ||||||
|  | change is the ability to represent an invalid UUID (vs a NIL UUID). | ||||||
|  | 
 | ||||||
|  | ###### Install | ||||||
|  | `go get github.com/google/uuid` | ||||||
|  | 
 | ||||||
|  | ###### Documentation  | ||||||
|  | [](http://godoc.org/github.com/google/uuid) | ||||||
|  | 
 | ||||||
|  | Full `go doc` style documentation for the package can be viewed online without | ||||||
|  | installing this package by using the GoDoc site here:  | ||||||
|  | http://godoc.org/github.com/google/uuid | ||||||
|  | @ -0,0 +1,80 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/binary" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A Domain represents a Version 2 domain
 | ||||||
|  | type Domain byte | ||||||
|  | 
 | ||||||
|  | // Domain constants for DCE Security (Version 2) UUIDs.
 | ||||||
|  | const ( | ||||||
|  | 	Person = Domain(0) | ||||||
|  | 	Group  = Domain(1) | ||||||
|  | 	Org    = Domain(2) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NewDCESecurity returns a DCE Security (Version 2) UUID.
 | ||||||
|  | //
 | ||||||
|  | // The domain should be one of Person, Group or Org.
 | ||||||
|  | // On a POSIX system the id should be the users UID for the Person
 | ||||||
|  | // domain and the users GID for the Group.  The meaning of id for
 | ||||||
|  | // the domain Org or on non-POSIX systems is site defined.
 | ||||||
|  | //
 | ||||||
|  | // For a given domain/id pair the same token may be returned for up to
 | ||||||
|  | // 7 minutes and 10 seconds.
 | ||||||
|  | func NewDCESecurity(domain Domain, id uint32) (UUID, error) { | ||||||
|  | 	uuid, err := NewUUID() | ||||||
|  | 	if err == nil { | ||||||
|  | 		uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
 | ||||||
|  | 		uuid[9] = byte(domain) | ||||||
|  | 		binary.BigEndian.PutUint32(uuid[0:], id) | ||||||
|  | 	} | ||||||
|  | 	return uuid, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewDCEPerson returns a DCE Security (Version 2) UUID in the person
 | ||||||
|  | // domain with the id returned by os.Getuid.
 | ||||||
|  | //
 | ||||||
|  | //  NewDCESecurity(Person, uint32(os.Getuid()))
 | ||||||
|  | func NewDCEPerson() (UUID, error) { | ||||||
|  | 	return NewDCESecurity(Person, uint32(os.Getuid())) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewDCEGroup returns a DCE Security (Version 2) UUID in the group
 | ||||||
|  | // domain with the id returned by os.Getgid.
 | ||||||
|  | //
 | ||||||
|  | //  NewDCESecurity(Group, uint32(os.Getgid()))
 | ||||||
|  | func NewDCEGroup() (UUID, error) { | ||||||
|  | 	return NewDCESecurity(Group, uint32(os.Getgid())) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Domain returns the domain for a Version 2 UUID.  Domains are only defined
 | ||||||
|  | // for Version 2 UUIDs.
 | ||||||
|  | func (uuid UUID) Domain() Domain { | ||||||
|  | 	return Domain(uuid[9]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
 | ||||||
|  | // UUIDs.
 | ||||||
|  | func (uuid UUID) ID() uint32 { | ||||||
|  | 	return binary.BigEndian.Uint32(uuid[0:4]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d Domain) String() string { | ||||||
|  | 	switch d { | ||||||
|  | 	case Person: | ||||||
|  | 		return "Person" | ||||||
|  | 	case Group: | ||||||
|  | 		return "Group" | ||||||
|  | 	case Org: | ||||||
|  | 		return "Org" | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("Domain%d", int(d)) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | // Package uuid generates and inspects UUIDs.
 | ||||||
|  | //
 | ||||||
|  | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
 | ||||||
|  | // Services.
 | ||||||
|  | //
 | ||||||
|  | // A UUID is a 16 byte (128 bit) array.  UUIDs may be used as keys to
 | ||||||
|  | // maps or compared directly.
 | ||||||
|  | package uuid | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module github.com/google/uuid | ||||||
|  | @ -0,0 +1,53 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"crypto/md5" | ||||||
|  | 	"crypto/sha1" | ||||||
|  | 	"hash" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Well known namespace IDs and UUIDs
 | ||||||
|  | var ( | ||||||
|  | 	NameSpaceDNS  = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) | ||||||
|  | 	NameSpaceURL  = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) | ||||||
|  | 	NameSpaceOID  = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) | ||||||
|  | 	NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) | ||||||
|  | 	Nil           UUID // empty UUID, all zeros
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NewHash returns a new UUID derived from the hash of space concatenated with
 | ||||||
|  | // data generated by h.  The hash should be at least 16 byte in length.  The
 | ||||||
|  | // first 16 bytes of the hash are used to form the UUID.  The version of the
 | ||||||
|  | // UUID will be the lower 4 bits of version.  NewHash is used to implement
 | ||||||
|  | // NewMD5 and NewSHA1.
 | ||||||
|  | func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { | ||||||
|  | 	h.Reset() | ||||||
|  | 	h.Write(space[:]) | ||||||
|  | 	h.Write(data) | ||||||
|  | 	s := h.Sum(nil) | ||||||
|  | 	var uuid UUID | ||||||
|  | 	copy(uuid[:], s) | ||||||
|  | 	uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) | ||||||
|  | 	uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
 | ||||||
|  | 	return uuid | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewMD5 returns a new MD5 (Version 3) UUID based on the
 | ||||||
|  | // supplied name space and data.  It is the same as calling:
 | ||||||
|  | //
 | ||||||
|  | //  NewHash(md5.New(), space, data, 3)
 | ||||||
|  | func NewMD5(space UUID, data []byte) UUID { | ||||||
|  | 	return NewHash(md5.New(), space, data, 3) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewSHA1 returns a new SHA1 (Version 5) UUID based on the
 | ||||||
|  | // supplied name space and data.  It is the same as calling:
 | ||||||
|  | //
 | ||||||
|  | //  NewHash(sha1.New(), space, data, 5)
 | ||||||
|  | func NewSHA1(space UUID, data []byte) UUID { | ||||||
|  | 	return NewHash(sha1.New(), space, data, 5) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,37 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // MarshalText implements encoding.TextMarshaler.
 | ||||||
|  | func (uuid UUID) MarshalText() ([]byte, error) { | ||||||
|  | 	var js [36]byte | ||||||
|  | 	encodeHex(js[:], uuid) | ||||||
|  | 	return js[:], nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalText implements encoding.TextUnmarshaler.
 | ||||||
|  | func (uuid *UUID) UnmarshalText(data []byte) error { | ||||||
|  | 	id, err := ParseBytes(data) | ||||||
|  | 	if err == nil { | ||||||
|  | 		*uuid = id | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarshalBinary implements encoding.BinaryMarshaler.
 | ||||||
|  | func (uuid UUID) MarshalBinary() ([]byte, error) { | ||||||
|  | 	return uuid[:], nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalBinary implements encoding.BinaryUnmarshaler.
 | ||||||
|  | func (uuid *UUID) UnmarshalBinary(data []byte) error { | ||||||
|  | 	if len(data) != 16 { | ||||||
|  | 		return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) | ||||||
|  | 	} | ||||||
|  | 	copy(uuid[:], data) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,90 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"sync" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	nodeMu sync.Mutex | ||||||
|  | 	ifname string  // name of interface being used
 | ||||||
|  | 	nodeID [6]byte // hardware for version 1 UUIDs
 | ||||||
|  | 	zeroID [6]byte // nodeID with only 0's
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NodeInterface returns the name of the interface from which the NodeID was
 | ||||||
|  | // derived.  The interface "user" is returned if the NodeID was set by
 | ||||||
|  | // SetNodeID.
 | ||||||
|  | func NodeInterface() string { | ||||||
|  | 	defer nodeMu.Unlock() | ||||||
|  | 	nodeMu.Lock() | ||||||
|  | 	return ifname | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
 | ||||||
|  | // If name is "" then the first usable interface found will be used or a random
 | ||||||
|  | // Node ID will be generated.  If a named interface cannot be found then false
 | ||||||
|  | // is returned.
 | ||||||
|  | //
 | ||||||
|  | // SetNodeInterface never fails when name is "".
 | ||||||
|  | func SetNodeInterface(name string) bool { | ||||||
|  | 	defer nodeMu.Unlock() | ||||||
|  | 	nodeMu.Lock() | ||||||
|  | 	return setNodeInterface(name) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func setNodeInterface(name string) bool { | ||||||
|  | 	iname, addr := getHardwareInterface(name) // null implementation for js
 | ||||||
|  | 	if iname != "" && addr != nil { | ||||||
|  | 		ifname = iname | ||||||
|  | 		copy(nodeID[:], addr) | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// We found no interfaces with a valid hardware address.  If name
 | ||||||
|  | 	// does not specify a specific interface generate a random Node ID
 | ||||||
|  | 	// (section 4.1.6)
 | ||||||
|  | 	if name == "" { | ||||||
|  | 		ifname = "random" | ||||||
|  | 		randomBits(nodeID[:]) | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
 | ||||||
|  | // if not already set.
 | ||||||
|  | func NodeID() []byte { | ||||||
|  | 	defer nodeMu.Unlock() | ||||||
|  | 	nodeMu.Lock() | ||||||
|  | 	if nodeID == zeroID { | ||||||
|  | 		setNodeInterface("") | ||||||
|  | 	} | ||||||
|  | 	nid := nodeID | ||||||
|  | 	return nid[:] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetNodeID sets the Node ID to be used for Version 1 UUIDs.  The first 6 bytes
 | ||||||
|  | // of id are used.  If id is less than 6 bytes then false is returned and the
 | ||||||
|  | // Node ID is not set.
 | ||||||
|  | func SetNodeID(id []byte) bool { | ||||||
|  | 	if len(id) < 6 { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	defer nodeMu.Unlock() | ||||||
|  | 	nodeMu.Lock() | ||||||
|  | 	copy(nodeID[:], id) | ||||||
|  | 	ifname = "user" | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeID returns the 6 byte node id encoded in uuid.  It returns nil if uuid is
 | ||||||
|  | // not valid.  The NodeID is only well defined for version 1 and 2 UUIDs.
 | ||||||
|  | func (uuid UUID) NodeID() []byte { | ||||||
|  | 	var node [6]byte | ||||||
|  | 	copy(node[:], uuid[10:]) | ||||||
|  | 	return node[:] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | // Copyright 2017 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | // +build js
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | // getHardwareInterface returns nil values for the JS version of the code.
 | ||||||
|  | // This remvoves the "net" dependency, because it is not used in the browser.
 | ||||||
|  | // Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
 | ||||||
|  | func getHardwareInterface(name string) (string, []byte) { return "", nil } | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | // Copyright 2017 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | // +build !js
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import "net" | ||||||
|  | 
 | ||||||
|  | var interfaces []net.Interface // cached list of interfaces
 | ||||||
|  | 
 | ||||||
|  | // getHardwareInterface returns the name and hardware address of interface name.
 | ||||||
|  | // If name is "" then the name and hardware address of one of the system's
 | ||||||
|  | // interfaces is returned.  If no interfaces are found (name does not exist or
 | ||||||
|  | // there are no interfaces) then "", nil is returned.
 | ||||||
|  | //
 | ||||||
|  | // Only addresses of at least 6 bytes are returned.
 | ||||||
|  | func getHardwareInterface(name string) (string, []byte) { | ||||||
|  | 	if interfaces == nil { | ||||||
|  | 		var err error | ||||||
|  | 		interfaces, err = net.Interfaces() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for _, ifs := range interfaces { | ||||||
|  | 		if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { | ||||||
|  | 			return ifs.Name, ifs.HardwareAddr | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return "", nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,59 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"database/sql/driver" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Scan implements sql.Scanner so UUIDs can be read from databases transparently
 | ||||||
|  | // Currently, database types that map to string and []byte are supported. Please
 | ||||||
|  | // consult database-specific driver documentation for matching types.
 | ||||||
|  | func (uuid *UUID) Scan(src interface{}) error { | ||||||
|  | 	switch src := src.(type) { | ||||||
|  | 	case nil: | ||||||
|  | 		return nil | ||||||
|  | 
 | ||||||
|  | 	case string: | ||||||
|  | 		// if an empty UUID comes from a table, we return a null UUID
 | ||||||
|  | 		if src == "" { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// see Parse for required string format
 | ||||||
|  | 		u, err := Parse(src) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Scan: %v", err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		*uuid = u | ||||||
|  | 
 | ||||||
|  | 	case []byte: | ||||||
|  | 		// if an empty UUID comes from a table, we return a null UUID
 | ||||||
|  | 		if len(src) == 0 { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// assumes a simple slice of bytes if 16 bytes
 | ||||||
|  | 		// otherwise attempts to parse
 | ||||||
|  | 		if len(src) != 16 { | ||||||
|  | 			return uuid.Scan(string(src)) | ||||||
|  | 		} | ||||||
|  | 		copy((*uuid)[:], src) | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return fmt.Errorf("Scan: unable to scan type %T into UUID", src) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Value implements sql.Valuer so that UUIDs can be written to databases
 | ||||||
|  | // transparently. Currently, UUIDs map to strings. Please consult
 | ||||||
|  | // database-specific driver documentation for matching types.
 | ||||||
|  | func (uuid UUID) Value() (driver.Value, error) { | ||||||
|  | 	return uuid.String(), nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,123 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/binary" | ||||||
|  | 	"sync" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A Time represents a time as the number of 100's of nanoseconds since 15 Oct
 | ||||||
|  | // 1582.
 | ||||||
|  | type Time int64 | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	lillian    = 2299160          // Julian day of 15 Oct 1582
 | ||||||
|  | 	unix       = 2440587          // Julian day of 1 Jan 1970
 | ||||||
|  | 	epoch      = unix - lillian   // Days between epochs
 | ||||||
|  | 	g1582      = epoch * 86400    // seconds between epochs
 | ||||||
|  | 	g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	timeMu   sync.Mutex | ||||||
|  | 	lasttime uint64 // last time we returned
 | ||||||
|  | 	clockSeq uint16 // clock sequence for this run
 | ||||||
|  | 
 | ||||||
|  | 	timeNow = time.Now // for testing
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // UnixTime converts t the number of seconds and nanoseconds using the Unix
 | ||||||
|  | // epoch of 1 Jan 1970.
 | ||||||
|  | func (t Time) UnixTime() (sec, nsec int64) { | ||||||
|  | 	sec = int64(t - g1582ns100) | ||||||
|  | 	nsec = (sec % 10000000) * 100 | ||||||
|  | 	sec /= 10000000 | ||||||
|  | 	return sec, nsec | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
 | ||||||
|  | // clock sequence as well as adjusting the clock sequence as needed.  An error
 | ||||||
|  | // is returned if the current time cannot be determined.
 | ||||||
|  | func GetTime() (Time, uint16, error) { | ||||||
|  | 	defer timeMu.Unlock() | ||||||
|  | 	timeMu.Lock() | ||||||
|  | 	return getTime() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getTime() (Time, uint16, error) { | ||||||
|  | 	t := timeNow() | ||||||
|  | 
 | ||||||
|  | 	// If we don't have a clock sequence already, set one.
 | ||||||
|  | 	if clockSeq == 0 { | ||||||
|  | 		setClockSequence(-1) | ||||||
|  | 	} | ||||||
|  | 	now := uint64(t.UnixNano()/100) + g1582ns100 | ||||||
|  | 
 | ||||||
|  | 	// If time has gone backwards with this clock sequence then we
 | ||||||
|  | 	// increment the clock sequence
 | ||||||
|  | 	if now <= lasttime { | ||||||
|  | 		clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 | ||||||
|  | 	} | ||||||
|  | 	lasttime = now | ||||||
|  | 	return Time(now), clockSeq, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClockSequence returns the current clock sequence, generating one if not
 | ||||||
|  | // already set.  The clock sequence is only used for Version 1 UUIDs.
 | ||||||
|  | //
 | ||||||
|  | // The uuid package does not use global static storage for the clock sequence or
 | ||||||
|  | // the last time a UUID was generated.  Unless SetClockSequence is used, a new
 | ||||||
|  | // random clock sequence is generated the first time a clock sequence is
 | ||||||
|  | // requested by ClockSequence, GetTime, or NewUUID.  (section 4.2.1.1)
 | ||||||
|  | func ClockSequence() int { | ||||||
|  | 	defer timeMu.Unlock() | ||||||
|  | 	timeMu.Lock() | ||||||
|  | 	return clockSequence() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func clockSequence() int { | ||||||
|  | 	if clockSeq == 0 { | ||||||
|  | 		setClockSequence(-1) | ||||||
|  | 	} | ||||||
|  | 	return int(clockSeq & 0x3fff) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetClockSequence sets the clock sequence to the lower 14 bits of seq.  Setting to
 | ||||||
|  | // -1 causes a new sequence to be generated.
 | ||||||
|  | func SetClockSequence(seq int) { | ||||||
|  | 	defer timeMu.Unlock() | ||||||
|  | 	timeMu.Lock() | ||||||
|  | 	setClockSequence(seq) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func setClockSequence(seq int) { | ||||||
|  | 	if seq == -1 { | ||||||
|  | 		var b [2]byte | ||||||
|  | 		randomBits(b[:]) // clock sequence
 | ||||||
|  | 		seq = int(b[0])<<8 | int(b[1]) | ||||||
|  | 	} | ||||||
|  | 	oldSeq := clockSeq | ||||||
|  | 	clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
 | ||||||
|  | 	if oldSeq != clockSeq { | ||||||
|  | 		lasttime = 0 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
 | ||||||
|  | // uuid.  The time is only defined for version 1 and 2 UUIDs.
 | ||||||
|  | func (uuid UUID) Time() Time { | ||||||
|  | 	time := int64(binary.BigEndian.Uint32(uuid[0:4])) | ||||||
|  | 	time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 | ||||||
|  | 	time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 | ||||||
|  | 	return Time(time) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClockSequence returns the clock sequence encoded in uuid.
 | ||||||
|  | // The clock sequence is only well defined for version 1 and 2 UUIDs.
 | ||||||
|  | func (uuid UUID) ClockSequence() int { | ||||||
|  | 	return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff | ||||||
|  | } | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // randomBits completely fills slice b with random data.
 | ||||||
|  | func randomBits(b []byte) { | ||||||
|  | 	if _, err := io.ReadFull(rander, b); err != nil { | ||||||
|  | 		panic(err.Error()) // rand should never fail
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // xvalues returns the value of a byte as a hexadecimal digit or 255.
 | ||||||
|  | var xvalues = [256]byte{ | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // xtob converts hex characters x1 and x2 into a byte.
 | ||||||
|  | func xtob(x1, x2 byte) (byte, bool) { | ||||||
|  | 	b1 := xvalues[x1] | ||||||
|  | 	b2 := xvalues[x2] | ||||||
|  | 	return (b1 << 4) | b2, b1 != 255 && b2 != 255 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,245 @@ | ||||||
|  | // Copyright 2018 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"encoding/hex" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
 | ||||||
|  | // 4122.
 | ||||||
|  | type UUID [16]byte | ||||||
|  | 
 | ||||||
|  | // A Version represents a UUID's version.
 | ||||||
|  | type Version byte | ||||||
|  | 
 | ||||||
|  | // A Variant represents a UUID's variant.
 | ||||||
|  | type Variant byte | ||||||
|  | 
 | ||||||
|  | // Constants returned by Variant.
 | ||||||
|  | const ( | ||||||
|  | 	Invalid   = Variant(iota) // Invalid UUID
 | ||||||
|  | 	RFC4122                   // The variant specified in RFC4122
 | ||||||
|  | 	Reserved                  // Reserved, NCS backward compatibility.
 | ||||||
|  | 	Microsoft                 // Reserved, Microsoft Corporation backward compatibility.
 | ||||||
|  | 	Future                    // Reserved for future definition.
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var rander = rand.Reader // random function
 | ||||||
|  | 
 | ||||||
|  | // Parse decodes s into a UUID or returns an error.  Both the standard UUID
 | ||||||
|  | // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
 | ||||||
|  | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
 | ||||||
|  | // Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
 | ||||||
|  | // encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
 | ||||||
|  | func Parse(s string) (UUID, error) { | ||||||
|  | 	var uuid UUID | ||||||
|  | 	switch len(s) { | ||||||
|  | 	// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 	case 36: | ||||||
|  | 
 | ||||||
|  | 	// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 	case 36 + 9: | ||||||
|  | 		if strings.ToLower(s[:9]) != "urn:uuid:" { | ||||||
|  | 			return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) | ||||||
|  | 		} | ||||||
|  | 		s = s[9:] | ||||||
|  | 
 | ||||||
|  | 	// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
 | ||||||
|  | 	case 36 + 2: | ||||||
|  | 		s = s[1:] | ||||||
|  | 
 | ||||||
|  | 	// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 | ||||||
|  | 	case 32: | ||||||
|  | 		var ok bool | ||||||
|  | 		for i := range uuid { | ||||||
|  | 			uuid[i], ok = xtob(s[i*2], s[i*2+1]) | ||||||
|  | 			if !ok { | ||||||
|  | 				return uuid, errors.New("invalid UUID format") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return uuid, nil | ||||||
|  | 	default: | ||||||
|  | 		return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) | ||||||
|  | 	} | ||||||
|  | 	// s is now at least 36 bytes long
 | ||||||
|  | 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 	if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { | ||||||
|  | 		return uuid, errors.New("invalid UUID format") | ||||||
|  | 	} | ||||||
|  | 	for i, x := range [16]int{ | ||||||
|  | 		0, 2, 4, 6, | ||||||
|  | 		9, 11, | ||||||
|  | 		14, 16, | ||||||
|  | 		19, 21, | ||||||
|  | 		24, 26, 28, 30, 32, 34} { | ||||||
|  | 		v, ok := xtob(s[x], s[x+1]) | ||||||
|  | 		if !ok { | ||||||
|  | 			return uuid, errors.New("invalid UUID format") | ||||||
|  | 		} | ||||||
|  | 		uuid[i] = v | ||||||
|  | 	} | ||||||
|  | 	return uuid, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ParseBytes is like Parse, except it parses a byte slice instead of a string.
 | ||||||
|  | func ParseBytes(b []byte) (UUID, error) { | ||||||
|  | 	var uuid UUID | ||||||
|  | 	switch len(b) { | ||||||
|  | 	case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 	case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 		if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { | ||||||
|  | 			return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) | ||||||
|  | 		} | ||||||
|  | 		b = b[9:] | ||||||
|  | 	case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
 | ||||||
|  | 		b = b[1:] | ||||||
|  | 	case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 | ||||||
|  | 		var ok bool | ||||||
|  | 		for i := 0; i < 32; i += 2 { | ||||||
|  | 			uuid[i/2], ok = xtob(b[i], b[i+1]) | ||||||
|  | 			if !ok { | ||||||
|  | 				return uuid, errors.New("invalid UUID format") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return uuid, nil | ||||||
|  | 	default: | ||||||
|  | 		return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) | ||||||
|  | 	} | ||||||
|  | 	// s is now at least 36 bytes long
 | ||||||
|  | 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | 	if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { | ||||||
|  | 		return uuid, errors.New("invalid UUID format") | ||||||
|  | 	} | ||||||
|  | 	for i, x := range [16]int{ | ||||||
|  | 		0, 2, 4, 6, | ||||||
|  | 		9, 11, | ||||||
|  | 		14, 16, | ||||||
|  | 		19, 21, | ||||||
|  | 		24, 26, 28, 30, 32, 34} { | ||||||
|  | 		v, ok := xtob(b[x], b[x+1]) | ||||||
|  | 		if !ok { | ||||||
|  | 			return uuid, errors.New("invalid UUID format") | ||||||
|  | 		} | ||||||
|  | 		uuid[i] = v | ||||||
|  | 	} | ||||||
|  | 	return uuid, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MustParse is like Parse but panics if the string cannot be parsed.
 | ||||||
|  | // It simplifies safe initialization of global variables holding compiled UUIDs.
 | ||||||
|  | func MustParse(s string) UUID { | ||||||
|  | 	uuid, err := Parse(s) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(`uuid: Parse(` + s + `): ` + err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return uuid | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FromBytes creates a new UUID from a byte slice. Returns an error if the slice
 | ||||||
|  | // does not have a length of 16. The bytes are copied from the slice.
 | ||||||
|  | func FromBytes(b []byte) (uuid UUID, err error) { | ||||||
|  | 	err = uuid.UnmarshalBinary(b) | ||||||
|  | 	return uuid, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Must returns uuid if err is nil and panics otherwise.
 | ||||||
|  | func Must(uuid UUID, err error) UUID { | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return uuid | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 | ||||||
|  | // , or "" if uuid is invalid.
 | ||||||
|  | func (uuid UUID) String() string { | ||||||
|  | 	var buf [36]byte | ||||||
|  | 	encodeHex(buf[:], uuid) | ||||||
|  | 	return string(buf[:]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // URN returns the RFC 2141 URN form of uuid,
 | ||||||
|  | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,  or "" if uuid is invalid.
 | ||||||
|  | func (uuid UUID) URN() string { | ||||||
|  | 	var buf [36 + 9]byte | ||||||
|  | 	copy(buf[:], "urn:uuid:") | ||||||
|  | 	encodeHex(buf[9:], uuid) | ||||||
|  | 	return string(buf[:]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func encodeHex(dst []byte, uuid UUID) { | ||||||
|  | 	hex.Encode(dst, uuid[:4]) | ||||||
|  | 	dst[8] = '-' | ||||||
|  | 	hex.Encode(dst[9:13], uuid[4:6]) | ||||||
|  | 	dst[13] = '-' | ||||||
|  | 	hex.Encode(dst[14:18], uuid[6:8]) | ||||||
|  | 	dst[18] = '-' | ||||||
|  | 	hex.Encode(dst[19:23], uuid[8:10]) | ||||||
|  | 	dst[23] = '-' | ||||||
|  | 	hex.Encode(dst[24:], uuid[10:]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Variant returns the variant encoded in uuid.
 | ||||||
|  | func (uuid UUID) Variant() Variant { | ||||||
|  | 	switch { | ||||||
|  | 	case (uuid[8] & 0xc0) == 0x80: | ||||||
|  | 		return RFC4122 | ||||||
|  | 	case (uuid[8] & 0xe0) == 0xc0: | ||||||
|  | 		return Microsoft | ||||||
|  | 	case (uuid[8] & 0xe0) == 0xe0: | ||||||
|  | 		return Future | ||||||
|  | 	default: | ||||||
|  | 		return Reserved | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Version returns the version of uuid.
 | ||||||
|  | func (uuid UUID) Version() Version { | ||||||
|  | 	return Version(uuid[6] >> 4) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (v Version) String() string { | ||||||
|  | 	if v > 15 { | ||||||
|  | 		return fmt.Sprintf("BAD_VERSION_%d", v) | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("VERSION_%d", v) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (v Variant) String() string { | ||||||
|  | 	switch v { | ||||||
|  | 	case RFC4122: | ||||||
|  | 		return "RFC4122" | ||||||
|  | 	case Reserved: | ||||||
|  | 		return "Reserved" | ||||||
|  | 	case Microsoft: | ||||||
|  | 		return "Microsoft" | ||||||
|  | 	case Future: | ||||||
|  | 		return "Future" | ||||||
|  | 	case Invalid: | ||||||
|  | 		return "Invalid" | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("BadVariant%d", int(v)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetRand sets the random number generator to r, which implements io.Reader.
 | ||||||
|  | // If r.Read returns an error when the package requests random data then
 | ||||||
|  | // a panic will be issued.
 | ||||||
|  | //
 | ||||||
|  | // Calling SetRand with nil sets the random number generator to the default
 | ||||||
|  | // generator.
 | ||||||
|  | func SetRand(r io.Reader) { | ||||||
|  | 	if r == nil { | ||||||
|  | 		rander = rand.Reader | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	rander = r | ||||||
|  | } | ||||||
|  | @ -0,0 +1,44 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/binary" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NewUUID returns a Version 1 UUID based on the current NodeID and clock
 | ||||||
|  | // sequence, and the current time.  If the NodeID has not been set by SetNodeID
 | ||||||
|  | // or SetNodeInterface then it will be set automatically.  If the NodeID cannot
 | ||||||
|  | // be set NewUUID returns nil.  If clock sequence has not been set by
 | ||||||
|  | // SetClockSequence then it will be set automatically.  If GetTime fails to
 | ||||||
|  | // return the current NewUUID returns nil and an error.
 | ||||||
|  | //
 | ||||||
|  | // In most cases, New should be used.
 | ||||||
|  | func NewUUID() (UUID, error) { | ||||||
|  | 	nodeMu.Lock() | ||||||
|  | 	if nodeID == zeroID { | ||||||
|  | 		setNodeInterface("") | ||||||
|  | 	} | ||||||
|  | 	nodeMu.Unlock() | ||||||
|  | 
 | ||||||
|  | 	var uuid UUID | ||||||
|  | 	now, seq, err := GetTime() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return uuid, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	timeLow := uint32(now & 0xffffffff) | ||||||
|  | 	timeMid := uint16((now >> 32) & 0xffff) | ||||||
|  | 	timeHi := uint16((now >> 48) & 0x0fff) | ||||||
|  | 	timeHi |= 0x1000 // Version 1
 | ||||||
|  | 
 | ||||||
|  | 	binary.BigEndian.PutUint32(uuid[0:], timeLow) | ||||||
|  | 	binary.BigEndian.PutUint16(uuid[4:], timeMid) | ||||||
|  | 	binary.BigEndian.PutUint16(uuid[6:], timeHi) | ||||||
|  | 	binary.BigEndian.PutUint16(uuid[8:], seq) | ||||||
|  | 	copy(uuid[10:], nodeID[:]) | ||||||
|  | 
 | ||||||
|  | 	return uuid, nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,38 @@ | ||||||
|  | // Copyright 2016 Google Inc.  All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import "io" | ||||||
|  | 
 | ||||||
|  | // New creates a new random UUID or panics.  New is equivalent to
 | ||||||
|  | // the expression
 | ||||||
|  | //
 | ||||||
|  | //    uuid.Must(uuid.NewRandom())
 | ||||||
|  | func New() UUID { | ||||||
|  | 	return Must(NewRandom()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRandom returns a Random (Version 4) UUID.
 | ||||||
|  | //
 | ||||||
|  | // The strength of the UUIDs is based on the strength of the crypto/rand
 | ||||||
|  | // package.
 | ||||||
|  | //
 | ||||||
|  | // A note about uniqueness derived from the UUID Wikipedia entry:
 | ||||||
|  | //
 | ||||||
|  | //  Randomly generated UUIDs have 122 random bits.  One's annual risk of being
 | ||||||
|  | //  hit by a meteorite is estimated to be one chance in 17 billion, that
 | ||||||
|  | //  means the probability is about 0.00000000006 (6 × 10−11),
 | ||||||
|  | //  equivalent to the odds of creating a few tens of trillions of UUIDs in a
 | ||||||
|  | //  year and having one duplicate.
 | ||||||
|  | func NewRandom() (UUID, error) { | ||||||
|  | 	var uuid UUID | ||||||
|  | 	_, err := io.ReadFull(rander, uuid[:]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return Nil, err | ||||||
|  | 	} | ||||||
|  | 	uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
 | ||||||
|  | 	uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
 | ||||||
|  | 	return uuid, nil | ||||||
|  | } | ||||||
|  | @ -1,23 +0,0 @@ | ||||||
| language: go |  | ||||||
| sudo: false |  | ||||||
| go: |  | ||||||
|     - 1.2 |  | ||||||
|     - 1.3 |  | ||||||
|     - 1.4 |  | ||||||
|     - 1.5 |  | ||||||
|     - 1.6 |  | ||||||
|     - 1.7 |  | ||||||
|     - 1.8 |  | ||||||
|     - 1.9 |  | ||||||
|     - tip |  | ||||||
| matrix: |  | ||||||
|     allow_failures: |  | ||||||
|         - go: tip |  | ||||||
|     fast_finish: true |  | ||||||
| before_install: |  | ||||||
|     - go get github.com/mattn/goveralls |  | ||||||
|     - go get golang.org/x/tools/cmd/cover |  | ||||||
| script: |  | ||||||
|     - $HOME/gopath/bin/goveralls -service=travis-ci |  | ||||||
| notifications: |  | ||||||
|     email: false |  | ||||||
|  | @ -1,20 +0,0 @@ | ||||||
| Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru> |  | ||||||
| 
 |  | ||||||
| Permission is hereby granted, free of charge, to any person obtaining |  | ||||||
| a copy of this software and associated documentation files (the |  | ||||||
| "Software"), to deal in the Software without restriction, including |  | ||||||
| without limitation the rights to use, copy, modify, merge, publish, |  | ||||||
| distribute, sublicense, and/or sell copies of the Software, and to |  | ||||||
| permit persons to whom the Software is furnished to do so, subject to |  | ||||||
| the following conditions: |  | ||||||
| 
 |  | ||||||
| The above copyright notice and this permission notice shall be |  | ||||||
| included in all copies or substantial portions of the Software. |  | ||||||
| 
 |  | ||||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |  | ||||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |  | ||||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |  | ||||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |  | ||||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |  | ||||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |  | ||||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |  | ||||||
|  | @ -1,65 +0,0 @@ | ||||||
| # UUID package for Go language |  | ||||||
| 
 |  | ||||||
| [](https://travis-ci.org/satori/go.uuid) |  | ||||||
| [](https://coveralls.io/github/satori/go.uuid) |  | ||||||
| [](http://godoc.org/github.com/satori/go.uuid) |  | ||||||
| 
 |  | ||||||
| This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. |  | ||||||
| 
 |  | ||||||
| With 100% test coverage and benchmarks out of box. |  | ||||||
| 
 |  | ||||||
| Supported versions: |  | ||||||
| * Version 1, based on timestamp and MAC address (RFC 4122) |  | ||||||
| * Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) |  | ||||||
| * Version 3, based on MD5 hashing (RFC 4122) |  | ||||||
| * Version 4, based on random numbers (RFC 4122) |  | ||||||
| * Version 5, based on SHA-1 hashing (RFC 4122) |  | ||||||
| 
 |  | ||||||
| ## Installation |  | ||||||
| 
 |  | ||||||
| Use the `go` command: |  | ||||||
| 
 |  | ||||||
| 	$ go get github.com/satori/go.uuid |  | ||||||
| 
 |  | ||||||
| ## Requirements |  | ||||||
| 
 |  | ||||||
| UUID package requires Go >= 1.2. |  | ||||||
| 
 |  | ||||||
| ## Example |  | ||||||
| 
 |  | ||||||
| ```go |  | ||||||
| package main |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"github.com/satori/go.uuid" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func main() { |  | ||||||
| 	// Creating UUID Version 4 |  | ||||||
| 	u1 := uuid.NewV4() |  | ||||||
| 	fmt.Printf("UUIDv4: %s\n", u1) |  | ||||||
| 
 |  | ||||||
| 	// Parsing UUID from string input |  | ||||||
| 	u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("Something gone wrong: %s", err) |  | ||||||
| 	} |  | ||||||
| 	fmt.Printf("Successfully parsed: %s", u2) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## Documentation |  | ||||||
| 
 |  | ||||||
| [Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. |  | ||||||
| 
 |  | ||||||
| ## Links |  | ||||||
| * [RFC 4122](http://tools.ietf.org/html/rfc4122) |  | ||||||
| * [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) |  | ||||||
| 
 |  | ||||||
| ## Copyright |  | ||||||
| 
 |  | ||||||
| Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>. |  | ||||||
| 
 |  | ||||||
| UUID package released under MIT License. |  | ||||||
| See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. |  | ||||||
|  | @ -1,206 +0,0 @@ | ||||||
| // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 |  | ||||||
| //
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining
 |  | ||||||
| // a copy of this software and associated documentation files (the
 |  | ||||||
| // "Software"), to deal in the Software without restriction, including
 |  | ||||||
| // without limitation the rights to use, copy, modify, merge, publish,
 |  | ||||||
| // distribute, sublicense, and/or sell copies of the Software, and to
 |  | ||||||
| // permit persons to whom the Software is furnished to do so, subject to
 |  | ||||||
| // the following conditions:
 |  | ||||||
| //
 |  | ||||||
| // The above copyright notice and this permission notice shall be
 |  | ||||||
| // included in all copies or substantial portions of the Software.
 |  | ||||||
| //
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 |  | ||||||
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 |  | ||||||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 |  | ||||||
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 |  | ||||||
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 |  | ||||||
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 |  | ||||||
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/hex" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // FromBytes returns UUID converted from raw byte slice input.
 |  | ||||||
| // It will return error if the slice isn't 16 bytes long.
 |  | ||||||
| func FromBytes(input []byte) (u UUID, err error) { |  | ||||||
| 	err = u.UnmarshalBinary(input) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // FromBytesOrNil returns UUID converted from raw byte slice input.
 |  | ||||||
| // Same behavior as FromBytes, but returns a Nil UUID on error.
 |  | ||||||
| func FromBytesOrNil(input []byte) UUID { |  | ||||||
| 	uuid, err := FromBytes(input) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return Nil |  | ||||||
| 	} |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // FromString returns UUID parsed from string input.
 |  | ||||||
| // Input is expected in a form accepted by UnmarshalText.
 |  | ||||||
| func FromString(input string) (u UUID, err error) { |  | ||||||
| 	err = u.UnmarshalText([]byte(input)) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // FromStringOrNil returns UUID parsed from string input.
 |  | ||||||
| // Same behavior as FromString, but returns a Nil UUID on error.
 |  | ||||||
| func FromStringOrNil(input string) UUID { |  | ||||||
| 	uuid, err := FromString(input) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return Nil |  | ||||||
| 	} |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // MarshalText implements the encoding.TextMarshaler interface.
 |  | ||||||
| // The encoding is the same as returned by String.
 |  | ||||||
| func (u UUID) MarshalText() (text []byte, err error) { |  | ||||||
| 	text = []byte(u.String()) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // UnmarshalText implements the encoding.TextUnmarshaler interface.
 |  | ||||||
| // Following formats are supported:
 |  | ||||||
| //   "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
 |  | ||||||
| //   "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
 |  | ||||||
| //   "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
 |  | ||||||
| //   "6ba7b8109dad11d180b400c04fd430c8"
 |  | ||||||
| // ABNF for supported UUID text representation follows:
 |  | ||||||
| //   uuid := canonical | hashlike | braced | urn
 |  | ||||||
| //   plain := canonical | hashlike
 |  | ||||||
| //   canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
 |  | ||||||
| //   hashlike := 12hexoct
 |  | ||||||
| //   braced := '{' plain '}'
 |  | ||||||
| //   urn := URN ':' UUID-NID ':' plain
 |  | ||||||
| //   URN := 'urn'
 |  | ||||||
| //   UUID-NID := 'uuid'
 |  | ||||||
| //   12hexoct := 6hexoct 6hexoct
 |  | ||||||
| //   6hexoct := 4hexoct 2hexoct
 |  | ||||||
| //   4hexoct := 2hexoct 2hexoct
 |  | ||||||
| //   2hexoct := hexoct hexoct
 |  | ||||||
| //   hexoct := hexdig hexdig
 |  | ||||||
| //   hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
 |  | ||||||
| //             'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
 |  | ||||||
| //             'A' | 'B' | 'C' | 'D' | 'E' | 'F'
 |  | ||||||
| func (u *UUID) UnmarshalText(text []byte) (err error) { |  | ||||||
| 	switch len(text) { |  | ||||||
| 	case 32: |  | ||||||
| 		return u.decodeHashLike(text) |  | ||||||
| 	case 36: |  | ||||||
| 		return u.decodeCanonical(text) |  | ||||||
| 	case 38: |  | ||||||
| 		return u.decodeBraced(text) |  | ||||||
| 	case 41: |  | ||||||
| 		fallthrough |  | ||||||
| 	case 45: |  | ||||||
| 		return u.decodeURN(text) |  | ||||||
| 	default: |  | ||||||
| 		return fmt.Errorf("uuid: incorrect UUID length: %s", text) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // decodeCanonical decodes UUID string in format
 |  | ||||||
| // "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
 |  | ||||||
| func (u *UUID) decodeCanonical(t []byte) (err error) { |  | ||||||
| 	if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { |  | ||||||
| 		return fmt.Errorf("uuid: incorrect UUID format %s", t) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	src := t[:] |  | ||||||
| 	dst := u[:] |  | ||||||
| 
 |  | ||||||
| 	for i, byteGroup := range byteGroups { |  | ||||||
| 		if i > 0 { |  | ||||||
| 			src = src[1:] // skip dash
 |  | ||||||
| 		} |  | ||||||
| 		_, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup]) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		src = src[byteGroup:] |  | ||||||
| 		dst = dst[byteGroup/2:] |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // decodeHashLike decodes UUID string in format
 |  | ||||||
| // "6ba7b8109dad11d180b400c04fd430c8".
 |  | ||||||
| func (u *UUID) decodeHashLike(t []byte) (err error) { |  | ||||||
| 	src := t[:] |  | ||||||
| 	dst := u[:] |  | ||||||
| 
 |  | ||||||
| 	if _, err = hex.Decode(dst, src); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // decodeBraced decodes UUID string in format
 |  | ||||||
| // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format
 |  | ||||||
| // "{6ba7b8109dad11d180b400c04fd430c8}".
 |  | ||||||
| func (u *UUID) decodeBraced(t []byte) (err error) { |  | ||||||
| 	l := len(t) |  | ||||||
| 
 |  | ||||||
| 	if t[0] != '{' || t[l-1] != '}' { |  | ||||||
| 		return fmt.Errorf("uuid: incorrect UUID format %s", t) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return u.decodePlain(t[1 : l-1]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // decodeURN decodes UUID string in format
 |  | ||||||
| // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format
 |  | ||||||
| // "urn:uuid:6ba7b8109dad11d180b400c04fd430c8".
 |  | ||||||
| func (u *UUID) decodeURN(t []byte) (err error) { |  | ||||||
| 	total := len(t) |  | ||||||
| 
 |  | ||||||
| 	urn_uuid_prefix := t[:9] |  | ||||||
| 
 |  | ||||||
| 	if !bytes.Equal(urn_uuid_prefix, urnPrefix) { |  | ||||||
| 		return fmt.Errorf("uuid: incorrect UUID format: %s", t) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return u.decodePlain(t[9:total]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // decodePlain decodes UUID string in canonical format
 |  | ||||||
| // "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format
 |  | ||||||
| // "6ba7b8109dad11d180b400c04fd430c8".
 |  | ||||||
| func (u *UUID) decodePlain(t []byte) (err error) { |  | ||||||
| 	switch len(t) { |  | ||||||
| 	case 32: |  | ||||||
| 		return u.decodeHashLike(t) |  | ||||||
| 	case 36: |  | ||||||
| 		return u.decodeCanonical(t) |  | ||||||
| 	default: |  | ||||||
| 		return fmt.Errorf("uuid: incorrrect UUID length: %s", t) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // MarshalBinary implements the encoding.BinaryMarshaler interface.
 |  | ||||||
| func (u UUID) MarshalBinary() (data []byte, err error) { |  | ||||||
| 	data = u.Bytes() |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
 |  | ||||||
| // It will return error if the slice isn't 16 bytes long.
 |  | ||||||
| func (u *UUID) UnmarshalBinary(data []byte) (err error) { |  | ||||||
| 	if len(data) != Size { |  | ||||||
| 		err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	copy(u[:], data) |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  | @ -1,239 +0,0 @@ | ||||||
| // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 |  | ||||||
| //
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining
 |  | ||||||
| // a copy of this software and associated documentation files (the
 |  | ||||||
| // "Software"), to deal in the Software without restriction, including
 |  | ||||||
| // without limitation the rights to use, copy, modify, merge, publish,
 |  | ||||||
| // distribute, sublicense, and/or sell copies of the Software, and to
 |  | ||||||
| // permit persons to whom the Software is furnished to do so, subject to
 |  | ||||||
| // the following conditions:
 |  | ||||||
| //
 |  | ||||||
| // The above copyright notice and this permission notice shall be
 |  | ||||||
| // included in all copies or substantial portions of the Software.
 |  | ||||||
| //
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 |  | ||||||
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 |  | ||||||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 |  | ||||||
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 |  | ||||||
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 |  | ||||||
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 |  | ||||||
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/md5" |  | ||||||
| 	"crypto/rand" |  | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"hash" |  | ||||||
| 	"net" |  | ||||||
| 	"os" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Difference in 100-nanosecond intervals between
 |  | ||||||
| // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
 |  | ||||||
| const epochStart = 122192928000000000 |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	global = newDefaultGenerator() |  | ||||||
| 
 |  | ||||||
| 	epochFunc = unixTimeFunc |  | ||||||
| 	posixUID  = uint32(os.Getuid()) |  | ||||||
| 	posixGID  = uint32(os.Getgid()) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NewV1 returns UUID based on current timestamp and MAC address.
 |  | ||||||
| func NewV1() UUID { |  | ||||||
| 	return global.NewV1() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV2 returns DCE Security UUID based on POSIX UID/GID.
 |  | ||||||
| func NewV2(domain byte) UUID { |  | ||||||
| 	return global.NewV2(domain) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV3 returns UUID based on MD5 hash of namespace UUID and name.
 |  | ||||||
| func NewV3(ns UUID, name string) UUID { |  | ||||||
| 	return global.NewV3(ns, name) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV4 returns random generated UUID.
 |  | ||||||
| func NewV4() UUID { |  | ||||||
| 	return global.NewV4() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
 |  | ||||||
| func NewV5(ns UUID, name string) UUID { |  | ||||||
| 	return global.NewV5(ns, name) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Generator provides interface for generating UUIDs.
 |  | ||||||
| type Generator interface { |  | ||||||
| 	NewV1() UUID |  | ||||||
| 	NewV2(domain byte) UUID |  | ||||||
| 	NewV3(ns UUID, name string) UUID |  | ||||||
| 	NewV4() UUID |  | ||||||
| 	NewV5(ns UUID, name string) UUID |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Default generator implementation.
 |  | ||||||
| type generator struct { |  | ||||||
| 	storageOnce  sync.Once |  | ||||||
| 	storageMutex sync.Mutex |  | ||||||
| 
 |  | ||||||
| 	lastTime      uint64 |  | ||||||
| 	clockSequence uint16 |  | ||||||
| 	hardwareAddr  [6]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func newDefaultGenerator() Generator { |  | ||||||
| 	return &generator{} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV1 returns UUID based on current timestamp and MAC address.
 |  | ||||||
| func (g *generator) NewV1() UUID { |  | ||||||
| 	u := UUID{} |  | ||||||
| 
 |  | ||||||
| 	timeNow, clockSeq, hardwareAddr := g.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(V1) |  | ||||||
| 	u.SetVariant(VariantRFC4122) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV2 returns DCE Security UUID based on POSIX UID/GID.
 |  | ||||||
| func (g *generator) NewV2(domain byte) UUID { |  | ||||||
| 	u := UUID{} |  | ||||||
| 
 |  | ||||||
| 	timeNow, clockSeq, hardwareAddr := g.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(V2) |  | ||||||
| 	u.SetVariant(VariantRFC4122) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV3 returns UUID based on MD5 hash of namespace UUID and name.
 |  | ||||||
| func (g *generator) NewV3(ns UUID, name string) UUID { |  | ||||||
| 	u := newFromHash(md5.New(), ns, name) |  | ||||||
| 	u.SetVersion(V3) |  | ||||||
| 	u.SetVariant(VariantRFC4122) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV4 returns random generated UUID.
 |  | ||||||
| func (g *generator) NewV4() UUID { |  | ||||||
| 	u := UUID{} |  | ||||||
| 	g.safeRandom(u[:]) |  | ||||||
| 	u.SetVersion(V4) |  | ||||||
| 	u.SetVariant(VariantRFC4122) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
 |  | ||||||
| func (g *generator) NewV5(ns UUID, name string) UUID { |  | ||||||
| 	u := newFromHash(sha1.New(), ns, name) |  | ||||||
| 	u.SetVersion(V5) |  | ||||||
| 	u.SetVariant(VariantRFC4122) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (g *generator) initStorage() { |  | ||||||
| 	g.initClockSequence() |  | ||||||
| 	g.initHardwareAddr() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (g *generator) initClockSequence() { |  | ||||||
| 	buf := make([]byte, 2) |  | ||||||
| 	g.safeRandom(buf) |  | ||||||
| 	g.clockSequence = binary.BigEndian.Uint16(buf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (g *generator) initHardwareAddr() { |  | ||||||
| 	interfaces, err := net.Interfaces() |  | ||||||
| 	if err == nil { |  | ||||||
| 		for _, iface := range interfaces { |  | ||||||
| 			if len(iface.HardwareAddr) >= 6 { |  | ||||||
| 				copy(g.hardwareAddr[:], iface.HardwareAddr) |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Initialize hardwareAddr randomly in case
 |  | ||||||
| 	// of real network interfaces absence
 |  | ||||||
| 	g.safeRandom(g.hardwareAddr[:]) |  | ||||||
| 
 |  | ||||||
| 	// Set multicast bit as recommended in RFC 4122
 |  | ||||||
| 	g.hardwareAddr[0] |= 0x01 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (g *generator) safeRandom(dest []byte) { |  | ||||||
| 	if _, err := rand.Read(dest); err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns UUID v1/v2 storage state.
 |  | ||||||
| // Returns epoch timestamp, clock sequence, and hardware address.
 |  | ||||||
| func (g *generator) getStorage() (uint64, uint16, []byte) { |  | ||||||
| 	g.storageOnce.Do(g.initStorage) |  | ||||||
| 
 |  | ||||||
| 	g.storageMutex.Lock() |  | ||||||
| 	defer g.storageMutex.Unlock() |  | ||||||
| 
 |  | ||||||
| 	timeNow := epochFunc() |  | ||||||
| 	// Clock changed backwards since last UUID generation.
 |  | ||||||
| 	// Should increase clock sequence.
 |  | ||||||
| 	if timeNow <= g.lastTime { |  | ||||||
| 		g.clockSequence++ |  | ||||||
| 	} |  | ||||||
| 	g.lastTime = timeNow |  | ||||||
| 
 |  | ||||||
| 	return timeNow, g.clockSequence, g.hardwareAddr[:] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns difference in 100-nanosecond intervals between
 |  | ||||||
| // UUID epoch (October 15, 1582) and current time.
 |  | ||||||
| // This is default epoch calculation function.
 |  | ||||||
| func unixTimeFunc() uint64 { |  | ||||||
| 	return epochStart + uint64(time.Now().UnixNano()/100) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns UUID based on hashing of namespace UUID and name.
 |  | ||||||
| func newFromHash(h hash.Hash, ns UUID, name string) UUID { |  | ||||||
| 	u := UUID{} |  | ||||||
| 	h.Write(ns[:]) |  | ||||||
| 	h.Write([]byte(name)) |  | ||||||
| 	copy(u[:], h.Sum(nil)) |  | ||||||
| 
 |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
|  | @ -1,78 +0,0 @@ | ||||||
| // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 |  | ||||||
| //
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining
 |  | ||||||
| // a copy of this software and associated documentation files (the
 |  | ||||||
| // "Software"), to deal in the Software without restriction, including
 |  | ||||||
| // without limitation the rights to use, copy, modify, merge, publish,
 |  | ||||||
| // distribute, sublicense, and/or sell copies of the Software, and to
 |  | ||||||
| // permit persons to whom the Software is furnished to do so, subject to
 |  | ||||||
| // the following conditions:
 |  | ||||||
| //
 |  | ||||||
| // The above copyright notice and this permission notice shall be
 |  | ||||||
| // included in all copies or substantial portions of the Software.
 |  | ||||||
| //
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 |  | ||||||
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 |  | ||||||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 |  | ||||||
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 |  | ||||||
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 |  | ||||||
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 |  | ||||||
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"database/sql/driver" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Value implements the driver.Valuer interface.
 |  | ||||||
| func (u UUID) Value() (driver.Value, error) { |  | ||||||
| 	return u.String(), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Scan implements the sql.Scanner interface.
 |  | ||||||
| // A 16-byte slice is handled by UnmarshalBinary, while
 |  | ||||||
| // a longer byte slice or a string is handled by UnmarshalText.
 |  | ||||||
| func (u *UUID) Scan(src interface{}) error { |  | ||||||
| 	switch src := src.(type) { |  | ||||||
| 	case []byte: |  | ||||||
| 		if len(src) == Size { |  | ||||||
| 			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) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NullUUID can be used with the standard sql package to represent a
 |  | ||||||
| // UUID value that can be NULL in the database
 |  | ||||||
| type NullUUID struct { |  | ||||||
| 	UUID  UUID |  | ||||||
| 	Valid bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Value implements the driver.Valuer interface.
 |  | ||||||
| func (u NullUUID) Value() (driver.Value, error) { |  | ||||||
| 	if !u.Valid { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 	// Delegate to UUID Value function
 |  | ||||||
| 	return u.UUID.Value() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Scan implements the sql.Scanner interface.
 |  | ||||||
| func (u *NullUUID) Scan(src interface{}) error { |  | ||||||
| 	if src == nil { |  | ||||||
| 		u.UUID, u.Valid = Nil, false |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Delegate to UUID Scan function
 |  | ||||||
| 	u.Valid = true |  | ||||||
| 	return u.UUID.Scan(src) |  | ||||||
| } |  | ||||||
|  | @ -1,161 +0,0 @@ | ||||||
| // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 |  | ||||||
| //
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining
 |  | ||||||
| // a copy of this software and associated documentation files (the
 |  | ||||||
| // "Software"), to deal in the Software without restriction, including
 |  | ||||||
| // without limitation the rights to use, copy, modify, merge, publish,
 |  | ||||||
| // distribute, sublicense, and/or sell copies of the Software, and to
 |  | ||||||
| // permit persons to whom the Software is furnished to do so, subject to
 |  | ||||||
| // the following conditions:
 |  | ||||||
| //
 |  | ||||||
| // The above copyright notice and this permission notice shall be
 |  | ||||||
| // included in all copies or substantial portions of the Software.
 |  | ||||||
| //
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 |  | ||||||
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 |  | ||||||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 |  | ||||||
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 |  | ||||||
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 |  | ||||||
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 |  | ||||||
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| // Package uuid provides implementation of Universally Unique Identifier (UUID).
 |  | ||||||
| // Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
 |  | ||||||
| // version 2 (as specified in DCE 1.1).
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/hex" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Size of a UUID in bytes.
 |  | ||||||
| const Size = 16 |  | ||||||
| 
 |  | ||||||
| // UUID representation compliant with specification
 |  | ||||||
| // described in RFC 4122.
 |  | ||||||
| type UUID [Size]byte |  | ||||||
| 
 |  | ||||||
| // UUID versions
 |  | ||||||
| const ( |  | ||||||
| 	_ byte = iota |  | ||||||
| 	V1 |  | ||||||
| 	V2 |  | ||||||
| 	V3 |  | ||||||
| 	V4 |  | ||||||
| 	V5 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // UUID layout variants.
 |  | ||||||
| const ( |  | ||||||
| 	VariantNCS byte = iota |  | ||||||
| 	VariantRFC4122 |  | ||||||
| 	VariantMicrosoft |  | ||||||
| 	VariantFuture |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // UUID DCE domains.
 |  | ||||||
| const ( |  | ||||||
| 	DomainPerson = iota |  | ||||||
| 	DomainGroup |  | ||||||
| 	DomainOrg |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // String parse helpers.
 |  | ||||||
| var ( |  | ||||||
| 	urnPrefix  = []byte("urn:uuid:") |  | ||||||
| 	byteGroups = []int{8, 4, 4, 4, 12} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Nil is special form of UUID that is specified to have all
 |  | ||||||
| // 128 bits set to zero.
 |  | ||||||
| var Nil = UUID{} |  | ||||||
| 
 |  | ||||||
| // Predefined namespace UUIDs.
 |  | ||||||
| var ( |  | ||||||
| 	NamespaceDNS  = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) |  | ||||||
| 	NamespaceURL  = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) |  | ||||||
| 	NamespaceOID  = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) |  | ||||||
| 	NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Equal returns true if u1 and u2 equals, otherwise returns false.
 |  | ||||||
| func Equal(u1 UUID, u2 UUID) bool { |  | ||||||
| 	return bytes.Equal(u1[:], u2[:]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Version returns algorithm version used to generate UUID.
 |  | ||||||
| func (u UUID) Version() byte { |  | ||||||
| 	return u[6] >> 4 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Variant returns UUID layout variant.
 |  | ||||||
| func (u UUID) Variant() byte { |  | ||||||
| 	switch { |  | ||||||
| 	case (u[8] >> 7) == 0x00: |  | ||||||
| 		return VariantNCS |  | ||||||
| 	case (u[8] >> 6) == 0x02: |  | ||||||
| 		return VariantRFC4122 |  | ||||||
| 	case (u[8] >> 5) == 0x06: |  | ||||||
| 		return VariantMicrosoft |  | ||||||
| 	case (u[8] >> 5) == 0x07: |  | ||||||
| 		fallthrough |  | ||||||
| 	default: |  | ||||||
| 		return VariantFuture |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Bytes returns bytes slice representation of UUID.
 |  | ||||||
| func (u UUID) Bytes() []byte { |  | ||||||
| 	return u[:] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns canonical string representation of UUID:
 |  | ||||||
| // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 |  | ||||||
| func (u UUID) String() string { |  | ||||||
| 	buf := make([]byte, 36) |  | ||||||
| 
 |  | ||||||
| 	hex.Encode(buf[0:8], u[0:4]) |  | ||||||
| 	buf[8] = '-' |  | ||||||
| 	hex.Encode(buf[9:13], u[4:6]) |  | ||||||
| 	buf[13] = '-' |  | ||||||
| 	hex.Encode(buf[14:18], u[6:8]) |  | ||||||
| 	buf[18] = '-' |  | ||||||
| 	hex.Encode(buf[19:23], u[8:10]) |  | ||||||
| 	buf[23] = '-' |  | ||||||
| 	hex.Encode(buf[24:], u[10:]) |  | ||||||
| 
 |  | ||||||
| 	return string(buf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetVersion sets version bits.
 |  | ||||||
| func (u *UUID) SetVersion(v byte) { |  | ||||||
| 	u[6] = (u[6] & 0x0f) | (v << 4) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetVariant sets variant bits.
 |  | ||||||
| func (u *UUID) SetVariant(v byte) { |  | ||||||
| 	switch v { |  | ||||||
| 	case VariantNCS: |  | ||||||
| 		u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) |  | ||||||
| 	case VariantRFC4122: |  | ||||||
| 		u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) |  | ||||||
| 	case VariantMicrosoft: |  | ||||||
| 		u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) |  | ||||||
| 	case VariantFuture: |  | ||||||
| 		fallthrough |  | ||||||
| 	default: |  | ||||||
| 		u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Must is a helper that wraps a call to a function returning (UUID, error)
 |  | ||||||
| // and panics if the error is non-nil. It is intended for use in variable
 |  | ||||||
| // initializations such as
 |  | ||||||
| //	var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"));
 |  | ||||||
| func Must(u UUID, err error) UUID { |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| 	return u |  | ||||||
| } |  | ||||||
|  | @ -368,6 +368,9 @@ github.com/golang/snappy | ||||||
| github.com/google/go-github/v24/github | github.com/google/go-github/v24/github | ||||||
| # github.com/google/go-querystring v1.0.0 | # github.com/google/go-querystring v1.0.0 | ||||||
| github.com/google/go-querystring/query | github.com/google/go-querystring/query | ||||||
|  | # github.com/google/uuid v1.1.1 | ||||||
|  | ## explicit | ||||||
|  | github.com/google/uuid | ||||||
| # github.com/gorilla/context v1.1.1 | # github.com/gorilla/context v1.1.1 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/gorilla/context | github.com/gorilla/context | ||||||
|  | @ -594,9 +597,6 @@ github.com/quasoft/websspi | ||||||
| github.com/quasoft/websspi/secctx | github.com/quasoft/websspi/secctx | ||||||
| # github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 | # github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 | ||||||
| ## explicit | ## explicit | ||||||
| # github.com/satori/go.uuid v1.2.0 |  | ||||||
| ## explicit |  | ||||||
| github.com/satori/go.uuid |  | ||||||
| # github.com/sergi/go-diff v1.1.0 | # github.com/sergi/go-diff v1.1.0 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/sergi/go-diff/diffmatchpatch | github.com/sergi/go-diff/diffmatchpatch | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue