Golang:将字节数组转换为big.Int。

huangapple go评论85阅读模式
英文:

Golang: Convert byte array to big.Int

问题

我正在尝试从存储在字节数组中的模数和指数创建一个RSA公钥。经过一些实验,我得到了以下代码:

func bytes_to_int(b []byte) (acc uint64) {
  length := len(b)
  if length % 4 != 0 {
    extra := (4 - length % 4)
    b = append([]byte(strings.Repeat("
func bytes_to_int(b []byte) (acc uint64) {
  length := len(b)
  if length % 4 != 0 {
    extra := (4 - length % 4)
    b = append([]byte(strings.Repeat("\000", extra)), b...)
    length += extra
  }
  var block uint32
  for i := 0; i < length; i += 4 {
    block = binary.BigEndian.Uint32(b[i:i+4])
    acc = (acc << 32) + uint64(block)
  }
  return
}

func main() {
  fmt.Println(bytes_to_int(data[:128]))
  fmt.Println(bytes_to_int(data[128:]))
}
0"
, extra)), b...)
length += extra } var block uint32 for i := 0; i < length; i += 4 { block = binary.BigEndian.Uint32(b[i:i+4]) acc = (acc << 32) + uint64(block) } return } func main() { fmt.Println(bytes_to_int(data[:128])) fmt.Println(bytes_to_int(data[128:])) }

这段代码似乎可以工作(尽管我不确定是否有更好的方法)。我的下一步是将其转换为使用math/big来处理更大的数字。我可以看到有一个Lsh函数可以执行左移操作,但是我无法弄清楚如何将Uint32(block)递归地添加到big.Int中。

供参考,我尝试导入的公钥是存储在密钥环(pubring.mix)中的Mixmaster密钥:
http://www.mixmin.net/draft-sassaman-mixmaster-XX.html#key-format
http://pinger.mixmin.net/pubring.mix

英文:

I'm trying to create an RSA Public Key from a Modulus and Exponent stored in a byte array. After some experimentation I've got the following:

func bytes_to_int(b []byte) (acc uint64) {
  length := len(b)
  if length % 4 != 0 {
    extra := (4 - length % 4)
    b = append([]byte(strings.Repeat(&quot;
func bytes_to_int(b []byte) (acc uint64) {
length := len(b)
if length % 4 != 0 {
extra := (4 - length % 4)
b = append([]byte(strings.Repeat(&quot;\000&quot;, extra)), b...)
length += extra
}
var block uint32
for i := 0; i &lt; length; i += 4 {
block = binary.BigEndian.Uint32(b[i:i+4])
acc = (acc &lt;&lt; 32) + uint64(block)
}
return
}
func main() {
fmt.Println(bytes_to_int(data[:128]))
fmt.Println(bytes_to_int(data[128:]))
}
0&quot;, extra)), b...) length += extra } var block uint32 for i := 0; i &lt; length; i += 4 { block = binary.BigEndian.Uint32(b[i:i+4]) acc = (acc &lt;&lt; 32) + uint64(block) } return } func main() { fmt.Println(bytes_to_int(data[:128])) fmt.Println(bytes_to_int(data[128:])) }

This appears to work (although I'm not convinced there isn't a better way). My next step was to convert it to use math/big in order to handle larger numbers. I can see an Lsh function to do the << but can't figure out how to recursively add the Uint32(block) to the big.Int.

For reference, the Public Key I'm attempting to import is a Mixmaster Key stored in a keyring (pubring.mix):
http://www.mixmin.net/draft-sassaman-mixmaster-XX.html#key-format
http://pinger.mixmin.net/pubring.mix

答案1

得分: 21

你想要使用Int.SetBytes方法,通过一个[]byte切片创建一个big.Int

func (z *Int) SetBytes(buf []byte) *Int

SetBytes方法将buf解释为大端字节序的无符号整数,并将z设置为该值,然后返回z

根据你提供的文档链接,由于你的密钥是按照大端字节序格式存储的,所以在你的应用程序中使用这个方法应该非常简单。

英文:

You want Int.SetBytes to make a big.int from a slice of []byte.

func (z *Int) SetBytes(buf []byte) *Int

SetBytes interprets buf as the bytes of a big-endian unsigned integer, sets z to that value, and returns z.

This should be quite straightforward to use in your application since your keys are in big-endian format according to the doc you linked.

答案2

得分: 12

import "math/big"

z := new(big.Int)
z.SetBytes(byteSliceHere)
import "math/big"

z := new(big.Int)
z.SetBytes(byteSliceHere)
英文:
import &quot;math/big&quot;

z := new(big.Int)
z.SetBytes(byteSliceHere)

答案3

得分: 4

像Nick提到的那样,你可以使用SetBytes函数,但要记住输入是base64编码的,所以你需要先解码。

示例:

func Base64ToInt(s string) (*big.Int, error) {
    data, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        return nil, err
    }
    i := new(big.Int)
    i.SetBytes(data)
    return i, nil
}
英文:

Like Nick mentioned, you could use SetBytes, keep in mind the input is in base64 so you have to decode that first.

<kbd>Example</kbd>:

func Base64ToInt(s string) (*big.Int, error) {
    data, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        return nil, err
    }
    i := new(big.Int)
    i.SetBytes(data)
    return i, nil
}

huangapple
  • 本文由 发表于 2014年7月15日 20:06:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/24757814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定