Skip to content

Instantly share code, notes, and snippets.

@chaosmatrix
Last active August 12, 2023 14:16
Show Gist options
  • Save chaosmatrix/bc4a3d423273becbda3657102a12c5cd to your computer and use it in GitHub Desktop.
Save chaosmatrix/bc4a3d423273becbda3657102a12c5cd to your computer and use it in GitHub Desktop.
golang tips

check file permission bits

// executable
if stat, err := os.Stat(filename); err != nil {
  panic(err)
}
if stat.Mode().Perm() & 0111 == 0000 {
  fmt.Printf("%s not executable\n", filename)
}
@chaosmatrix
Copy link
Author

Golang Upgrade Version

  1. go get only check library's version, won't re-compile tools after go version change

@chaosmatrix
Copy link
Author

Example

s = "ab"

s[i] is uint8 type

for _, r := range s {
    // r is rune type, is int32 type
}

int(s[0] - s[1]) => int(uint8(uint8(s[1]) - uint8(s[0])))

s[0] < s[1], so, s[0] - s[1] = -1, as uint8, will overflow as 255

int(s[0]) - int(s[1]) = -1

@chaosmatrix
Copy link
Author

chaosmatrix commented Aug 2, 2023

net.IP

Rules:

  1. Both IPv4 and IPv6 address store as IPv6 address
  2. To16() can convert IPv4 to IPv6 (because IPv4 store as IPv6 format)
  3. To4() will check if the IP address is valid IPv4 or not (::ffff:808:808 is valid IPv4)
  4. String(): all valid IPv4 address will be show as IPv4 format (::ffff:808:808 will be show as 8.8.8.8)
  5. When you want to know a string is valid IP and distinguish between IPv4 and IPv6, it's good to use netip.ParseAddr() in net/netip
Example
input string net.ParseIP() String() To4()
2607:f8b0:4006:81f::2004 net.IP{0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4} 2607:f8b0:4006:81f::2004 nil
8.8.8.8 net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x8, 0x8, 0x8, 0x8} 8.8.8.8
::ffff:808:808 net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x8, 0x8, 0x8, 0x8} 8.8.8.8

Cookbooks:

Check an Input string is valid IPv4 address (dotted decimal notations)
ip := net.ParseIP(s)
if ip != nil && ip.To4() != nil && !strings.Contains(s, ":") {
    return true
}
return false
Check an IP is valid IPv6 address

All IP addresses are IPv6 address, you can only check an IP address is valid IPv4 or not

ip := net.ParseIP(s)
if ip != nil && ip.To4() == nil {
    return false
}
return ip != nil

@chaosmatrix
Copy link
Author

net/netip

package main

import (
	"fmt"
	"net/netip"
)

func main() {

	ts := []string {
        "2001:db8::68",
        "8.8.8.8",
        "::ffff:808:808",
        "0:0:0:0:0:ffff:0808:0808",
        "0000:0000:0000:0000:0000:ffff:0808:0808",
    }
    for _, s := range ts {
		addr, err := netip.ParseAddr(s)
		if err == nil {
			fmt.Printf("ip: %s, is_ipv4: %v, is_ipv4Toipv6: %v, is_ipv6: %v, string: %s\n", s, addr.Is4(), addr.Is4In6(), addr.Is6(), addr.String())
		} else {
			fmt.Printf("[+] invalid ip %s\n", s)
		}
	}
}

Output:

ip: 2001:db8::68, is_ipv4: false, is_ipv4Toipv6: false, is_ipv6: true, string: 2001:db8::68
ip: 8.8.8.8, is_ipv4: true, is_ipv4Toipv6: false, is_ipv6: false, string: 8.8.8.8
ip: ::ffff:808:808, is_ipv4: false, is_ipv4Toipv6: true, is_ipv6: true, string: ::ffff:8.8.8.8
ip: 0:0:0:0:0:ffff:0808:0808, is_ipv4: false, is_ipv4Toipv6: true, is_ipv6: true, string: ::ffff:8.8.8.8
ip: 0000:0000:0000:0000:0000:ffff:0808:0808, is_ipv4: false, is_ipv4Toipv6: true, is_ipv6: true, string: ::ffff:8.8.8.8

@chaosmatrix
Copy link
Author

chaosmatrix commented Aug 4, 2023

time.Timer vs time.Ticker

Diff:

  1. Timer need to Reset every time when it fired
  2. Ticker auto reset every time when it fired

Warning:

  1. when the job wast more than ticker duration, there might has more than one job executed or lose some ticker

The difference of them show as code

// timer
for {
    time.Sleep(d)
    do_some_thing
    // timer reset
}

// ticker
for {
    time.Sleep(d)
    go func() {
        do_some_thing
    }()
   // wait next ticker
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment