Go 言語(以下 Golang)で、make([]byte, 8, 8) で作成した 8 バイトのスライスを uint64符号なしint に変換したい。
「golang “[]byte” uint64 変換」でググっても、逆の uint64 から []byte に変換するものや、int32 のリトルエンディアン後ろ詰め方式 だったり、符号あり前提のものばかりだったので、自分のググラビリティとして。
TL; DR (今北産業)
encoding/binary の Golang 標準パッケージを使う。
binary.BigEndian.Uint64(b []byte) uint64 メソッドを使う。4 バイト・スライスの場合は binary.BigEndian.Uint16(b []byte) uint16。
使い方: myUint64 := binary.BigEndian.Uint64(myByteSlice)
my8byte := []byte{255, 0, 255, 0, 255, 0, 255, 0}
myUint64 := binary.BigEndian.Uint64(my8byte)
fmt.Printf(
“Type: %T\nDec : %d\nBin : %064b\n”,
myUint64, myUint64, myUint64,
)
// Output:
// Type: uint64
// Dec : 18374966859414961920
// Bin : 1111111100000000111111110000000011111111000000001111111100000000
オンラインで動作を見る @ Go Playground
TS; DR cap 付き []byte スライスの結合・連結からの UINT64
2 つの 4 バイト長のデータを、各々 byte スライス([]byte、バイトごとの配列状態)にブツ切りにした後、ゴニョゴニョしてから、1 つに結合した len = 8要素数 8 のスライスを uint64 に変換したかったのです。
この時、cap 付き領域予約済みでイジッているので、なるべくリアロケート領域を再確保させたくなかったのです。つまり append を使わないで結合したかったのです。
誰に需要があるのかわかりませんが、以下は 4 バイト長の 2 つのスライス を結合した、8 バイト・スライスを uint64 に変換する例です。
package main
import (
"encoding/binary"
"fmt"
)
func main() {
var v = make([]byte, 8, 8) // なぜか 8 バイト cap で宣言されている変数
a8 := []byte{49, 50, 51, 52} // ゴニョゴニョ済みの 4 バイトデータ
b8 := []byte{65, 66, 67, 68} // ゴニョゴニョ済みの 4 バイトデータ
copy(v, a8) // 前半にコピー
copy(v[4:], b8) // 後半にコピー
fmt.Printf(
"v = Len: %d, Cap: %d, String: \"%s\", Data: %d\n",
len(v),
cap(v),
string(v),
binary.BigEndian.Uint64(v), // ここがポイント
)
}
// Output:
// v = Len: 8, Cap: 8, String: "1234ABCD", Data: 3544952156220179268
オンラインで動作を見る @ Go Playground
参考文献
Converting variable-sized []byte to int64 in Golang @ Stackoverflow