github.com/TIBCOSoftware/flogo-lib@v0.5.9/util/fastuuid.go (about) 1 package util 2 3 //Copyright © 2014, Roger Peppe 4 //All rights reserved. 5 // 6 //Redistribution and use in source and binary forms, with or without modification, 7 //are permitted provided that the following conditions are met: 8 // 9 //* Redistributions of source code must retain the above copyright notice, 10 //this list of conditions and the following disclaimer. 11 //* Redistributions in binary form must reproduce the above copyright notice, 12 //this list of conditions and the following disclaimer in the documentation 13 //and/or other materials provided with the distribution. 14 //* Neither the name of this project nor the names of its contributors 15 //may be used to endorse or promote products derived from this software 16 //without specific prior written permission. 17 // 18 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 //A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 //OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 //SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24 //TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Package fastuuid provides fast UUID generation of 192 bit 31 // universally unique identifiers. It does not provide 32 // formatting or parsing of the identifiers (it is assumed 33 // that a simple hexadecimal or base64 representation 34 // is sufficient, for which adequate functionality exists elsewhere). 35 // 36 // Note that the generated UUIDs are not unguessable - each 37 // UUID generated from a Generator is adjacent to the 38 // previously generated UUID. 39 // 40 // It ignores RFC 4122. 41 // 42 // fm: Modified to return 128 bit UUID as string 43 44 import ( 45 "crypto/rand" 46 "encoding/binary" 47 "encoding/hex" 48 "errors" 49 "sync/atomic" 50 ) 51 52 // Generator represents a UUID generator that 53 // generates UUIDs in sequence from a random starting 54 // point. 55 type Generator struct { 56 seed [24]byte 57 counter uint64 58 } 59 60 // NewGenerator returns a new Generator. 61 // It can fail if the crypto/rand read fails. 62 func NewGenerator() (*Generator, error) { 63 var g Generator 64 _, err := rand.Read(g.seed[:]) 65 if err != nil { 66 return nil, errors.New("cannot generate random seed: " + err.Error()) 67 } 68 return &g, nil 69 } 70 71 // Next returns the next UUID from the generator. 72 // Only the first 8 bytes can differ from the previous 73 // UUID, so taking a slice of the first 16 bytes 74 // is sufficient to provide a somewhat less secure 128 bit UUID. 75 // 76 // It is OK to call this method concurrently. 77 func (g *Generator) Next() [24]byte { 78 x := atomic.AddUint64(&g.counter, 1) 79 var counterBytes [8]byte 80 binary.LittleEndian.PutUint64(counterBytes[:], x) 81 82 uuid := g.seed 83 for i, b := range counterBytes { 84 uuid[i] ^= b 85 } 86 return uuid 87 } 88 89 // NextAsString returns the next UUID from the generator as a string. 90 func (g *Generator) NextAsString() string { 91 x := atomic.AddUint64(&g.counter, 1) 92 var counterBytes [8]byte 93 binary.LittleEndian.PutUint64(counterBytes[:], x) 94 95 uuid := g.seed 96 for i, b := range counterBytes { 97 uuid[i] ^= b 98 } 99 100 buf := make([]byte, 32) 101 hex.Encode(buf[0:], uuid[0:16]) //truncate to 128bit UUID 102 103 return string(buf) 104 }