Kepler core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

133 lines
2.9 KiB

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
}
}