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

广告
将在 10 秒后关闭
bannerAds