package misc
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"encoding/binary"
|
|
"reflect"
|
|
|
|
"github.com/archsh/go.uuid"
|
|
)
|
|
|
|
// Generate DeviceId according given prefix and mac, model
|
|
// 00000000-0000-0000-0000-000000000000
|
|
// *prefix*-MCRC-0000-MCRC-***MAC******
|
|
func Generate_DeviceId(prefix uint32, mac string, model ...string) (uuid.UUID, error) {
|
|
//println("Generate_DeviceId:>", prefix, mac, model)
|
|
tmp := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
|
m, e := MacAddr2Bytes(mac)
|
|
if nil != e {
|
|
println("Generate_DeviceId:> MacAddr2Bytes() failed:", e)
|
|
return uuid.Nil, e
|
|
}
|
|
for i, x := range m {
|
|
tmp[10+i] = x
|
|
}
|
|
binary.BigEndian.PutUint32(tmp[0:4], prefix)
|
|
binary.BigEndian.PutUint16(tmp[4:6], CRC16(tmp[:4]))
|
|
mac_crc16 := CRC16(m)
|
|
var model_crc16 uint16 = 0
|
|
if len(model) > 0 {
|
|
model_crc16 = CRC16([]byte(model[0]))
|
|
}
|
|
binary.BigEndian.PutUint16(tmp[6:8], model_crc16)
|
|
binary.BigEndian.PutUint16(tmp[8:10], mac_crc16)
|
|
copy(tmp[10:], m)
|
|
u, e := uuid.FromBytes(tmp)
|
|
return u, e
|
|
}
|
|
|
|
func Validate_DeviceId(s string, mac string, model ...string) bool {
|
|
u, e := uuid.FromString(s)
|
|
if nil != e {
|
|
return false
|
|
}
|
|
m, e := MacAddr2Bytes(mac)
|
|
if nil != e {
|
|
return false
|
|
}
|
|
ubytes := u.Bytes()
|
|
mac_crc16 := CRC16(m)
|
|
var model_crc16 uint16 = 0
|
|
if len(model) > 0 {
|
|
model_crc16 = CRC16([]byte(model[0]))
|
|
}
|
|
if binary.BigEndian.Uint16(ubytes[4:6]) != CRC16(ubytes[0:4]) {
|
|
return false
|
|
}
|
|
if binary.BigEndian.Uint16(ubytes[6:8]) != model_crc16 {
|
|
return false
|
|
}
|
|
if binary.BigEndian.Uint16(ubytes[8:10]) != mac_crc16 {
|
|
return false
|
|
}
|
|
if ! EqualBytes(ubytes[10:], m) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func Validate_DeviceId_Simple(s string) bool {
|
|
u, e := uuid.FromString(s)
|
|
if nil != e {
|
|
return false
|
|
}
|
|
ubytes := u.Bytes()
|
|
if binary.BigEndian.Uint16(ubytes[4:6]) != CRC16(ubytes[0:4]) {
|
|
return false
|
|
}
|
|
if binary.BigEndian.Uint16(ubytes[8:10]) != CRC16(ubytes[10:]) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func getType(myvar interface{}) string {
|
|
if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr {
|
|
return t.Elem().Name()
|
|
} else {
|
|
return t.Name()
|
|
}
|
|
}
|
|
|
|
func MakeObjectId(entity interface{}, refs ...interface{}) string {
|
|
refIds := []interface{}{getType(entity)}
|
|
refIds = append(refIds, refs...)
|
|
uid := MakeResourceId(refIds...)
|
|
return uid.String()
|
|
}
|
|
|
|
func MakeResourceId(refIds ...interface{}) uuid.UUID {
|
|
//fmt.Println("MakeResourceId:::>", refIds)
|
|
var args []interface{}
|
|
for _, s := range refIds {
|
|
if v, ok := s.(string); ok {
|
|
args = append(args, CRC16([]byte(v)))
|
|
} else {
|
|
switch s.(type) {
|
|
case uint8, uint16, uint32, uint64:
|
|
args = append(args, s)
|
|
default:
|
|
panic("Invalid type.")
|
|
}
|
|
}
|
|
}
|
|
return uuid.FromUintX(args...)
|
|
}
|
|
|
|
func MakeMixUUID(uids ...uuid.UUID) uuid.UUID {
|
|
if len(uids) == 0 {
|
|
return uuid.UUID{}
|
|
} else if len(uids) == 1 {
|
|
return uids[0]
|
|
} else {
|
|
h := md5.New()
|
|
for _, uid := range uids {
|
|
h.Write(uid.Bytes())
|
|
}
|
|
uid, err := uuid.FromBytes(h.Sum(nil))
|
|
if nil != err {
|
|
panic(err)
|
|
}
|
|
return uid
|
|
}
|
|
}
|