進数
進数とは、数を表現する方法です。
日常的に使っている「10進数」もその一つですが、コンピュータでは特に以下の進数がよく使われます。
2進数(Binary)
- 基数:2
- 使用する数字:0, 1
- コンピュータの最も基本的な数値表現。ビット(0または1)を用いる
8進数(Octal)
- 基数:8
- 使用する数字:0〜7
- Linuxのパーミッション管理で使われている
16進数(Hexadecimal)
- 基数:16
- 使用する数字:0〜9、A〜F(10進数の10〜15を表す)
- 大量の2進数を短く表現するために便利。メモリのアドレス指定やカラーコードで使われている
エンコーディング
エンコーディングとは、データを特定のルールに基づいて符号化することです。
文字エンコーディング
-
ASCII:
- 7ビットで英数字や記号を表現
- 例:「A」は10進数で65、2進数で01000001
-
UTF-8:
- 可変長のエンコーディング
- ASCIIと互換性があり、世界中の文字を表現可能
データエンコーディング
-
Base64:
- バイナリデータをテキスト形式に変換
- メールやURLでバイナリデータを扱う際に便利
-
URLエンコーディング:
- 特殊文字を % と16進数で表現します。Webで安全にデータを転送するために使用
進数のGoサンプルコード
10進数から他の進数への変換
package main
import "fmt"
func main() {
decimal := 255
fmt.Printf("Decimal: %d\n", decimal)
fmt.Printf("Binary: %b\n", decimal) // 2進数
fmt.Printf("Octal: %o\n", decimal) // 8進数
fmt.Printf("Hexadecimal: %X\n", decimal) // 16進数
}
Decimal: 255
Binary: 11111111
Octal: 377
Hexadecimal: FF
進数を10進数に変換
package main
import (
"fmt"
"strconv"
)
func main() {
binary := "11111111" // 2進数
octal := "377" // 8進数
hex := "FF" // 16進数
// 2進数→10進数
decimalBinary, _ := strconv.ParseInt(binary, 2, 64)
fmt.Printf("Binary to Decimal: %d\n", decimalBinary)
// 8進数→10進数
decimalOctal, _ := strconv.ParseInt(octal, 8, 64)
fmt.Printf("Octal to Decimal: %d\n", decimalOctal)
// 16進数→10進数
decimalHex, _ := strconv.ParseInt(hex, 16, 64)
fmt.Printf("Hexadecimal to Decimal: %d\n", decimalHex)
}
Binary to Decimal: 255
Octal to Decimal: 255
Hexadecimal to Decimal: 255
エンコーディングのGoサンプルコード
文字列をバイトに変換(UTF-8)
package main
import "fmt"
func main() {
text := "こんにちは🌏" // 日本語と地球の絵文字を含む文字列
bytes := []byte(text)
fmt.Printf("Text: %s\n", text)
fmt.Printf("Bytes: %v\n", bytes)
fmt.Println("\nDetails of each byte (UTF-8 encoding):")
// 各バイトを2進数で表示
for i, b := range bytes {
fmt.Printf("Byte %d: %08b\n", i, b)
}
fmt.Println("\nCharacter-wise breakdown:")
// 各文字のUTF-8エンコーディングを表示
for i, r := range text {
fmt.Printf("Character %d: '%c' (code point: %U)\n", i, r, r)
}
}
UTF-8だと、ひらがなは3バイト、絵文字は4バイトなのが確認できる
Text: こんにちは🌏
Bytes: [227 129 147 227 130 147 227 129 171 227 129 161 227 129 175 240 159 140 143]
Details of each byte:
Byte 0: 11100011
Byte 1: 10000001
Byte 2: 10010011
Byte 3: 11100011
Byte 4: 10000010
Byte 5: 10010011
Byte 6: 11100011
Byte 7: 10000001
Byte 8: 10101011
Byte 9: 11100011
Byte 10: 10000001
Byte 11: 10100001
Byte 12: 11100011
Byte 13: 10000001
Byte 14: 10101111
Byte 15: 11110000
Byte 16: 10011111
Byte 17: 10001100
Byte 18: 10001111
Character-wise breakdown:
Character 0: 'こ' (code point: U+3053)
Character 3: 'ん' (code point: U+3093)
Character 6: 'に' (code point: U+306B)
Character 9: 'ち' (code point: U+3061)
Character 12: 'は' (code point: U+306F)
Character 15: '🌏' (code point: U+1F30F)
Base64エンコーディング
package main
import (
"encoding/base64"
"fmt"
"os"
)
func main() {
// 画像を読み込む
filePath := "example.png"
binaryData, err := os.ReadFile(filePath)
if err != nil {
fmt.Println("ファイルの読み込みに失敗しました:", err)
return
}
fmt.Println("元のバイナリデータの長さ:", len(binaryData), "バイト")
// Base64エンコード
base64Encoded := base64.StdEncoding.EncodeToString(binaryData)
fmt.Println("Base64エンコード後のデータ:")
fmt.Println(base64Encoded[:100], "続く...") // データの一部を表示
// Base64デコード
decodedData, err := base64.StdEncoding.DecodeString(base64Encoded)
if err != nil {
fmt.Println("Base64デコードに失敗しました:", err)
return
}
fmt.Println("デコード後のバイナリデータの長さ:", len(decodedData), "バイト")
// デコードしたデータを新しいファイルとして保存
outputPath := "decoded_example.png"
err = os.WriteFile(outputPath, decodedData, 0644)
if err != nil {
fmt.Println("デコードしたデータの書き込みに失敗しました:", err)
return
}
fmt.Println("デコードしたデータをファイルとして保存しました:", outputPath)
}
元のバイナリデータの長さ: 46710 バイト
Base64エンコード後のデータ:
iVBORw0KGgoAAAANSUhEUgAAAZAAAAH0CAMAAAAkBIuyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhp 続く...
デコード後のバイナリデータの長さ: 46710 バイト
デコードしたデータをファイルとして保存しました: decoded_example.png
URLエンコーディング
package main
import (
"fmt"
"net/url"
)
func main() {
// サンプルデータ:エンコードする文字列
rawString := "こんにちは! 😊 & Go=楽しい"
// URLエンコーディング
encoded := url.QueryEscape(rawString)
fmt.Println("エンコード結果:", encoded)
// エンコードされた文字列をデコード
decoded, err := url.QueryUnescape(encoded)
if err != nil {
fmt.Println("デコードエラー:", err)
return
}
fmt.Println("デコード結果:", decoded)
// URLにクエリパラメータとして追加
baseURL := "https://example.com/search"
params := url.Values{}
params.Add("query", rawString)
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
fmt.Println("クエリ付きURL:", fullURL)
// クエリパラメータを解析
parsedURL, err := url.Parse(fullURL)
if err != nil {
fmt.Println("URL解析エラー:", err)
return
}
queryParams := parsedURL.Query()
fmt.Println("解析されたクエリパラメータ:", queryParams.Get("query"))
}
エンコード結果: %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%21+%F0%9F%98%8A+%26+Go%3D%E6%A5%BD%E3%81%97%E3%81%84
デコード結果: こんにちは! 😊 & Go=楽しい
クエリ付きURL: https://example.com/search?query=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%21+%F0%9F%98%8A+%26+Go%3D%E6%A5%BD%E3%81%97%E3%81%84
解析されたクエリパラメータ: こんにちは! 😊 & Go=楽しい