$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

Hatena-Textbook 2018 学習日記(3)

Hatena-Textbook 2018 学習日記(2) - $shibayu36->blog; の続きです。

今回は https://github.com/shibayu36/go-Intern-Diary/compare/01b1518eb0159b4a6d410188fd70ca1901a0e0ef...dca88a611ca9bf338f7fc901a11c1ebbe063ec56 あたりまで。ユーザー名からユーザーを探してくるメソッドや、ログイン用トークンの発行まで行った。

学んだことは

  • ランダム文字列を作る方法
  • database/sqlとgo-sql-driver/mysqlの関係

ランダム文字列を作る方法

go-Intern-Diaryでランダム文字列を作っているところは、テスト用のユーティリティとログイン用トークンの発行。

テスト用は

import "math/rand"
// テストでランダム文字列を使いたいときが多い
func randomString() string {
	return strconv.FormatInt(time.Now().Unix()^rand.Int63(), 16)
}

これはmath/randを用いて64bitのランダム整数が作られて、それを16文字(4bit)で文字列化するので、16文字の[0-9a-f]の文字列が出来るみたい。


続いてログイン用トークンの発行。

import "crypto/rand"
func generateToken() string {
	table := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@"
	l := len(table)
	ret := make([]byte, 128)
	src := make([]byte, 128)
	rand.Read(src)
	for i := 0; i < 128; i++ {
		ret[i] = table[int(src[i])%l]
	}
	return string(ret)
}

これは128文字のランダム文字列を作っている。crypt/randを使っているので暗号学的に安全なランダム文字列が作られる。tableが64文字、byteが8bitで256通りのランダムな値が作られるので、使う文字に偏りなくランダムな文字列が生成されそう。

database/sqlとgo-sql-driver/mysqlの関係

database/sqlはデータベースアクセスへのインターフェースで、go-sql-driver/mysqlは接続先のデータベース種別ごとのドライバとなっている。go-sql-driver/mysqlの説明を見ると、以下のようにimportするだけでdatabase/sqlに登録される。

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

これどうなってるのかなと思ったら、database/sqlRegisterという関数があって、これをgo-sql-driver/mysql/driver.goのinit関数で呼んで、ドライバを登録しているいるようだった。なるほど。