How to cut uuid in golang? - go

In order to make semi-random slugs, I'd like to use first 8 characters of uuid. So I have
import (
fmt
"github.com/satori/go.uuid"
)
u1 := uuid.NewV4()
fmt.Println("u1 :", u1)
runes := []rune(u1)
slug := string(runes[0:7])
But in compile time I get this error:
cannot convert u1 (type uuid.UUID) to type []rune
How can I fix it?

There is no need to convert the UUID to a []rune. That UUID type is stored in a binary representation as a [16]byte. There is a UUID.String() method which you can use to convert to a string, then slice it.
slug := u1.String()[:7]

In that package (I just looked at the source code) a UUID is an alias for [16]byte, so you cannot concert it to a rune array, not that you want to.
Try this:
s := hex.EncodeToString(u1.Bytes()[:4])
This will give you 8 hex digits. However, this is still a roundabout way of doing things. A v4 UUID is random except for certain bits, so if you are not using the whole UUID it is more straightforward to just generate 4 random bytes. Use the Read() function in math/rand (which must be seeded) or crypto/rand (which is what the UUID library uses).
b := make([]byte, 4)
rand.Read(b) // Doesn’t actually fail
s := hex.EncodeToString(b)

Related

How to convert the string representation of a Terraform set of strings to a slice of strings

I've a terratest where I get an output from terraform like so s := "[a b]". The terraform output's value = toset([resource.name]), it's a set of strings.
Apparently fmt.Printf("%T", s) returns string. I need to iterate to perform further validation.
I tried the below approach but errors!
var v interface{}
if err := json.Unmarshal([]byte(s), &v); err != nil {
fmt.Println(err)
}
My current implementation to convert to a slice is:
s := "[a b]"
s1 := strings.Fields(strings.Trim(s, "[]"))
for _, v:= range s1 {
fmt.Println("v -> " + v)
}
Looking for suggestions to current approach or alternative ways to convert to arr/slice that I should be considering. Appreciate any inputs. Thanks.
Actually your current implementation seems just fine.
You can't use JSON unmarshaling because JSON strings must be enclosed in double quotes ".
Instead strings.Fields does just that, it splits a string on one or more characters that match unicode.IsSpace, which is \t, \n, \v. \f, \r and .
Moeover this works also if terraform sends an empty set as [], as stated in the documentation:
returning [...] an empty slice if s contains only white space.
...which includes the case of s being empty "" altogether.
In case you need additional control over this, you can use strings.FieldsFunc, which accepts a function of type func(rune) bool so you can determine yourself what constitutes a "space". But since your input string comes from terraform, I guess it's going to be well-behaved enough.
There may be third-party packages that already implement this functionality, but unless your program already imports them, I think the native solution based on the standard lib is always preferrable.
unicode.IsSpace actually includes also the higher runes 0x85 and 0xA0, in which case strings.Fields calls FieldsFunc(s, unicode.IsSpace)
package main
import (
"fmt"
"strings"
)
func main() {
src := "[a b]"
dst := strings.Split(src[1:len(src)-1], " ")
fmt.Println(dst)
}
https://play.golang.org/p/KVY4r_8RWv6

Pick the random value from slice and print on cli

How to pick the random value from slice in golang and i need to display it to cli.I have string which i converted to string array by splitting it. Now i want to choose random string from string array and display to user in cli and i need to ask user to input that particular string which is displayed on screen
and compare the user entered input.
string randgen := ‘na gd tg er dd wq ff gen vf ws’
s:= String.split(randgen,””)
s = [“na”, “gd”, ”er”, “tg”, “er”, “dd”, “wq”, “ff”, “gen”, “vf”, “ws”]
There are some issues with your code. You shouldn't define the type when initializing a variable using :=.
Also, it's not recommended to depend on spaces to construct and split your slice, as it's not clear what will happen if for example you have multiple spaces, or a tab between the characters instead.
This is a minimal solution that 'just works'.
package main
import (
"fmt"
"math/rand"
"strings"
"time"
)
func main() {
randgen := `na gd tg er dd wq ff gen vf ws`
s := strings.Split(randgen, " ")
fmt.Println(s)
rand.Seed(time.Now().UnixNano())
randIdx := rand.Intn(len(s))
fmt.Println("Randomly selected slice value : ", s[randIdx])
}
I would suggest reading the rand package documentation for an explanation of what rand.Seed does. Also, take a look at the shuffle function available in rand, as it's suited to your problem, if you want to build a more robust solution.

golang simplejson mustint64 doesn't convert from string to int64

I am using simplejson, and it provides type asserters.
fmt.Printf("%s %s", m.Get("created_time").MustString(), m.Get("created_time").MustInt64())
above code shows this result:
1506259900 %!s(int64=0)
So MustInt64() gives 0 instead of converted Int64 value.
Is it because the 1506259900 is too big to be converted?
Thank for your help!
The original json was:
{"created_time":"1505733738"}
Not
{"created_time":1505733738}
It's originally a STRING, not a NUMBER.
So, when use MustInt64() to that json, it should return 0 because type is not matched.
Right way to treat this is using strconv.
i64, err := strconv.ParseInt(m.Get("created_time").MustString(), 10, 64)
And you'll get what you wanted as i64.

Display base 10 representation of huge hexa string?

Trying to find how to have this hexa string "58068906d6194c6cbda7a6df" into it's base 10 representation.
I tried with this:
i, err := strconv.Parse("58068906d6194c6cbda7a6df", 16, 64)
Obviously I'm getting this error: parsing "58068906d6194c6cbda7a6df"; value out of range
I also need to take the base 10 string representation and get this hexa value back after some processing. i.e.:
base10 := "58068906d6194c6cbda7a6df" => to base 10 string
some processing
hexa := base10 => to base 16 string
Can I use the fmt package to dislpay the base 10? I know that displaying the hexa of a base 10 I could use %x, but what can I do with an existing string?
Thanks for your help, for a reason I cannot understand, I'm unable to find any way to do this.
Your hex value is larger than int64 can hold, so you have to use a big.Int
https://play.golang.org/p/OPPL43u6nB
i := new(big.Int)
i.SetString("58068906d6194c6cbda7a6df", 16)
fmt.Println(i)
To get a hex string representation from a big.Int, you can use the Text method:
hex := i.Text(16)

Umlauts and slices

I'm having some trouble while reading a file which has a fixed column length format. Some columns may contain umlauts.
Umlauts seem to use 2 bytes instead of one. This is not the behaviour I was expecting. Is there any kind of function which returns a substring? Slice does not seem to work in this case.
Here's some sample code:
http://play.golang.org/p/ZJ1axy7UXe
umlautsString := "Rhön"
fmt.Println(len(umlautsString))
fmt.Println(umlautsString[0:4])
Prints:
5
Rhö
In go, a slice of a string counts bytes, not runes. This is why "Rhön"[0:3] gives you Rh and the first byte of ö.
Characters encoded in UTF-8 are represented as runes because UTF-8 encodes characters in more than one
byte (up to four bytes) to provide a bigger range of characters.
If you want to slice a string with the [] syntax, convert the string to []rune before.
Example (on play):
umlautsString := "Rhön"
runes = []rune(umlautsString)
fmt.Println(string(runes[0:3])) // Rhö
Noteworthy: This golang blog post about string representation in go.
You can convert string to []rune and work with it:
package main
import "fmt"
func main() {
umlautsString := "Rhön"
fmt.Println(len(umlautsString))
subStrRunes:= []rune(umlautsString)
fmt.Println(len(subStrRunes))
fmt.Println(string(subStrRunes[0:4]))
}
http://play.golang.org/p/__WfitzMOJ
Hope that helps!
Another option is the utf8string package:
package main
import "golang.org/x/exp/utf8string"
func main() {
s := utf8string.NewString("🧡💛💚💙💜")
// example 1
n := s.RuneCount()
println(n == 5)
// example 2
t := s.Slice(0, 2)
println(t == "🧡💛")
}
https://pkg.go.dev/golang.org/x/exp/utf8string

Resources