将big.Int的最后8位放入uint8

时间:2012-09-29 14:01:36

标签: type-conversion go

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

有一个好的简单方法吗?我看到了使用encoding/binaryint64转换为[8]uint8的答案,但这些似乎对我的目的来说是不必要的复杂。任何指导都将受到赞赏:)。

2 个答案:

答案 0 :(得分: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.Int IIRC的所有位的副本)中提取它,使用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-

答案 1 :(得分:1)

如果您希望从crypto/rand中获取字节数,我将完全跳过使用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))
}