🚙

Golangにおけるbyte型の扱いとユースケース

2024/01/21に公開

イントロダクション

Golangを使っていて「byte型」をなんとなく使っている方は結構いるのではないでしょうか?
自分はかなり雰囲気で使っていたので、調べた内容を記事にしてみました。

byte型の基本

Go言語におけるbyte型は、実際にはuint8型の別名であり、8ビットの符号なし整数を表します。これは、1バイトのデータを格納するのに使われる型です。

わかりやすさの観点から1バイトの単位として処理を行う際にuint8ではなく、byte型を使うのがGolangの慣習らしいです。

UTF-8との対応

Golangの文字列はUTF-8エンコードされたbyte配列として表現できます。
UTF-8は1文字1バイトから最大4バイトで表現する可変長エンコーディングです。

例えば、英語のアルファベットや数字は1バイトで表現されますが、日本語や中国語などの多くの漢字は3バイトで表現されます。
具体的な例を見てみましょう。文字列 "hoge" と "こんにちは" を比較してみます。"hoge" はすべて英語のアルファベットから構成されているため、各文字は1バイトで表現されます
※ 16進数で表現しています。

"hoge" -> [0x68 0x6f 0x67 0x65]

一方で、こんにちは は日本語の文字を含むため、より多くのバイトで表現されます:

"こんにちは" -> [0xe3 0x81 0x93 0xe3 0x82 0x93 0xe3 0x81 0xab 0xe3 0x81 0xa1 0xe3 0x81 0xaf]

このようにGolangにおいて、UTF-8の扱い方を理解することは国際化されたテキスト処理において重要です。
UTF-8コード表(1)

byte型の使用方法

Golangでは内部ではUTF-8で表現されている文字列(string)とbyte型の変換が1番使用頻度が高いと思います。これは文字列データをバイナリデータとして使う際や、暗号化、外部システムとのデータ交換行う際に特に重要になります。

文字列からbyte型への変換

文字列からbyte型への変換は、非常に簡単です。[]byte()関数を使用することで、任意の文字列をbyteのスライスに変換することができます。

例えば、以下のようにして文字列 hoge をbyteのスライスに変換できます:

str := "hoge"
bytes := []byte(str)

この操作により、bytes変数は文字列 "hoge" を表すbyteの配列 [0x68 0x6f 0x67 0x65] を保持します。

byte型から文字列への変換

逆に、byteのスライスから文字列への変換も同様に容易です。string()関数を使用することで、byteのスライスを文字列に戻すことができます。例えば、以下のようにしてbyteの配列を文字列に戻すことができます:

bytes := []byte{0x68, 0x6f, 0x67, 0x65}
str := string(bytes)

この操作により、str変数は文字列 "hoge" を保持します。

byte型の利点とケーススタディ: XOR暗号化による文字列操作

Golangにおけるbyte型の一つの重要な利点は、文字列データを2進数の形式で扱うことができる点です。これにより、文字列に対してビットレベルでの操作、特にXOR演算のようなビットワイズ操作が可能になります。
XOR演算について

文字列のXOR暗号化

func xorString(str string, key byte) string {
    byteData := []byte(str)
    for i := range byteData {
        byteData[i] ^= key
    }
    return string(byteData)
}

func main() {
    originalText := "Secret Message"
    // 鍵
    key := byte(0x3F)
    
    // 暗号化
    encryptedText := xorString(originalText, key)
    fmt.Println("Encrypted:", encryptedText)

        // 復号化
    decryptedText := xorString(encryptedText, key)
    fmt.Println("Decrypted:", decryptedText)
}

このコードでは、最初にxorString関数を使用して文字列 "Secret Message" を暗号化し、その結果を表示しています。その後、同じ関数とキーを使用して暗号化されたテキストを復号化し、元の文字列を回復していす。
※ XOR暗号化はセキュリティ上の弱点が多いので使用しない方が良いです。

まとめ

本記事では、Go言語におけるbyte型についてと文字列とbyte型の間の変換方法について解説しました。
byte型はメモリ効率が良く、ビットレベルでの操作が可能であるため、暗号化やデータ処理において重要な役割を果たします。
Webアプリケーションを作るという観点ではなかなか意識出来ていない部分だと思うので、定期的に振り返りたいですね。

Discussion