mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 08:03:43 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			54 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			54 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package identity
 | |
| 
 | |
| import (
 | |
| 	cryptorand "crypto/rand"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"math/big"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// idReader is used for random id generation. This declaration allows us to
 | |
| 	// replace it for testing.
 | |
| 	idReader = cryptorand.Reader
 | |
| )
 | |
| 
 | |
| // parameters for random identifier generation. We can tweak this when there is
 | |
| // time for further analysis.
 | |
| const (
 | |
| 	randomIDEntropyBytes = 17
 | |
| 	randomIDBase         = 36
 | |
| 
 | |
| 	// To ensure that all identifiers are fixed length, we make sure they
 | |
| 	// get padded out or truncated to 25 characters.
 | |
| 	//
 | |
| 	// For academics,  f5lxx1zz5pnorynqglhzmsp33  == 2^128 - 1. This value
 | |
| 	// was calculated from floor(log(2^128-1, 36)) + 1.
 | |
| 	//
 | |
| 	// While 128 bits is the largest whole-byte size that fits into 25
 | |
| 	// base-36 characters, we generate an extra byte of entropy to fill
 | |
| 	// in the high bits, which would otherwise be 0. This gives us a more
 | |
| 	// even distribution of the first character.
 | |
| 	//
 | |
| 	// See http://mathworld.wolfram.com/NumberLength.html for more information.
 | |
| 	maxRandomIDLength = 25
 | |
| )
 | |
| 
 | |
| // NewID generates a new identifier for use where random identifiers with low
 | |
| // collision probability are required.
 | |
| //
 | |
| // With the parameters in this package, the generated identifier will provide
 | |
| // ~129 bits of entropy encoded with base36. Leading padding is added if the
 | |
| // string is less 25 bytes. We do not intend to maintain this interface, so
 | |
| // identifiers should be treated opaquely.
 | |
| func NewID() string {
 | |
| 	var p [randomIDEntropyBytes]byte
 | |
| 
 | |
| 	if _, err := io.ReadFull(idReader, p[:]); err != nil {
 | |
| 		panic(fmt.Errorf("failed to read random bytes: %v", err))
 | |
| 	}
 | |
| 
 | |
| 	p[0] |= 0x80 // set high bit to avoid the need for padding
 | |
| 	return (&big.Int{}).SetBytes(p[:]).Text(randomIDBase)[1 : maxRandomIDLength+1]
 | |
| }
 | 
