Kravitz
Kravitz

Reputation: 2859

How can I convert a *big.Int into a byte array in golang

Im trying to do calculations on a big int number and then convert the result to a byte array, but I cannot figure out how to do so this is where Im at so far. anyone got any ideas

sum := big.NewInt(0)

for _, num := range balances {
    sum = sum.Add(sum, num)
}

fmt.Println("total: ", sum)

phrase := []byte(sum)
phraseLen := len(phrase)
padNumber := 65 - phraseLen

Upvotes: 11

Views: 9591

Answers (2)

Yuriy Vasylenko
Yuriy Vasylenko

Reputation: 3171

There is a problem with a sign in suggested .Bytes() function. I assume you were doing it for serialization. If so, you could just represent it as a string in whatever format you wish.

func BIntToBytes(bI *big.Int) []byte {
    return []byte(fmt.Sprintf("%x", bI))
}

func BytesToBInt(bts []byte) *big.Int {
    var bI big.Int
    fmt.Sscanf(string(bts), "%x", &bI)
    return &bI
}

And the test

func TestBIntConversion(t *testing.T) {
    bI := big.NewInt(-1304558504092135411)
    bIPositive := big.NewInt(1304558504092135411)
    bts := BIntToBytes(bI)
    assert.Equal(t, bI, BytesToBInt(bts))
    assert.NotEqual(t, bIPositive, BytesToBInt(bts))

    btsPos := BIntToBytes(bIPositive)
    assert.Equal(t, bIPositive, BytesToBInt(btsPos))
}

Upvotes: 0

maerics
maerics

Reputation: 156592

Try using Int.Bytes() to get the byte array representation and Int.SetBytes([]byte) to set the value from a byte array. For example:

x := new(big.Int).SetInt64(123456)
fmt.Printf("OK: x=%s (bytes=%#v)\n", x, x.Bytes())
// OK: x=123456 (bytes=[]byte{0x1, 0xe2, 0x40})

y := new(big.Int).SetBytes(x.Bytes())
fmt.Printf("OK: y=%s (bytes=%#v)\n", y, y.Bytes())
// OK: y=123456 (bytes=[]byte{0x1, 0xe2, 0x40})

Note that the byte array value of big numbers is a compact machine representation and should not be mistaken for the string value, which can be retrieved by the usual String() method (or Text(int) for different bases) and set from a string value by the SetString(...) method:

a := new(big.Int).SetInt64(42)
a.String() // => "42"

b, _ := new(big.Int).SetString("cafebabe", 16)
b.String() // => "3405691582"
b.Text(16) // => "cafebabe"
b.Bytes()  // => []byte{0xca, 0xfe, 0xba, 0xbe}

Upvotes: 12

Related Questions