2

I'm trying to write a password generator. It requires that characters be in ASCII representation, but I'm trying to use crypto/rand. This provides numbers in big.Int format, though, and I need to convert the relevant lower 8 bits to a form usable in a string. I've tried converting from big.Int to uint8 with no luck so far.

Is there a good and easy method to do this? I have seen answers involving using encoding/binary to convert from int64 to [8]uint8, but those seem needlessly complex for my purpose. Any guidance at all would be appreciated :).

4

2 に答える 2

2
package main

import (
        "fmt"
        "math/big"
)

func main() {
        mpInt := big.NewInt(0x123456789abcdef0)
        b := byte(mpInt.Int64())
        fmt.Printf("%02x", b)
}

f0

実際: http://play.golang.org/p/92PbLdiVsP


編集: Evan Shaw は、上記のコードが実際には制限外の大きな Int に対して正しくないことをコメントで正しく指摘していint64ます。( IIRCbig.Bytesを表すすべてのビットのコピーを作成する)からそれを引き出す代わりに、おそらく使用する方がパフォーマンスが高くなります:big.Intbig.And


package main

import (
        "fmt"
        "log"
        "math/big"
)

func lsB(n *big.Int) byte {
        var m big.Int
        return byte(m.And(m.SetInt64(255), n).Int64())
}

func main() {
        var mpInt big.Int
        if _, ok := mpInt.SetString("0x123456789abcdef012342", 0); !ok {
                log.Fatal()
        }

        fmt.Printf("%02x", lsB(&mpInt))
}

プレイグラウンド: http://play.golang.org/p/pgkGEFgb8-

于 2012-09-29T14:57:31.117 に答える
1

からバイトを取得したい場合は、 and の使用を完全にcrypto/randスキップして、 or のいずれかを使用します。big.Intrand.Int()rand.Read()rand.Reader

package main

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

// If you want just a byte at a time ...
// (you could change 'byte' to int8 if you prefer)    
func secureRandomByte() byte {
    data := make([]byte, 1)
    if _, err := rand.Read(data); err != nil {
        // handle error
        panic(err)
    }
    return data[0]
}

// If you want to read multiple bytes at a time ...
func genPassword(len int) (string, error) {
    data := make([]byte, len)
    if _, err := io.ReadFull(rand.Reader, data); err != nil {
        // handle error
        return "", err
    }
    for i := range data {
        // XXX quick munge into something printable
        data[i] &= 0x3F
        data[i] += 0x20
    }
    return string(data), nil
}

func main() {
    b := secureRandomByte()
    fmt.Printf("%T = %v\n", b, b)
    fmt.Println(genPassword(16))
}
于 2012-09-29T23:40:43.630 に答える