我想将big.Int
转换为简单的base32。不是标准的base32内容,如base32
实现的 RFC 4648 , zBase32 , Crockford 我只需要简单的普通5位字符0-9A-V字符集。
我知道base32
包并且它没有做我想要的 - 它使用填充和我不想要的东西在标准的基数32数字中构建结果。当然,我可以使用它并撕下尾随的“=”字符并破解剩下的东西,但这似乎是一个残酷的解决方案。
有一个big.SetString(string, base)
可以解析字符串形式的base32号码,但没有反向 - 我正在寻找的是big.GetString(base)
,就像Java BigInteger.toString(int base)
一样。
然而,nat.string
确实完全我想要的东西。我怎样才能访问它?
有没有办法我可以手动扩展big
来实施big.GetString(base)
,而nat.string
使用正确的charset
来调用big.nat
?
我是否有办法覆盖big
使用nat.string
并nat.trailingZeroBits
使用{{1}}的未导出{{1}}?
我还能做些什么吗?
P.S。我也有兴趣使用{{1}} - 我必须自己编写,因为我没有意识到这已经完成了。
答案 0 :(得分:2)
您根本无法访问未导出的功能。您需要重新编写nat.go
的至少一部分才能实现该功能。其中一些函数看起来非常有用,因此可能值sending a feature request to the golang-nuts
group要求在将来的版本中导出其中一些函数。
但是,您可以使用strconv.FormatInt()
来执行您需要的操作。
给出big.Int
b
即可:
strconv.FormatInt(b.Int64(), 32)
完整示例:
package main
import (
"fmt"
"math/big"
"strconv"
)
func main() {
i := 3286583923486565782 // Some random integer
b := big.NewInt(int64(i))
fmt.Println(strconv.FormatInt(b.Int64(), 32))
}
产地:
2r72al99uq9cm
答案 1 :(得分:2)
我认为go团队不会导出nat
中的任何内容,因为这是big.Int
的实现细节。他们可能会看好ToBase
来自big.Int
的{{1}}功能。
与此同时,这是一款经过轻度测试的天真基础转换器
func ToBase(x *big.Int, base int) string {
if x.Sign() == 0 {
return "0"
}
y := new(big.Int).Set(x)
b := big.NewInt(int64(base))
charset := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
out := make([]byte, 0, 16)
negative := false
if y.Sign() < 0 {
negative = true
y.Neg(y)
}
digit := new(big.Int)
for y.Sign() != 0 {
y.DivMod(y, b, digit)
out = append(out, charset[digit.Int64()])
}
if negative {
out = append(out, '-')
}
// Reverse out
for i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 {
out[i], out[j] = out[j], out[i]
}
return string(out)
}
答案 2 :(得分:1)
我已经贴上了疯狂的帖子。他们似乎对我的建议感到满意。
同时 - 我的Base32实现(不处理符号 - nat
)
// The digits
const charset string = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
/*
Convert the big to base32
*/
func Base32(n big.Int) string {
// The bytes of the number
bytes := n.Bytes()
nBytes := len(bytes)
if nBytes == 0 {
// Special case 0.
return "0"
}
// How many digits will be in the string?
nBits := nBytes * 8
nDigits := nBits / 5
if nBits%5 > 0 {
nDigits += 1
}
// Grow the digits into an array
digits := make([]byte, nDigits)
digit := nDigits - 1
// Peel off 5 bits from the array each time.
for b, shr := nBytes-1, uint(0); b >= 0; {
// The next lot is there.
shrp5 := shr + 5
// Build my bits.
x := (bytes[b] >> shr)
if shrp5 > 8 && b > 0 {
of := shrp5 - 8
// Add in some bits from the next byte too.
x &= (1 << (8 - shr)) - 1
x |= bytes[b-1] << (5 - of)
}
// Shift 5 more.
shr = shrp5
// Should we step to next byte?
if shr >= 8 {
// Next byte
shr -= 8
b -= 1
}
x &= 0x1f
// Build my digit
digits[digit] = charset[x]
digit -= 1
}
// Skip leading zeros.
lz := 0
for digits[lz] == '0' {
lz += 1
}
// Return the string equivalent.
return string(digits[lz:])
}
欢迎评论。