golang实现java uuid和string的序列化
2020-10-06 本文已影响0人
EasyNetCN
终于搞定,直接上码
package utility
import (
"bytes"
"encoding/binary"
"github.com/google/uuid"
)
const (
STREAM_MAGIC = 0xaced
STREAM_VERSION = 5
TC_STRING = 0x74
TC_OBJECT = 0x73
TC_CLASSDESC = 0x72
SC_SERIALIZABLE = 0x02
TC_ENDBLOCKDATA = 0x78
TC_NULL = 0x70
UUID_SERIAL_VERSION_UID = -4856846361193249489
)
func StringJavaBytes(str string) []byte {
buf := new(bytes.Buffer)
buf.Write(ShortBytes(STREAM_MAGIC))
buf.Write(ShortBytes(STREAM_VERSION))
buf.Write([]byte{TC_STRING})
strLen := len(str)
buf.Write(ShortBytes(uint16(strLen)))
buf.Write([]byte(str))
return buf.Bytes()
}
func UUIDJavaBytes(uuid uuid.UUID) []byte {
byteBuffer := new(bytes.Buffer)
byteBuffer.Write(ShortBytes(STREAM_MAGIC))
byteBuffer.Write(ShortBytes(STREAM_VERSION))
byteBuffer.Write([]byte{TC_OBJECT})
byteBuffer.Write([]byte{TC_CLASSDESC})
className := "java.util.UUID"
classNameLen := len(className)
byteBuffer.Write(ShortBytes(uint16(classNameLen)))
byteBuffer.Write([]byte(className))
sid := UUID_SERIAL_VERSION_UID
byteBuffer.Write(LongBytes(uint64(sid)))
//flags
byteBuffer.Write([]byte{2})
//fields length
byteBuffer.Write(ShortBytes(2))
//filed type code
byteBuffer.Write([]byte{'J'})
f1 := "leastSigBits"
f1Len := len(f1)
byteBuffer.Write(ShortBytes(uint16(f1Len)))
byteBuffer.Write([]byte(f1))
//filed type code
byteBuffer.Write([]byte{'J'})
f2 := "mostSigBits"
f2Len := len(f2)
byteBuffer.Write(ShortBytes(uint16(f2Len)))
byteBuffer.Write([]byte(f2))
byteBuffer.Write([]byte{TC_ENDBLOCKDATA})
byteBuffer.Write([]byte{TC_NULL})
mostSigBits, leastSigBits := UUIDSigBits(uuid)
byteBuffer.Write(LongBytes(uint64(leastSigBits)))
byteBuffer.Write(LongBytes(uint64(mostSigBits)))
return byteBuffer.Bytes()
}
func UUIDSigBits(uuid uuid.UUID) (int64, int64) {
msb := int64(0)
lsb := int64(0)
for i, b := range uuid {
if i >= 0 && i < 8 {
msb = (msb << 8) | int64(b&0xff)
} else if i >= 8 && i < 16 {
lsb = (lsb << 8) | int64(b&0xff)
}
}
return msb, lsb
}
func ShortBytes(i uint16) []byte {
bytes := make([]byte, 2)
binary.BigEndian.PutUint16(bytes, i)
return bytes
}
func LongBytes(i uint64) []byte {
bytes := make([]byte, 8)
binary.BigEndian.PutUint64(bytes, i)
return bytes
}