github.com/cnotch/ipchub@v1.1.0/provider/security/id.go (about)

     1  /**********************************************************************************
     2  * Copyright (c) 2009-2017 Misakai Ltd.
     3  * This program is free software: you can redistribute it and/or modify it under the
     4  * terms of the GNU Affero General Public License as published by the  Free Software
     5  * Foundation, either version 3 of the License, or(at your option) any later version.
     6  *
     7  * This program is distributed  in the hope that it  will be useful, but WITHOUT ANY
     8  * WARRANTY;  without even  the implied warranty of MERCHANTABILITY or FITNESS FOR A
     9  * PARTICULAR PURPOSE.  See the GNU Affero General Public License  for  more details.
    10  *
    11  * You should have  received a copy  of the  GNU Affero General Public License along
    12  * with this program. If not, see<http://www.gnu.org/licenses/>.
    13  ************************************************************************************/
    14  //
    15  // Copyright (c) 2019,CAOHONGJU All rights reserved.
    16  // Use of this source code is governed by a MIT-style
    17  // license that can be found in the LICENSE file.
    18  
    19  package security
    20  
    21  import (
    22  	"crypto/md5"
    23  	"crypto/sha1"
    24  	"encoding/base32"
    25  	"encoding/base64"
    26  	"encoding/binary"
    27  	"encoding/hex"
    28  	"strconv"
    29  	"strings"
    30  	"sync/atomic"
    31  	"time"
    32  
    33  	"golang.org/x/crypto/pbkdf2"
    34  )
    35  
    36  // ID represents a process-wide unique ID.
    37  type ID uint64
    38  
    39  // next is the next identifier. We seed it with the time in seconds
    40  // to avoid collisions of ids between process restarts.
    41  var next = uint64(
    42  	time.Now().Sub(time.Date(2017, 9, 17, 0, 0, 0, 0, time.UTC)).Seconds(),
    43  )
    44  
    45  // NewID generates a new, process-wide unique ID.
    46  func NewID() ID {
    47  	return ID(atomic.AddUint64(&next, 1))
    48  }
    49  
    50  // Unique generates unique id based on the current id with a prefix and salt.
    51  func (id ID) Unique(prefix uint64, salt string) string {
    52  	buffer := [16]byte{}
    53  	binary.BigEndian.PutUint64(buffer[:8], prefix)
    54  	binary.BigEndian.PutUint64(buffer[8:], uint64(id))
    55  
    56  	enc := pbkdf2.Key(buffer[:], []byte(salt), 4096, 16, sha1.New)
    57  	return strings.Trim(base32.StdEncoding.EncodeToString(enc), "=")
    58  }
    59  
    60  // String converts the ID to a string representation.
    61  func (id ID) String() string {
    62  	return strconv.FormatUint(uint64(id), 10)
    63  }
    64  
    65  // Base64 Base64格式
    66  func (id ID) Base64() string {
    67  	buf := [10]byte{}
    68  	l := binary.PutUvarint(buf[:], uint64(id))
    69  	return base64.RawURLEncoding.EncodeToString(buf[:l])
    70  }
    71  
    72  // Hex 二进制格式
    73  func (id ID) Hex() string {
    74  	buf := [10]byte{}
    75  	l := binary.PutUvarint(buf[:], uint64(id))
    76  	return strings.ToUpper(hex.EncodeToString(buf[:l]))
    77  }
    78  
    79  // MD5 获取ID的MD5值
    80  func (id ID) MD5() string {
    81  	buf := [10]byte{}
    82  	l := binary.PutUvarint(buf[:], uint64(id))
    83  	md5Digest := md5.Sum(buf[:l])
    84  	return hex.EncodeToString(md5Digest[:])
    85  }