// executable
if stat, err := os.Stat(filename); err != nil {
panic(err)
}
if stat.Mode().Perm() & 0111 == 0000 {
fmt.Printf("%s not executable\n", filename)
}
Last active
August 12, 2023 14:16
-
-
Save chaosmatrix/bc4a3d423273becbda3657102a12c5cd to your computer and use it in GitHub Desktop.
golang tips
Golang Upgrade Version
go get
only check library's version, won't re-compile tools aftergo version
change
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
net.IP
Rules:
- Both IPv4 and IPv6 address store as IPv6 address
To16()
can convert IPv4 to IPv6 (because IPv4 store as IPv6 format)To4()
will check if the IP address is valid IPv4 or not (::ffff:808:808
is valid IPv4)String()
: all valid IPv4 address will be show as IPv4 format (::ffff:808:808
will be show as8.8.8.8
)- 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
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
time.Timer vs time.Ticker
Diff:
- Timer need to Reset every time when it fired
- Ticker auto reset every time when it fired
Warning:
- 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
defer
When:
Rules:
pidfall
equal with