LoginSignup
17
7

More than 3 years have passed since last update.

golang でランダム文字列生成

Posted at

Go では乱数を返すライブラリはあれど、ランダム文字列を返すライブラリがない(少なくとも今の所は)。
というわけで、パスワードなどでランダムな文字列を生成したい場合は自分で書く必要がある。

ちなみに乱数を生成するには math/randcrypto/rand があり、本記事ではcrypto/randを使っているが、どちらでも良い。

方法1 乱数を使って、定義しておいた定数からランダムに抽出する

以下のような定数 letters を定義しておいて、乱数を使ってランダムに取り出す方法。よく見る。
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
この記事が詳しい。

main.go
package main

import (
    "crypto/rand"
    "errors"
    "fmt"
)

func main() {
    random, _ := MakeRandomStr(10)
    fmt.Println(random)
}

func MakeRandomStr(digit uint32) (string, error) {
    const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

    // 乱数を生成
    b := make([]byte, digit)
    if _, err := rand.Read(b); err != nil {
        return "", errors.New("unexpected error...")
    }

    // letters からランダムに取り出して文字列を生成
    var result string
    for _, v := range b {
        // index が letters の長さに収まるように調整
        result += string(letters[int(v)%len(letters)])
    }
    return result, nil
}

方法2 乱数を使って、ASCIIコードから文字に変換する方法

letters を定義するのダサくね?という人はこんな方法もある。
ただ、制御文字が入らないことをテストするのが実質無理なため、方法1の方が良さそう。

乱数を作るところまでは同じで、それをASCIIコードとみなし、stringにキャストする。

main.go
package main

import (
    "crypto/rand"
    "errors"
    "fmt"
)

func main() {
    random, _ := MakeRandomStr(10)
    fmt.Println(random)
}

func MakeRandomStr(digit uint32) (string, error) {
    // 乱数を生成
    b := make([]byte, digit)
    if _, err := rand.Read(b); err != nil {
        return "", errors.New("unexpected error...")
    }

    // 乱数をASCII文字列に変換
    var result string
    for _, v := range b {
        // 制御文字が当たらないように調整
        result += string(v%byte(94) + 33)
    }
    return result, nil
}
17
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
7