我正在尝试编写密码生成器。它要求字符以ASCII表示,但我正在尝试使用crypto/rand
。这提供了big.Int
格式的数字,我需要将相关的低8位转换为字符串中可用的形式。到目前为止,我尝试从big.Int
转换为uint8
而没有运气。
有一个好的简单方法吗?我看到了使用encoding/binary
从int64
转换为[8]uint8
的答案,但这些似乎对我的目的来说是不必要的复杂。任何指导都将受到赞赏:)。
答案 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
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))
}
答案 1 :(得分:1)
如果您希望从crypto/rand
中获取字节数,我将完全跳过使用big.Int
和rand.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))
}