日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)GoFrame教程:GoFrame二進(jìn)制編解碼-gbinary

?GOframe?框架提供了獨(dú)立的二進(jìn)制數(shù)據(jù)操作包?gbinary?,主要用于各種數(shù)據(jù)類型與?[ ]byte?二進(jìn)制類型之間的相互轉(zhuǎn)換;以及針對(duì)于整型數(shù)據(jù)進(jìn)行精準(zhǔn)按位處理的功能。常用于網(wǎng)絡(luò)通信時(shí)數(shù)據(jù)編碼/解碼,以及數(shù)據(jù)文件操作時(shí)的編碼/解碼。

成都創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)技術(shù)企業(yè),為成都企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制適合企業(yè)的網(wǎng)站。十年品質(zhì),值得信賴!

使用方式:

import "github.com/gogf/gf/v2/encoding/gbinary"

接口文檔:

https://pkg.go.dev/github.com/gogf/gf/v2/encoding/gbinary

用于二進(jìn)制數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換處理的接口文檔如下:

func Encode(vs ...interface{}) ([]byte, error)
func EncodeInt(i int) []byte
func EncodeInt8(i int8) []byte
func EncodeInt16(i int16) []byte
func EncodeInt32(i int32) []byte
func EncodeInt64(i int64) []byte
func EncodeUint(i uint) []byte
func EncodeUint8(i uint8) []byte
func EncodeUint16(i uint16) []byte
func EncodeUint32(i uint32) []byte
func EncodeUint64(i uint64) []byte
func EncodeBool(b bool) []byte
func EncodeFloat32(f float32) []byte
func EncodeFloat64(f float64) []byte
func EncodeString(s string) []byte

func Decode(b []byte, vs ...interface{}) error
func DecodeToInt(b []byte) int
func DecodeToInt8(b []byte) int8
func DecodeToInt16(b []byte) int16
func DecodeToInt32(b []byte) int32
func DecodeToInt64(b []byte) int64
func DecodeToUint(b []byte) uint
func DecodeToUint8(b []byte) uint8
func DecodeToUint16(b []byte) uint16
func DecodeToUint32(b []byte) uint32
func DecodeToUint64(b []byte) uint64
func DecodeToBool(b []byte) bool
func DecodeToFloat32(b []byte) float32
func DecodeToFloat64(b []byte) float64
func DecodeToString(b []byte) string

支持按位處理的接口文檔如下:

func EncodeBits(bits []Bit, i int, l int) []Bit
func EncodeBitsWithUint(bits []Bit, ui uint, l int) []Bit
func EncodeBitsToBytes(bits []Bit) []byte
func DecodeBits(bits []Bit) uint
func DecodeBitsToUint(bits []Bit) uint
func DecodeBytesToBits(bs []byte) []Bit

其中的?Bit?類型表示一個(gè)二進(jìn)制數(shù)字(0或1),其定義如下:

type Bit int8

二進(jìn)制操作示例

我們來看一個(gè)比較完整的二進(jìn)制操作示例,基本演示了絕大部分的二進(jìn)制轉(zhuǎn)換操作。

github.com/gogf/gf/v2/blob/master/.example/encoding/gbinary/binary.go

package main

import (
    "fmt"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/encoding/gbinary"
)

func main() {
    // 使用gbinary.Encoded對(duì)基本數(shù)據(jù)類型進(jìn)行二進(jìn)制打包
    if buffer := gbinary.Encode(18, 300, 1.01); buffer != nil {
       // glog.Error(err)
    } else {
        fmt.Println(buffer)
    }

    // 使用gbinary.Decode對(duì)整形二進(jìn)制解包,注意第二個(gè)及其后參數(shù)為字長確定的整形變量的指針地址,字長確定的類型,
    // 例如:int8/16/32/64、uint8/16/32/64、float32/64
    // 這里的1.01默認(rèn)為float64類型(64位系統(tǒng)下)
    if buffer := gbinary.Encode(18, 300, 1.01); buffer != nil {
        //glog.Error(err)
    } else {
        var i1 int8
        var i2 int16
        var f3 float64
        if err := gbinary.Decode(buffer, &i1, &i2, &f3); err != nil {
            glog.Error(err)
        } else {
            fmt.Println(i1, i2, f3)
        }
    }

    // 編碼/解析 int,自動(dòng)識(shí)別變量長度
    fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(1)))
    fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(300)))
    fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(70000)))
    fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(2000000000)))
    fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(500000000000)))

    // 編碼/解析 uint,自動(dòng)識(shí)別變量長度
    fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(1)))
    fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(300)))
    fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(70000)))
    fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(2000000000)))
    fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(500000000000)))

    // 編碼/解析 int8/16/32/64
    fmt.Println(gbinary.DecodeToInt8(gbinary.EncodeInt8(int8(100))))
    fmt.Println(gbinary.DecodeToInt16(gbinary.EncodeInt16(int16(100))))
    fmt.Println(gbinary.DecodeToInt32(gbinary.EncodeInt32(int32(100))))
    fmt.Println(gbinary.DecodeToInt64(gbinary.EncodeInt64(int64(100))))

    // 編碼/解析 uint8/16/32/64
    fmt.Println(gbinary.DecodeToUint8(gbinary.EncodeUint8(uint8(100))))
    fmt.Println(gbinary.DecodeToUint16(gbinary.EncodeUint16(uint16(100))))
    fmt.Println(gbinary.DecodeToUint32(gbinary.EncodeUint32(uint32(100))))
    fmt.Println(gbinary.DecodeToUint64(gbinary.EncodeUint64(uint64(100))))

    // 編碼/解析 string
    fmt.Println(gbinary.DecodeToString(gbinary.EncodeString("I'm string!")))
}

以上程序執(zhí)行結(jié)果為:

[18 44 1 41 92 143 194 245 40 240 63]
18 300 1.01
1
300
70000
2000000000
500000000000
1
300
70000
2000000000
500000000000
100
100
100
100
100
100
100
100
I'm string!

編碼

?gbinary.Encode?方法是一個(gè)非常強(qiáng)大靈活的方法,可以將所有的基本類型轉(zhuǎn)換為二進(jìn)制類型(?[ ]byte?)。在?gbinary.Encode?方法內(nèi)部,會(huì)自動(dòng)對(duì)變量進(jìn)行長度計(jì)算,采用最小二進(jìn)制長度來存放該變量的二進(jìn)制值。例如,針對(duì)int類型值為1的變量,?gbinary.Encode?將只會(huì)用1個(gè)byte來存儲(chǔ),而int類型值為300的變量,將會(huì)使用2個(gè)byte來存儲(chǔ),盡量減少二進(jìn)制結(jié)果的存儲(chǔ)空間。因此,在解析的時(shí)候要非常注意?[ ]byte?的長度,建議能夠確定變量長度的地方,在進(jìn)行二進(jìn)制編碼/解碼時(shí),盡量采用形如int8/16/32/64的定長基本類型來存儲(chǔ)變量,這樣解析的時(shí)候也能夠采用對(duì)應(yīng)的變量形式進(jìn)行解析,不易產(chǎn)生錯(cuò)誤。

?gbinary?包也提供了一系列?gbinary.Encode*?的方法,用于將基本數(shù)據(jù)類型轉(zhuǎn)換為二進(jìn)制。其中,?gbinary.EncodeInt/gbinary.EncodeUint?也是會(huì)在內(nèi)部自動(dòng)識(shí)別變量值大小,返回不定長度的?[ ]byte?值,長度范圍1/2/4/8。

解碼

在二進(jìn)制類型的解析操作中,二進(jìn)制的長度(?[ ]byte?的長度)是非常重要的,只有給定正確的長度才能執(zhí)行正確的解析,因此?gbinary.Decode?方法給定的變量長度必須為確定長度類型的變量,例如:int8/16/32/64、uint8/16/32/64、float32/64,而如果給定的第二個(gè)變量地址對(duì)應(yīng)的變量類型為int/uint,無法確定長度,因此解析會(huì)失敗。

此外,?gbinary?包也提供了一系列?gbinary.DecodeTo*?的方法,用于將二進(jìn)制轉(zhuǎn)換為特定的數(shù)據(jù)類型。其中,?gbinary.DecodeToInt/gbinary.DecodeToUint?方法會(huì)對(duì)二進(jìn)制長度進(jìn)行自動(dòng)識(shí)別解析,支持的二進(jìn)制參數(shù)長度范圍1-8。

按位操作處理示例

?gbinary?的Bits相關(guān)操作簡化了底層二進(jìn)制位操作的復(fù)雜度,為精準(zhǔn)的數(shù)據(jù)按位處理提供了可能。

批量傳感器狀態(tài)數(shù)據(jù)上報(bào)示例

例如,針對(duì)于物聯(lián)網(wǎng)項(xiàng)目而言,傳感器設(shè)備是比較常見的硬件設(shè)備,我們以下的示例展示了網(wǎng)關(guān)向平臺(tái)上報(bào)其下管理的傳感器的狀態(tài)信息。由于傳感器狀態(tài)只有4種(0:已下線,1:開啟, 2:關(guān)閉, 3:待機(jī)),正好對(duì)應(yīng)了2個(gè)二進(jìn)制位(2 bit),因此1byte(8 bit)便可以表示出4個(gè)傳感器設(shè)備的狀態(tài)。

看以下的例子,用以上報(bào)平臺(tái)100個(gè)傳感器已開啟,上報(bào)的狀態(tài)順序便是傳感器在網(wǎng)關(guān)下端口順序(索引從0開始):

https://github.com/gogf/gf/v2/blob/master/.example/encoding/gbinary/bits1.go

package main


import (
    "fmt"
    "github.com/gogf/gf/v2/encoding/gbinary"
)


func main() {
    // 傳感器狀態(tài),0:已下線, 1:開啟, 2:關(guān)閉, 3:待機(jī)
    count  := 100
    status := 1


    // 網(wǎng)關(guān)編碼
    bits := make([]gbinary.Bit, 0)
    for i := 0; i < count; i++ {
        bits = gbinary.EncodeBits(bits, int(status), 2)
    }
    buffer := gbinary.EncodeBitsToBytes(bits)
    fmt.Println("buffer length:", len(buffer))


    /* 上報(bào)過程忽略,這里只展示編碼/解碼示例 */


    // 平臺(tái)解碼
    alivecount := 0
    sensorbits := gbinary.DecodeBytesToBits(buffer)
    for i := 0; i < len(sensorbits); i += 2 {
        if gbinary.DecodeBits(sensorbits[i:i+2]) == 1 {
            alivecount++
        }
    }
    fmt.Println("alived sensor:", alivecount)
}

執(zhí)行后輸出結(jié)果為:

buffer length: 25
alived sensor: 100

可以看到,上報(bào)100個(gè)傳感器的狀態(tài)數(shù)據(jù)只需要25byte即可,該示例中我們?cè)谄脚_(tái)上解碼后統(tǒng)計(jì)開啟的傳感器數(shù)量有100臺(tái)。

gkvdb數(shù)據(jù)庫META數(shù)據(jù)結(jié)構(gòu)操作示例

我們?cè)倏纯匆粋€(gè)實(shí)戰(zhàn)的例子。?gkvdb?是?gf?框架相同作者開發(fā)的基于?DRH?算法的高性能?Key-Value?嵌入式數(shù)據(jù)庫,其中元數(shù)據(jù)的存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)如下:

[鍵名哈希64(64bit,8byte) 鍵名長度(8bit,1byte) 鍵值長度(24bit,3byte) 數(shù)據(jù)文件偏移量(40bit,5byte)](變長)

我們使用一條元數(shù)據(jù)來演示編碼/解碼操作。

github.com/gogf/gf/v2/blob/master/.example/encoding/gbinary/bits2.go

package main


import (
    "fmt"
    "github.com/gogf/gf/v2/encoding/gbinary"
)


func main() {
    // Meta元數(shù)據(jù)文件數(shù)據(jù)結(jié)構(gòu):[鍵名哈希64(64bit,8byte) 鍵名長度(8bit,1byte) 鍵值長度(24bit,3byte) 數(shù)據(jù)文件偏移量(40bit,5byte)](變長)
    hash   := 521369841259754125
    klen   := 12
    vlen   := 35535
    offset := 80000000


    // 編碼
    bits   := make([]gbinary.Bit, 0)
    bits    = gbinary.EncodeBits(bits, hash,   64)
    bits    = gbinary.EncodeBits(bits, klen,    8)
    bits    = gbinary.EncodeBits(bits, vlen,   24)
    bits    = gbinary.EncodeBits(bits, offset, 40)
    buffer := gbinary.EncodeBitsToBytes(bits)
    fmt.Println("meta length:", len(buffer))


	/* 文件存儲(chǔ)及數(shù)據(jù)查詢過程忽略,這里只展示元數(shù)據(jù)編碼/解碼示例 */


    // 解碼
    metabits := gbinary.DecodeBytesToBits(buffer)
    fmt.Println("hash  :", gbinary.DecodeBits(metabits[0  : 64]))
    fmt.Println("klen  :", gbinary.DecodeBits(metabits[64 : 72]))
    fmt.Println("vlen  :", gbinary.DecodeBits(metabits[72 : 96]))
    fmt.Println("offset:", gbinary.DecodeBits(metabits[96 : 136]))
}

運(yùn)行后,輸出結(jié)果為:

meta length: 17
hash  : 521369841259754125
klen  : 12
vlen  : 35535
offset: 80000000

當(dāng)前文章:創(chuàng)新互聯(lián)GoFrame教程:GoFrame二進(jìn)制編解碼-gbinary
文章出自:http://www.dlmjj.cn/article/ccopgoe.html