2

我正在尝试编写密码生成器。它要求字符采用 ASCII 表示,但我正在尝试使用crypto/rand. 不过,这提供了big.Int格式的数字,我需要将相关的低 8 位转换为可在字符串中使用的形式。到目前为止,我已经尝试从big.Intto转换为没有运气。uint8

有没有一个好的和简单的方法来做到这一点?我已经看到了涉及 using encoding/binaryto convert from int64to 的答案[8]uint8,但对于我的目的来说,这些似乎不必要地复杂。任何指导都将不胜感激:)。

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 在下面的评论中正确地指出,对于超出int64限制的大整数,上述代码实际上是不正确的。而不是从中提取它big.Bytes(这会复制代表big.IntIIRC 的所有位),使用它可能更高效big.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

如果您想从中获取字节crypto/rand,我会完全跳过使用big.Intandrand.Int()并使用rand.Read()or 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 回答