Golang string to uint - go

In my project, ID is designed as snowflakeid. The front end passes a string to me, and the database storage is bigint. This means that before I store it, it needs to be converted to uint. Please tell me what to do?
demo data :
m := "156343853366906880"
my code:
u, _ := strconv.ParseUint(m, 0, 19)
The expected results are accurate and will not lose accuracy

Third parameter of strconv.parseUint() is bitSize. 19 bits are not sufficient to represents the number 156343853366906880. So the method returns an error. (which you are ignoring by assigning it to _)
m := "156343853366906880"
_, err := strconv.ParseUint(m, 0, 19)
fmt.Println(err)
//strconv.ParseUint: parsing "156343853366906880": value out of range 524287
2^19 - 1 = 524287 is the biggest unsigned number that can be represented with 19 bits.
Pass 64 as bitSize :
m := "156343853366906880"
u, err := strconv.ParseUint(m, 0, 64)
if err == nil {
fmt.Print(u)
//156343853366906880
}
If your number is going to greater than uint64 use big.Int :
string to big Int in Go?

SnowflakeID is a time based 64-bit unique id. Since you need to convert string to a 64-bit number, strconv.ParseUint() is quite good. See, the reference at ParseUint.
In your code, you used 19 as bit size. Do not mix it with the number of digit(s) in the integer (unsigned) represented by the string from frontend.
For convert a 64-bit SnowflakeID (string) into a 64-bit unsigned integer, use 64 as bitSize arg.
U, err := strvonv.ParseUint(s, 0, 64)
if err != nil {
// handle error...
}
Also do not try to ignore error, when it really matters.

Related

how to force to save all decimal points of bigFloat in file, instead of rounding

Let's assume I have a very accurate input number(string format), and after math/big manipulation, I want to convert to string format again.
package main
import (
"fmt"
"math/big"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
// edit
s := "3.1415926123456789123456789123456789123456789"
var n, _ = new(big.Float).SetString(s)
// var n = big.NewFloat(3.1415926123456789123456789123456789123456789)
fmt.Println(n) // 3.1415926123456788
N := n.String()
fmt.Println(N) // 3.141592612
d1 := []byte(N)
err := os.WriteFile("./dat1.txt", d1, 0644) // 3.141592612
check(err)
}
How to save a big Float like 3.1415926123456789123456789123456789123456789 into a file? I want to keep all the decimal points, or at least as much as possible
You can parse and store your input "precisely", but you must increase the precision (the default precision doesn't cover that). Use Float.SetPrec() for that (requires a bit-count).
When generating text representation, use Float.Text(), again, with sufficiently large precision (requires a decimal digit-count). If you don't know the required digit-precision, as per the doc, you may use a negative value to have the smallest number of decimal digits that is needed for the Float's mantissa bits.
For example:
s := "3.1415926123456789123456789123456789123456789"
fmt.Println(s)
n := big.NewFloat(0)
n.SetPrec(200)
n.SetString(s)
N := n.Text('f', 50)
fmt.Println(N)
N = n.Text('f', -1)
fmt.Println(N)
This will output (try it on the Go Playground):
3.1415926123456789123456789123456789123456789
3.14159261234567891234567891234567891234567890000000
3.1415926123456789123456789123456789123456789
I've just looked what String method does and its documentation (https://pkg.go.dev/math/big#Float.String).
String formats x like x.Text('g', 10)...
So let's go to that method doc.
func (x *Float) Text(format byte, prec int) string
Text converts the floating-point number x to a string according to the given format and precision prec.
The precision prec controls the number of digits ... A negative precision selects the smallest number of decimal digits necessary to identify the value x uniquely
All you need is just reading the doc.

How to convert scientific notation string to a big.Int?

In golang I have a large number in a string like this: "4.49955000449955e+24".
How can I convert this to a big.Int?
use big.ParseFloat to get a big.Float and then the Int method to convert it to a big.Int:
flt, _, err := big.ParseFloat(input, 10, 0, big.ToNearestEven)
if err != nil {
/* handle a parsing error here */
}
var i = new(big.Int)
i, acc := flt.Int(i)
see it on the Go Playground.
By adjusting the prec argument to ParseFloat you can control the precision of the intermediate float — it takes at least 72 bits of precision for your example input to come out exactly (to a value ending in ten zeroes) but the default if you pass 0 is 64 bits.

How to bit shift hex value using Golang?

Let's say I have a string with the value of 4ADDF6C259EBAFF8.
Using this I want to get a timestamp, using the formula (hex(val) >> 25) + 1008000400.
Using t he encoding/hex package, I have come up with the following:
srcBytes := []byte(src)
dst := make([]byte, hex.EncodedLen(len(srcBytes)))
hex.Encode(dst, srcBytes)
After this, I need a way to bit shift dst 25 times, and then add a constant to it.
However dst is of type []byte.
I need it to be of type hex so I can bit shift after. How do I convert []byte so that it can be shifted?
Assuming your input string varies but has a maximum of 16 hex digits, you just convert to a 64 bit (unsigned) integer and do the math. I also prefixed your constant with 0x assuming it is hex (judging by the digits).
s := "4ADDF6C259EBAFF8"
if i, err := strconv.ParseUint(s, 16, 64); err == nil {
fmt.Printf("%x\n", i >> 25 + 0x1008000400)
}
BTW hex is not a type but a way of displaying integers.

How to create a big int with a secure random

I have this code in java and I need to reproduce in Go.
String nonce = new BigInteger(130, new SecureRandom()).toString(32);
Is the only way to generate a nonce for GDS amadeus soap header 4.
Thanks
Use package math/big and crypto/rand. The snippet looks like:
//Max random value, a 130-bits integer, i.e 2^130 - 1
max := new(big.Int)
max.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(max, big.NewInt(1))
//Generate cryptographically strong pseudo-random between 0 - max
n, err := rand.Int(rand.Reader, max)
if err != nil {
//error handling
}
//String representation of n in base 32
nonce := n.Text(32)
A working example can be found at The Go Playground.
The accepted answer is wrong because the crypto/rand rand.Int function
returns a uniform random value in [0, max). It panics if max <= 0.
Here is an answer that doesn't skip the 2^130 - 1 value.
// Max value, a 130-bits integer, i.e 2^130 - 1
var max *big.Int = big.NewInt(0).Exp(big.NewInt(2), big.NewInt(130), nil)
// Generate cryptographically strong pseudo-random between [0, max)
n, err := rand.Int(rand.Reader, max)
if err != nil {
// error handling
}
fmt.Println(n)

Working with bitstrings and big.Int in Go

I'm new to Go and I'm working on a few exercises to get up to speed. How can I convert a string representing a sequence of bits to the appropriate datatype in Go?
For eg, I see that if its a bitstring representing a 64-bit number, I can do :-
val, err := strconv.ParseInt(bitstring, 2, 64)
However, if the bitstring represents a larger number(say 1024 or 2048 bits), how can I go about converting that number to the appropriate type in Go? I believe the type for managing big integers in Go is big.Int.
Yes, you may use the big.Int type, and its Int.SetString() method, passing 2 as the base.
Example:
i := big.NewInt(0)
if _, ok := i.SetString("10101010101010101010101010101010101010101010101010101010101010101010101010", 2); !ok {
fmt.Println("Invalid number!")
} else {
fmt.Println(i)
}
Output (try it on the Go playground):
12592977287652387236522

Resources