# README
util
import "github.com/KEINOS/go-utiles/util"
Index
- Variables
- func Base58ToUInt(enc string) (uint, error)
- func ChDir(pathDir string) (deferReturn func())
- func ChDirHome() func()
- func ConvBytes2Uint(input []byte) uint
- func ConvUint2Bytes(i uint) []byte
- func CreateTemp(dir string, pattern string) (*os.File, error)
- func DecodeBase58(data string) ([]byte, error)
- func EncodeBase58(input []byte) (string, error)
- func ExitOnErr(err error)
- func FmtStructPretty(val interface{}, prefixes ...string) string
- func GenMask(lenBit int) uint
- func GetMods() []map[string]string
- func GetNameBin() string
- func GetPathDirRepo() string
- func GetTempDir() (pathDir string, cleanup func())
- func HashBLAKE3(input string, lenHash int) (hashed string, err error)
- func HashStruct(input interface{}, lenHash int) (string, error)
- func HereDoc(input string, indents ...string) string
- func IsDir(pathFile string) bool
- func IsFile(pathFile string) bool
- func IsNameFileJSON(name string) bool
- func ParseVersion(version string) (parsed map[string]string, err error)
- func PathExists(path string) bool
- func RandStr(length int) string
- func ReadFile(path string) ([]byte, error)
- func SUM(mask uint, input string) uint
- func UIntToBase58(value uint) (string, error)
- func UniqSliceString(input []string) []string
- func VerifySUM(mask uint, input string, sum uint) bool
- func WriteTmpFile(data string) (pathSaved string, funcCleanUp func(), err error)
Variables
MultibaseBase58BTC is a copy of multibase.Base58BTC to ease mock multibase.Base58BTC for testing.
This library uses MultibaseBase58BTC instead of multibase.Base58BTC, assign a dummy function to mock it's behavior.
var MultibaseBase58BTC multibase.Encoding = multibase.Base58BTC
OsChdir is a copy of os.Chdir to ease mocking during test.
All functions of this package that needs to use os.Chdir uses OsChdir instead. See the example in the test of ChDir for how-to-mock.
var OsChdir = os.Chdir
OsExit is a copy of os.Exit to ease mocking during test.
All functions of this package that needs to use os.Exit uses OsExit instead. See the example of ExitOnError for how-to-mock.
var OsExit = os.Exit
OsGetwd is a copy of os.Getwd to ease mocking during test.
All functions of this package that needs to use os.Getwd uses OsGetwd instead. See the example in the test of ChDir for how-to-mock.
var OsGetwd = os.Getwd
ReadBuildInfo is a copy of debug.ReadBuildInfo to ease mocking during test for GetMods.
This package uses this util.ReadBuildInfo insetead of debug.ReadBuildInfo.
var ReadBuildInfo = debug.ReadBuildInfo
func Base58ToUInt
func Base58ToUInt(enc string) (uint, error)
Base58ToUInt returns the decoded value of enc. The enc value must be Base58 encoded.
This function is basically used for human readable checksum by encoding/decoding the checksum values to Base58 and vice versa.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
const (
encValue = "zz" // Base58 encoded of value 3363
expect = uint(3363) // unsigned expect value
)
// Decode to uint
actual, err := util.Base58ToUInt(encValue)
if err != nil {
log.Fatal(err)
}
if expect == actual {
fmt.Println("it is a valid checksum!")
}
}
Output
it is a valid checksum!
func ChDir
func ChDir(pathDir string) (deferReturn func())
ChDir changes the current working directory to the given path in one-go. It returns a function which moves back to the original directory.
Note: This function exits with status 1 if any error happens.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
"os"
)
func main() {
pathDirToMove := "/tmp"
// Move working directory and defer switch back the diretory
funcReturn := util.ChDir(pathDirToMove)
defer funcReturn()
pathDirCurrent, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fmt.Println(pathDirCurrent)
}
Output
/tmp
func ChDirHome
func ChDirHome() func()
ChDirHome is similar to util.ChDir but it moves the current working directory to the user's home directory in one-go. It returns a function to move back to the original directory.
Note: This function exits with status 1 if any error happens.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
"os"
)
func main() {
// Move to current user home dir and defer moving back to original
funcReturn := util.ChDirHome()
defer funcReturn()
/* Get dir infos to check if the current dir is user's home */
pathDirHome, err := os.UserHomeDir()
if err != nil {
log.Fatal(err)
}
pathDirCurr, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
// Assert
if pathDirCurr == pathDirHome {
fmt.Println("moved to user's home dir")
} else {
log.Fatalf("failed to move dir. Home: %v, Current: %v", pathDirHome, pathDirCurr)
}
}
Output
moved to user's home dir
func ConvBytes2Uint
func ConvBytes2Uint(input []byte) uint
ConvBytes2Uint converts []byte (big endian) to uint.
To convert uint to []byte use ConvUint2Bytes().
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
// Bytes in big endian
input := []byte{0, 0, 0, 0, 0, 0, 48, 57} // = uint64(12345)
resultUint64 := util.ConvBytes2Uint(input)
fmt.Println(resultUint64)
// To convert uint64 to []byte use ConvUint2Bytes().
resultByteSlice := util.ConvUint2Bytes(resultUint64)
fmt.Println(resultByteSlice)
}
Output
12345
[48 57]
func ConvUint2Bytes
func ConvUint2Bytes(i uint) []byte
ConvUint2Bytes converts uint to []byte (big endian).
To conver []byte to uint use ConvBytes2Uint().
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
input := uint(12345) // 0x30 0x39
resultByteSlice := util.ConvUint2Bytes(input)
fmt.Println(resultByteSlice)
fmt.Printf("%#v\n", resultByteSlice)
resultUint64 := util.ConvBytes2Uint(resultByteSlice)
fmt.Println(resultUint64)
}
Output
[48 57]
[]byte{0x30, 0x39}
12345
Example (Negative_value)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
input := -123456789
resultByteSlice := util.ConvUint2Bytes(uint(input)) // note the uint conversion
resultUint64 := util.ConvBytes2Uint(resultByteSlice)
fmt.Println(input)
fmt.Println(int64(resultUint64)) // note the int64
}
Output
-123456789
-123456789
func CreateTemp
func CreateTemp(dir string, pattern string) (*os.File, error)
CreateTemp is similar to os.CreateTemp in Go 1.16+ but for compatibility with Go 1.14 and 1.15.
It creates a new temporary file in the existing directory dir, opens the file for reading and writing, and returns the resulting file.
The filename is generated by taking pattern and adding a random string to the end.
If pattern includes a "*", the random string replaces the last "*". If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by os.TempDir.
Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file. The caller can use the file's Name method to find the pathname of the file. It is the caller's responsibility to remove the file when it is no longer needed.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
"os"
)
func main() {
// Create temp file under temp dir with the name "foo-*.json"
p, err := util.CreateTemp("", "foo-*.json")
if err != nil {
log.Fatalf("%v", err)
}
defer p.Close() // Don't forget to close it
pathSaved := p.Name() // Get the file path
// Do something with the file
if util.IsFile(pathSaved) {
fmt.Println("file exists")
}
// Clean up the temp file
os.Remove(pathSaved)
if !util.IsFile(pathSaved) {
fmt.Println("temp file cleaned")
}
}
Output
file exists
temp file cleaned
func DecodeBase58
func DecodeBase58(data string) ([]byte, error)
DecodeBase58 takes a encoded string of EncodeBase58 and decodes into a bytes buffer.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
input := "abcdefg"
// Encode
encoded, err := util.EncodeBase58([]byte(input))
if err != nil {
log.Fatal(err)
}
fmt.Println("Encoded:", encoded)
// Decode
decoded, err := util.DecodeBase58(encoded)
if err != nil {
log.Fatal(err)
}
fmt.Println("Decoded:", string(decoded))
}
Output
Encoded: 4h3c6xC6Mc
Decoded: abcdefg
func EncodeBase58
func EncodeBase58(input []byte) (string, error)
EncodeBase58 returns the Base58 encoded string using Multibase Base58BTC format without the encode type prefix "z".
The used chars are: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" See: https://en.bitcoin.it/wiki/Base58Check_encoding
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
input := "abcdefg"
result, err := util.EncodeBase58([]byte(input))
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
Output
4h3c6xC6Mc
func ExitOnErr
func ExitOnErr(err error)
ExitOnErr exits with status 1 if err is not nil.
To test this function, mock the OsExit function variable. See ExitOnError_test.go for an example.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"github.com/pkg/errors"
)
func main() {
/*
Example to mock OsExit in ExitOnErr
*/
// Backup and defer restoration
oldOsExit := util.OsExit
defer func() {
util.OsExit = oldOsExit
}()
// Mock OsExit
util.OsExit = func(code int) {
fmt.Println("the exit code was:", code)
}
// Create error
err := errors.New("foo")
util.ExitOnErr(err)
}
Output
the exit code was: 1
func FmtStructPretty
func FmtStructPretty(val interface{}, prefixes ...string) string
FmtStructPretty formats JSON string or an object into pretty-indented JSON-strings.
If a prefix is provided then it will add the prefix to each line.
Example (Json)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
data := struct {
Foo string `json:"foo" mapstructure:"foo"`
}{
Foo: "bar",
}
prettyJSON := util.FmtStructPretty(data)
fmt.Println(prettyJSON)
}
Output
{
"foo": "bar"
}
Example (Slice)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
data := []string{
"foo",
"bar",
}
prettyJSON := util.FmtStructPretty(data)
fmt.Println(prettyJSON)
}
Output
[
"foo",
"bar"
]
func GenMask
func GenMask(lenBit int) uint
GenMask returns a lenBit length value filled with bit 1.
The lenBit should be between 0-64. Any greater number than 64 will be 64.
i := util.GenMask(0) // -> 0b0
i := util.GenMask(1) // -> 0b1
i := util.GenMask(4) // -> 0b1111
i := util.GenMask(8) // -> 0b11111111
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
fmt.Printf("%b\n", util.GenMask(0))
fmt.Printf("%b\n", util.GenMask(1))
fmt.Printf("%b\n", util.GenMask(2))
fmt.Printf("%b\n", util.GenMask(4))
fmt.Printf("%b\n", util.GenMask(11))
fmt.Printf("%b\n", util.GenMask(64))
fmt.Printf("%b\n", util.GenMask(65)) // Max is 64
fmt.Printf("%b\n", util.GenMask(1024)) // Max is 64
}
Output
0
1
11
1111
11111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
func GetMods
func GetMods() []map[string]string
GetMods returns a list of external modules used in the package. The list contains: module name, path and the version.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
listMods := util.GetMods()
for _, modInfo := range listMods {
fmt.Println(modInfo["name"])
fmt.Println(modInfo["path"])
fmt.Println(modInfo["version"])
}
}
Output
a
n/a
n/a
func GetNameBin
func GetNameBin() string
GetNameBin returns the file name of the current executable binary.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
nameBin := util.GetNameBin()
fmt.Println(nameBin)
}
Output
util.test
func GetPathDirRepo
func GetPathDirRepo() string
GetPathDirRepo returns the root directory of the current git repo. If no ".git" directory found then returns "".
It will search up the directory from the current working dir upto the depth level.
func GetTempDir
func GetTempDir() (pathDir string, cleanup func())
GetTempDir returns a temporary directory and the cleanup function for the test to use. It is similar to T.TempDir() but for Go 1.14 compatibility.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
pathDir, cleanup := util.GetTempDir()
defer cleanup()
if util.IsDir(pathDir) {
fmt.Println("directory exists")
}
}
Output
directory exists
func HashBLAKE3
func HashBLAKE3(input string, lenHash int) (hashed string, err error)
HashBLAKE3 returns the hashed value of "input" with length of "lenHash". The lenHash must be in the range between 1-1024.
The hash algorithm is based on BLAKE3 so it is fast but NOT suitable for cryptographic purposes. Only suitable for hashing a small range of values such as IDs or temporary values.
The input will be hashed with BLAKE3 algorithm then encodes it to Base58 (Base58BTC) and returns the first "lenHash" bytes of the results.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
input := "foo"
lenHash := 16
hashed, err := util.HashBLAKE3(input, lenHash)
if err != nil {
// Do something with the error
log.Fatalf("failed to hash: %v", err)
}
fmt.Println("Hashed value:", hashed)
fmt.Println("Length:", len(hashed))
}
Output
Hashed value: 7STCqaLBnDB6EKXi
Length: 16
func HashStruct
func HashStruct(input interface{}, lenHash int) (string, error)
HashStruct returns the hash value of the input struct with the given length.
Note that the hash value is only for change detection purposes and NOT to detect falsification.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
data := struct {
Foo string
Bar int
}{
Foo: "hoge fuga",
Bar: 1,
}
hash1, err := util.HashStruct(data, 16) // 16 char length
if err != nil {
log.Fatalf("hash error: %v", err)
}
fmt.Println("Hash value before change:", hash1)
data.Bar = 2 // Change value
hash2, err := util.HashStruct(data, 16) // 16 char length
if err != nil {
log.Fatalf("hash error: %v", err)
}
fmt.Println("Hash value after change :", hash2)
}
Output
Hash value before change: 4KcWDdX1qXnGBV4U
Hash value after change : 6aESjhTWhk3Tv91h
func HereDoc
func HereDoc(input string, indents ...string) string
HereDoc returns an un-indented string such as here-document-like format. Useful for help messages to print.
If indents were given it will use as a prefix of each line.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
msg := util.HereDoc(`
Here Title
Here description
`)
fmt.Println(msg)
}
Output
Here Title
Here description
Example (Optional_indentation)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
input := `
Here Title
Here description
`
indent := "> " // prefix of each line
fmt.Println(util.HereDoc(input, indent))
}
Output
> Here Title
> Here description
>
func IsDir
func IsDir(pathFile string) bool
IsDir returns true if pathFile is an existing directory and not a file.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
// Existing dir
if util.IsDir("../testdata/sample_data") {
fmt.Println("is dir")
}
// Not existing dir
if !util.IsDir("./foobar") {
fmt.Println("not a dir")
}
// File exists but not a dir
if !util.IsDir("./IsDir_test.go") {
fmt.Println("not a dir")
}
}
Output
is dir
not a dir
not a dir
func IsFile
func IsFile(pathFile string) bool
IsFile returns true if file exists in the given path.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
fmt.Println(util.IsFile("./IsFile_test.go"))
fmt.Println(util.IsFile("./non-existing-file.txt"))
fmt.Println(util.IsFile("../util")) // Existing but is a dir
}
Output
true
false
false
func IsNameFileJSON
func IsNameFileJSON(name string) bool
IsNameFileJSON returns true if name is a file path and ends with ".json".
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
if target := "/foo/bar/buz.json"; util.IsNameFileJSON(target) {
fmt.Println(target, "is a JSON file")
}
}
Output
/foo/bar/buz.json is a JSON file
func ParseVersion
func ParseVersion(version string) (parsed map[string]string, err error)
ParseVersion parses a version string into a mapped data.
It is similar to go's semver package, but it includes a build string as well. This function is compatible with git-tagged versions.
ParseVersion("v1.2.3-alpha-abcde123")
// => map[string]string{
// "major": "1",
// "minor": "2",
// "patch": "3",
// "prerelease": "alpha",
// "build": "abcde123",
// }, nil
func PathExists
func PathExists(path string) bool
PathExists returns true if the path is an existing file or dir.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
fmt.Println(util.PathExists("./PathExists_test.go"))
fmt.Println(util.PathExists("../util"))
fmt.Println(util.PathExists("./non-existing"))
}
Output
true
true
false
func RandStr
func RandStr(length int) string
RandStr returns a random unique string with the given length. The length range must be between 1-1024. Otherwise it will os.Exit with status 1.
Note that, it is a pseudo-random string generator and unsuitable for security-sensitive work.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
length := 16
for i := 0; i < 1000; i++ {
h1 := util.RandStr(length)
h2 := util.RandStr(length)
if h1 == h2 {
log.Fatalf("the result did collide\nh1: %v\nh2: %v\n", h1, h2)
}
}
fmt.Println("ok")
}
Output
ok
func ReadFile
func ReadFile(path string) ([]byte, error)
ReadFile is similar to os.ReadFile inf Go v1.16+. Aim to use for Go v1.14 and 1.15 compatibility.
func SUM
func SUM(mask uint, input string) uint
SUM returns the checksum of the input based on 2's complement of the sum with max length of the mask.
The returned sum will be between 1 - mask. For example if the mask is 255, then the checksum will be between 1-255.
To verify the checksum with the input, use VerifySUM() function.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
input := "foo bar"
sum8 := uint(0b11111111) // 8bit mask = 255 = checksum between 1-255
checksum := util.SUM(sum8, input)
fmt.Printf("%d (0x%x, %T)\n", checksum, checksum, checksum)
}
Output
156 (0x9c, uint)
Example (More_accurate)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
const (
input = "foo bar"
sumBase58 = uint(3363) // 3363 is the max number of 2 digit Base58 = "zz"
)
// Create checksum
checksum := util.SUM(sumBase58, input)
fmt.Printf("Checksum: %v (0x%x, 0b%b, %T)\n", checksum, checksum, checksum, checksum)
// Encode to Base58
enc, err := util.UIntToBase58(checksum)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Base58 encoded: %v (%T)\n", enc, enc)
}
Output
Checksum: 666 (0x29a, 0b1010011010, uint)
Base58 encoded: CV (string)
Example (With_verify)
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
input := util.RandStr(1024) // 1024 char length random string
sum8 := uint(255) // checksum for max 8bit = 0b11111111 = 0d255
checksum := util.SUM(sum8, input)
// Verify
if util.VerifySUM(sum8, input, checksum) {
fmt.Print("verify success! checksum of the input is valid")
}
}
Output
verify success! checksum of the input is valid
func UIntToBase58
func UIntToBase58(value uint) (string, error)
UIntToBase58 returns Base58(BTC) encoded string of the given uint value. Note that this function returns in 2 digit minimum. Such as 0d0 -> "11".
This function is basically used for human readable checksum by encoding/decoding the checksum values to Base58 and vice versa.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
// In base58(BTC), zero becomes "1". See EncodeBase58().
inputZero := uint(0)
if encZero, err := util.UIntToBase58(inputZero); err != nil {
log.Fatal(err)
} else {
fmt.Println(encZero) // note that the result is in 2 digit -> "11"
}
inputTen := uint(10)
if encTen, err := util.UIntToBase58(inputTen); err != nil {
log.Fatal(err)
} else {
fmt.Println(encTen)
}
inputHuge := uint(123456789)
if encHuge, err := util.UIntToBase58(inputHuge); err != nil {
log.Fatal(err)
} else {
fmt.Println(encHuge)
}
}
Output
11
1B
BukQL
Example (More_accurate)
This function is used when you need a more accurate checksum in 2 digit string.
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
input := uint(3363) // 3363 is the max value of 2 digit Base58 "zz"
// Encode the checksum to Base58 as a string
enc, err := util.UIntToBase58(input)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Encoded checksum: %v (%T)", enc, enc)
}
Output
Encoded checksum: zz (string)
func UniqSliceString
func UniqSliceString(input []string) []string
UniqSliceString removes duplicate values of a given slice and returns a slice with unique values. The order remains the same as the original.
Issue: https://qiitadon.com/web/statuses/106158855888548864 Ref: https://qiitadon.com/web/statuses/106158948168528024
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
data := []string{
"one",
"one",
"two",
"two",
"three",
"three",
}
fmt.Println(util.UniqSliceString(data))
}
Output
[one two three]
func VerifySUM
func VerifySUM(mask uint, input string, sum uint) bool
VerifySUM returns true if the sum is a valid checksum of the input with the given mask. The sum value should be created via SUM() function with the same mask value.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
)
func main() {
const (
input = "abcdefghijk" // target data
bitLen = uint(0b11111111) // 0b11111111 = 255
)
// Create checksum between 1-255
checksum := util.SUM(bitLen, input)
fmt.Printf("Checksum is: %v (0b%b)\n", checksum, checksum)
// Verify
if util.VerifySUM(bitLen, input, checksum) {
fmt.Println("Check result: ok")
} else {
fmt.Println("Check result: ng")
}
}
Output
Checksum is: 103 (0b1100111)
Check result: ok
func WriteTmpFile
func WriteTmpFile(data string) (pathSaved string, funcCleanUp func(), err error)
WriteTmpFile saves the string of data to a temp file. It returns the saved path and a function to delete that temp file.
Example
package main
import (
"fmt"
"github.com/KEINOS/go-utiles/util"
"log"
)
func main() {
data := "foo bar"
pathFile, deferCleanUp, err := util.WriteTmpFile(data)
if err != nil {
log.Fatal(err)
}
defer deferCleanUp()
read, err := util.ReadFile(pathFile)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(read))
}
Output
foo bar
Generated by gomarkdoc