Day04
作业1 我有一个梦想字母统计
// 我有一个梦想 中出现次数最多的top 10 字符集出现次数
package main
import (
"fmt"
"sort"
)
func main() {
article := `abcdabcdabadDDDDDDDEDDDDDDDDDDcadbcABCDEFGBCDECDEDEEefghijelmnopqrsqweasdzxcxzcdffesrvsdhhdrofmflpcodDSFOEFSIOHFISOKOJXIO`
start := map[rune]int{}
for _, ch := range article {
if ch > 'a' && ch < 'z' || ch > 'A' && ch < 'Z' {
start[ch]++
}
}
// fmt.Println(start)
startSlice := make([][]int, 0, len(start))
for ch, cnt := range start {
// fmt.Printf("%c:%d\n", ch, cnt)
startSlice = append(startSlice, []int{int(ch), cnt})
}
// fmt.Println(startSlice)
sort.Slice(startSlice, func(i, j int) bool { return startSlice[i][1] > startSlice[j][1] })
// fmt.Println(startSlice)
// fmt.Println(startSlice[:10])
for index, value := range startSlice[:10] {
fmt.Printf("%d %c %d\n", index+1, value[0], value[1])
}
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312>go run hw01.go
1 D 22
2 d 9
3 E 7
4 c 7
5 f 5
6 O 5
7 s 4
8 F 4
9 e 4
10 b 4
*/
作业2 统计ip 状态码 流量等
3 统计
a 每个IP出现次数
b 每个状态码出现次数
c 每个IP在每个URL上产生的流量
int[][4]string{
// ip url 状态码 字节大小
{"1.1.1.1","/index.html","200","1000"},
{"1.1.1.2","/index.html","200","10000"},
{"1.1.1.1","/index.html","200","10000"}
}
key:map 必须是可以使用==进行比较的数据类型
key 数据类型,ip+url =>string key
[]string{ip,url}
[2]string{ip,url}
package main
import (
"fmt"
"strconv"
)
func main() {
lines := [][4]string{
{"1.1.1.1", "/index.html", "200", "1000"},
{"1.1.1.2", "/index.html", "400", "10000"},
{"1.1.1.1", "/index.html", "200", "10000"},
}
ip := map[string]int{}
status := map[int]int{}
traffic := map[[2]string]int{}
for _, line := range lines {
ip[line[0]]++
code, _ := strconv.Atoi(line[2])
status[code]++
key := [2]string{line[0], line[1]}
tr, _ := strconv.Atoi(line[3])
traffic[key] += tr
}
fmt.Println(ip)
fmt.Println(status)
fmt.Println(traffic)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312>go run hw02.go
map[1.1.1.1:2 1.1.1.2:1]
map[200:2 400:1]
map[[1.1.1.1 /index.html]:11000 [1.1.1.2 /index.html]:10000]
*/
作业3 todolist
4 todo管理
a 编辑
请输入编辑的ID
通过ID查找=>Task =>显示
用户确认是否进行编辑(y/yes):编辑
用户输入:任务名称,开始时间,状态
//状态如果是已完成,初始化完成时间
//time.Now().Format("2006-01-02 15:04:05")
b删除
请输入编辑的ID
通过ID查找 =>Task =>显示
用户确认是否进行删除(y/yes):删除
c数据验证(用户输入数据检查)
任务名称:不能重复(新增,编辑)
编辑:
a,任务名称不变
b. 任务名称改成其他已存在的
任务状态:
新创建,开始执行,已完成,暂停
包管理
导入本地包
package models
// 包外可见
var Name = "test"
// D:\GoWork\src\go_course\day04-20230312\todolist\models\task.go
package main
import (
"fmt"
"todolist/models"
)
func main() {
fmt.Println(models.Name)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\todolist>go run main.go
test
*/
重复,使用别名
同一个文件夹向下package 包名 要一致
文件1
package task
// 包外可见
var Name = "test"
// D:\GoWork\src\go_course\day04-20230312\todolist\models\task\task.go
文件2
package task
var Name = "Controller Task"
// D:\GoWork\src\go_course\day04-20230312\todolist\controllers\task\task.go
文件3
import (
"fmt"
"todolist/controllers/task"
mtask "todolist/models/task"
)
func main() {
fmt.Println(mtask.Name)
fmt.Println(task.Name)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\todolist>go run main.go
test
Controller Task
*/
点导入
package main
import (
"fmt"
. "todolist/controllers/task"
mtask "todolist/models/task"
)
func main() {
fmt.Println(mtask.Name)
fmt.Println(Name)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\todolist>go run main.go
test
Controller Task
*/
init初始化
文件1
package task
// 包外可见
var Name = "test"
// D:\GoWork\src\go_course\day04-20230312\todolist\models\task\task.go
文件2
package task
import "fmt"
var Name = "Controller Task"
var Version string //需要在运行启动之前进行初始化
func Call() {
fmt.Println("Controller Call")
}
//包在使用的时候自动对数据进行初始化
func init() {
Version = "Controller v1.0"
fmt.Println("Controller init")
}
// D:\GoWork\src\go_course\day04-20230312\todolist\controllers\task\task.go
文件3
package main
import (
"fmt"
"todolist/controllers/task"
mtask "todolist/models/task"
// 1 导入 mod init name + 目录结构
// 2 包名与所在目录名称保持一致
// 3 调用时用包名 .VAR(包名不是文件名)
)
func main() {
fmt.Println(mtask.Name)
fmt.Println(task.Name)
task.Call()
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\todolist>go run main.go
Controller init
test
Controller Task
Controller Call
*/
属性
修改文件2
version包外不可见,使用GetVersion对外提供只读
package task
import "fmt"
var Name = "Controller Task"
var Version string //需要在运行启动之前进行初始化
// 属性
// 包外可见
// 包外是否可以修改 => 需要在包外不能修改值
var version string
// 提供对外修改的函数(读,不可写)
func GetVersion() string {
return version
}
func printVersion() {
fmt.Println("print version call")
}
func Call() {
fmt.Println("Controller Call")
}
//包在使用的时候自动对数据进行初始化
func init() {
Version = "Controller v1.0"
fmt.Println("Controller init")
}
自己创建一个包,供导入
package strutil
func RandString() string {
return "kk"
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\strutil\rand.go
//配置秘钥
D:\GoWork\src\go_course\day04-20230312\strutil>go mod init github.com/xxx/strutil
eval $(ssh-agent -s)
ssh-add ~/.ssh/github
//使用git上传代码
git init
git add .
git commit -sv
git remote add origin git@github.com:xxx/strutil.git
git push origin master
//使用
import "github.com/xxx/strutil"
fmt.Println(strutil.RandString())
*/
导入外部包
package main
import (
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
//D:\GoWork\src\go_course\day04-20230312\web\main.go
列出所有包
D:\GoWork\src\go_course\day04-20230312\web>go list -m all
//指定json格式
D:\GoWork\src\go_course\day04-20230312\web>go list -m -json all
// go mod graph 和go list -m all 类似
D:\GoWork\src\go_course\day04-20230312\\web>go mod graph
// 老版本替换
D:\GoWork\src\go_course\day04-20230312\web>
go mod edit --replace=golang.org/x/crypto@v1.0.0=github.com/golang/crypto@latest
//go.mod会生成如下replace语句: 请求golang.org回去github.com中找
replace golang.org/x/crypto v1.0.0 => github.com/golang/crypto latest
标准包
go list std
D:\GoWork\src\go_course\day04-20230312\web>go list std
查看 go doc
D:\GoWork\src\go_course\day04-20230312\web>go doc time.Now
package time // import "time"
func Now() Time
Now returns the current local time.
os包
package main
import (
"fmt"
"os"
)
func main() {
fmt.Printf("%#v\n", os.Args)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testcmd>go mod init testcmd
go: creating new go.mod: module testcmd
go: to add module requirements and sums:
go mod tidy
D:\GoWork\src\go_course\day04-20230312\testcmd>go mod tidy
D:\GoWork\src\go_course\day04-20230312\testcmd>go build
D:\GoWork\src\go_course\day04-20230312\testcmd>testcmd.exe
[]string{"testcmd.exe"}
D:\GoWork\src\go_course\day04-20230312\testcmd>testcmd.exe a b c d e f
[]string{"testcmd.exe", "a", "b", "c", "d", "e", "f"}
*/
flag
package main
import (
"flag"
"fmt"
)
//命令行中的参数进行解析=>指定的命令参数->变量
func main() {
var (
host string
port int
h bool
help bool
)
// -h host -P port
//解析变量的指针,命令行中指定的参数名,默认值,帮助
flag.StringVar(&host, "H", "127.0.0.1", "连接地址")
flag.IntVar(&port, "P", 22, "连接端口")
flag.BoolVar(&h, "h", false, "帮助")
flag.BoolVar(&help, "help", false, "帮助")
flag.Usage = func() {
fmt.Println("usage:testflag [-H 127.0.0.1] [-P 22]")
flag.PrintDefaults()
}
flag.Parse()
fmt.Println(host, port, h, help)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testflag>go mod init testflag
go: creating new go.mod: module testflag
go: to add module requirements and sums:
go mod tidy
D:\GoWork\src\go_course\day04-20230312\testflag>go mod tidy
D:\GoWork\src\go_course\day04-20230312\testflag>go build
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe
127.0.0.1 22 false false
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -h
127.0.0.1 22 true false
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe --help
127.0.0.1 22 false true
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -help
127.0.0.1 22 false true
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -help -P 33 -H 1.1.1.1
1.1.1.1 33 false true
*/
修改,调用flag.Usage()
package main
import (
"flag"
"fmt"
)
//命令行中的参数进行解析=>指定的命令参数->变量
func main() {
var (
host string
port int
h bool
help bool
)
// -h host -P port
//解析变量的指针,命令行中指定的参数名,默认值,帮助
flag.StringVar(&host, "H", "127.0.0.1", "连接地址")
flag.IntVar(&port, "P", 22, "连接端口")
flag.BoolVar(&h, "h", false, "帮助")
flag.BoolVar(&help, "help", false, "帮助")
flag.Usage = func() {
fmt.Println("usage:testflag [-H 127.0.0.1] [-P 22]")
flag.PrintDefaults()
}
flag.Parse()
fmt.Println(host, port, h, help)
if h || help {
flag.Usage()
//os.Exit(0) //不要在协程使用
return
}
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testflag>go build
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -P 33 -H 1.1.1.1
1.1.1.1 33 false false
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -help
127.0.0.1 22 false true
usage:testflag [-H 127.0.0.1] [-P 22]
-H string
连接地址 (default "127.0.0.1")
-P int
连接端口 (default 22)
-h 帮助
-help
帮助
*/
flag.NArg()参数个数
flag.Args()切片
package main
import (
"flag"
"fmt"
)
//命令行中的参数进行解析=>指定的命令参数->变量
func main() {
var (
host string
port int
h bool
help bool
)
// -h host -P port
//解析变量的指针,命令行中指定的参数名,默认值,帮助
flag.StringVar(&host, "H", "127.0.0.1", "连接地址")
flag.IntVar(&port, "P", 22, "连接端口")
flag.BoolVar(&h, "h", false, "帮助")
flag.BoolVar(&help, "help", false, "帮助")
flag.Usage = func() {
fmt.Println("usage:testflag [-H 127.0.0.1] [-P 22]")
flag.PrintDefaults()
}
flag.Parse()
fmt.Println(host, port, h, help)
if h || help {
flag.Usage()
//os.Exit(0) //不要在协程使用
return
}
fmt.Println(flag.NArg())
fmt.Println(flag.Args())
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe -P 33 -H 1.1.1.1 a b c
1.1.1.1 33 false false
3
[a b c]
D:\GoWork\src\go_course\day04-20230312\testflag>testflag.exe x a b
127.0.0.1 22 false false
3
[x a b]
*/
修改为指针
package main
import (
"flag"
"fmt"
)
// 命令行中的参数进行解析=>指定的命令参数->变量
func main() {
// -h host -P port
//解析变量的指针,命令行中指定的参数名,默认值,帮助
host := flag.String("H", "127.0.0.1", "连接地址")
port := flag.Int("P", 22, "连接端口")
h := flag.Bool("h", false, "帮助")
help := flag.Bool("help", false, "帮助")
flag.Usage = func() {
fmt.Println("usage:testflag [-H 127.0.0.1] [-P 22]")
flag.PrintDefaults()
}
flag.Parse()
fmt.Printf("%T,%T,%T,%T\n", host, port, h, help)
if *h || *help {
flag.Usage()
//os.Exit(0) //不要在协程使用
return
}
fmt.Println(*host, *port, *h, *help)
fmt.Println(flag.NArg())
fmt.Println(flag.Args())
}
/*打印结果
PS D:\GoWork\src\go_course\day04-20230312\testflag> go build
PS D:\GoWork\src\go_course\day04-20230312\testflag> ./testflag.exe -P 33 -H 1.1.1.1 a b c
*string,*int,*bool,*bool
1.1.1.1 33 false false
3
[a b c]
PS D:\GoWork\src\go_course\day04-20230312\testflag> ./testflag.exe x a b
*string,*int,*bool,*bool
127.0.0.1 22 false false
3
[x a b]
*/
cobra 参考
https://blog.csdn.net/inthat/article/details/123527784
记录日志
package main
import "log"
func main() {
//设置格式
// flags
// log.SetFlags(log.Flags() | log.Ldate | log.Lshortfile)
// log.SetFlags(log.Flags() | log.Lshortfile)
log.SetFlags(log.Flags())
// prefix
log.SetPrefix("main:")
log.Println("我是第一条日志")
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testlog>go run main.go
main:2023/03/15 21:55:29 main.go:14: 我是第一条日志
// 默认有log.Ldate时间,默认没有文件名
D:\GoWork\src\go_course\day04-20230312\testlog>go run main.go
main:2023/03/15 21:57:13 我是第一条日志
*/
Fatal日志
fatal执行后,直接退出了
package main
import "log"
func main() {
//设置格式
// flags
// log.SetFlags(log.Flags() | log.Ldate | log.Lshortfile)
log.SetFlags(log.Flags() | log.Lshortfile)
// prefix
log.SetPrefix("main:")
log.Println("我是第一条日志")
log.Fatal("我是一个Fatal日志")
log.Println("我是第二条Println日志")
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testlog>go run main.go
main:2023/03/15 22:42:31 main.go:13: 我是第一条日志
main:2023/03/15 22:42:31 main.go:14: 我是一个Fatal日志
exit status 1
*/
Panic日志
panic日志,抛出错误
package main
import "log"
func main() {
//设置格式
// flags
// log.SetFlags(log.Flags() | log.Ldate | log.Lshortfile)
log.SetFlags(log.Flags() | log.Lshortfile)
// prefix
log.SetPrefix("main:")
log.Println("我是第一条日志")
// log.Fatal("我是一个Fatal日志")
log.Panicln("我是一条panic日志")
log.Println("我是第二条Println日志")
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testlog>go run main.go
main:2023/03/15 22:45:12 main.go:13: 我是第一条日志
main:2023/03/15 22:45:12 main.go:15: 我是一条panic日志
panic: 我是一条panic日志
goroutine 1 [running]:
log.Panicln({0xc0000cdf60, 0x85c9dd, 0x7c6e65})
C:/Program Files/Go/src/log/log.go:368 +0x65
main.main()
D:/GoWork/src/go_course/day04-20230312/testlog/main.go:15 +0xb5
exit status 2
*/
定义多个日志格式
package main
import (
"log"
"os"
)
func main() {
//设置格式
// flags
// log.SetFlags(log.Flags() | log.Ldate | log.Lshortfile)
log.SetFlags(log.Flags() | log.Lshortfile)
// prefix
log.SetPrefix("main:")
log.Println("我是第一条日志")
// log.Fatal("我是一个Fatal日志")
// log.Panicln("我是一条panic日志")
log.Println("我是第二条Println日志")
//DEBUG INFO WARNING ERROR
//logrus
logger := log.New(os.Stdout, "logger:", log.Flags())
logger2 := log.New(os.Stdout, "logger2:", log.Flags())
logger.Println("我是logger日志")
logger2.Println("我是logger2日志")
//标准输入/输出 fmt.Scan fmt.Println
//os.Stdin os.Stdout os.Stderr
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testlog>go run main.go
main:2023/03/15 22:53:27 main.go:16: 我是第一条日志
main:2023/03/15 22:53:27 main.go:19: 我是第二条Println日志
logger:2023/03/15 22:53:27 main.go:25: 我是logger日志
logger2:2023/03/15 22:53:27 main.go:26: 我是logger2日志
*/
时间包
时间戳
package main
import (
"fmt"
"time"
)
func main() {
//1时间
now := time.Now()
fmt.Printf("%T,%#v\n", now, now)
fmt.Println(now.Date())
fmt.Println(now.Year())
fmt.Println(now.Month())
fmt.Println(now.Day())
fmt.Println(now.Hour())
fmt.Println(now.Minute())
fmt.Println(now.Second())
//unix时间戳
fmt.Println(now.Unix())
fmt.Println(now.UnixNano())
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testtime>go run main.go
time.Time,time.Date(2023, time.March, 15, 23, 30, 1, 366743300, time.Local)
2023 March 15
2023
March
15
23
30
1
1678894201
1678894201366743300
*/
时间字符串
package main
import (
"fmt"
"time"
)
func main() {
//1时间
now := time.Now()
//=> 字符串 2023-03-15 20:00:xx?
//Printf 格式化字符串 占位符
//2006 4位数字的年
//01 2位数字的月
//02 2位数字的天
//03 12进制的小时
//15 24进制的小时
//04 2位数字的分钟
//05 2位数字的秒
fmt.Println(now.Format("2006-01-02 03:04:05"))
fmt.Println(now.Format("2006年01月02日 03:04:05"))
fmt.Println(now.Format("2006年01月02日 15:04:05"))
fmt.Println(now.Format("15:04:05 2006年01月02日"))
fmt.Println(now.Format("15:04:05 02/01/2006"))
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testtime>go run main.go
2023-03-15 11:38:08
2023年03月15日 11:38:08
2023年03月15日 23:38:08
23:38:08 2023年03月15日
23:38:08 15/03/2023
*/
生成时间
package main
import (
"fmt"
"time"
)
func main() {
//生成时间
year, month, day := 1990, time.March, 1
time1990 := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
fmt.Println(time1990.Format("2006-01-02 15:04:05"))
//unixtime
startTime := time.Unix(0, 0)
fmt.Println(startTime.Format("2006-01-02 15:04:05"))
//字符串
cTime, err := time.Parse("2006-01-02", "2001-12-01")
fmt.Println(cTime.Format("2006-01-02 15:04:05"), err)
cTime, err = time.Parse("2006/01/02", "2001/12/01")
fmt.Println(cTime.Format("2006-01-02 15:04:05"), err)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testtime>go run main.go
1990-03-01 00:00:00
1970-01-01 08:00:00
2001-12-01 00:00:00 <nil>
2001-12-01 00:00:00 <nil>
*/
时间区间
package main
import (
"fmt"
"time"
)
func main() {
//字符串
cTime, err := time.Parse("2006-01-02", "2001-12-01")
fmt.Println(cTime.Format("2006-01-02 15:04:05"), err)
//时间区间
//生成时间区间
// now - time
dura := time.Since(cTime)
fmt.Printf("%T,%#v\n", dura, dura)
fmt.Println(dura)
// time - now
dura02 := time.Until(cTime)
fmt.Println(dura02)
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testtime>go run main.go
1990-03-01 00:00:00
1970-01-01 08:00:00
2001-12-01 00:00:00 <nil>
time.Duration,671731385503438700
186592h3m5.5034387s
-186592h3m5.5040161s
*/
time.ParseDuration
package main
import (
"fmt"
"time"
)
func main() {
// //1时间
now := time.Now()
//字符串
cTime, err := time.Parse("2006-01-02", "2001-12-01")
fmt.Println(cTime.Format("2006-01-02 15:04:05"), err)
//时间区间
//生成时间区间
// now - time
dura := time.Since(cTime)
fmt.Printf("%T,%#v\n", dura, dura)
fmt.Println(dura)
// time - now
dura02 := time.Until(cTime)
fmt.Println(dura02)
dura03, err := time.ParseDuration("1h1m1s")
fmt.Println(dura03, err)
fmt.Println(dura03.Hours())
fmt.Println(dura03.Minutes())
fmt.Println(dura03.Seconds())
dura03, err = time.ParseDuration("1m")
fmt.Println(dura03, err)
// dayInterval, _ := time.ParseDuration("24h")
dayInterval, _ := time.ParseDuration("-24h1m")
fmt.Println(now.Add(dayInterval))
}
/*打印结果
D:\GoWork\src\go_course\day04-20230312\testtime>go run main.go
2001-12-01 00:00:00 <nil>
time.Duration,671731985238049500
186592h13m5.2380495s
-186592h13m5.2385713s
1h1m1s <nil>
1.0169444444444444
61.016666666666666
3661
1m0s <nil>
2023-03-15 00:12:05.2374956 +0800 CST m=-86459.993930399
*/
判断时间
package main
import (
"fmt"
"time"
)
func main() {
// //1时间
now := time.Now()
//字符串
cTime, err := time.Parse("2006-01-02", "2001-12-01")
fmt.Println(cTime.Format("2006-01-02 15:04:05"), err)
//时间区间
//生成时间区间
// now - time
dura := time.Since(cTime)
fmt.Printf("%T,%#v\n", dura, dura)
fmt.Println(dura)
// time - now
dura02 := time.Until(cTime)
fmt.Println(dura02)
dura03, err := time.ParseDuration("1h1m1s")
fmt.Println(dura03, err)
fmt.Println(dura03.Hours())
fmt.Println(dura03.Minutes())
fmt.Println(dura03.Seconds())
dura03, err = time.ParseDuration("1m")
fmt.Println(dura03, err)
// dayInterval, _ := time.ParseDuration("24h")
dayInterval, _ := time.ParseDuration("-24h1m")
fmt.Println(now.Add(dayInterval))
//判断时间
// a>b a<b
yesterday := now.Add(dayInterval)
fmt.Println(yesterday.After(now))
fmt.Println(yesterday.Before(now))
fmt.Println(yesterday.Sub(now))
}
/**打印结果
S D:\GoWork\src\go_course\day04-20230312\testtime> go run .\main.go
2001-12-01 00:00:00 <nil>
time.Duration,672326858988808200
186757h27m38.9888082s
-186757h27m38.9894169s
1h1m1s <nil>
1.0169444444444444
61.016666666666666
3661
1m0s <nil>
2023-03-21 21:26:38.9888082 +0800 CST m=-86459.998134499
false
true
-24h1m0s
*/
时间常量
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(time.Second * 3)
fmt.Println(time.Now())
}
/**打印结果
PS D:\GoWork\src\go_course\day04-20230312\testtime> go run .\main.go
2023-03-22 21:30:36.1898018 +0800 CST m=+3.011667801
*/
编码base64
StdEncoding编码
package main
import (
"encoding/base64"
"fmt"
)
func main() {
//base64
//通常说的base64 0-9a-zA-Z+/ 64
fmt.Println(base64.StdEncoding.EncodeToString([]byte("abcdef")))
fmt.Println(base64.StdEncoding.EncodeToString([]byte("abcde")))
//在URL中+/特殊字符,base64url (-_替换)
// 非对齐 3的整数倍 =补齐
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testbase64> go run .\main.go
YWJjZGVm
YWJjZGU=
*/
StdEncoding解码
package main
import (
"encoding/base64"
"fmt"
)
func main() {
fmt.Println(base64.StdEncoding.EncodeToString([]byte("我是tt")))
fmt.Println(base64.StdEncoding.DecodeString("5oiR5pivdHQ="))
txt, _ := base64.StdEncoding.DecodeString("5oiR5pivdHQ=")
fmt.Println(string(txt))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testbase64> go run .\main.go
5oiR5pivdHQ=
[230 136 145 230 152 175 116 116] <nil>
我是tt
*/
URLEncoding编码&解码
package main
import (
"encoding/base64"
"fmt"
)
func main() {
fmt.Println(base64.StdEncoding.EncodeToString([]byte("我是tt")))
fmt.Println(base64.StdEncoding.DecodeString("5oiR5pivdHQ="))
txt, _ := base64.StdEncoding.DecodeString("5oiR5pivdHQ=")
fmt.Println(string(txt))
//在URL中+/特殊字符,base64url(-_)替换
fmt.Println(base64.URLEncoding.EncodeToString([]byte("我发动机开始了解开了是tt")))
txt, _ = base64.URLEncoding.DecodeString("5oiR5Y-R5Yqo5py65byA5aeL5LqG6Kej5byA5LqG5pivdHQ=")
fmt.Println(string(txt))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testbase64> go run .\main.go
5oiR5pivdHQ=
[230 136 145 230 152 175 116 116] <nil>
我是tt
*/
RawStdEncoding&RawURLEncoding非对齐
不使用=补全
package main
import (
"encoding/base64"
"fmt"
)
func main() {
fmt.Println(base64.StdEncoding.EncodeToString([]byte("我是tt")))
fmt.Println(base64.StdEncoding.DecodeString("5oiR5pivdHQ="))
txt, _ := base64.StdEncoding.DecodeString("5oiR5pivdHQ=")
fmt.Println(string(txt))
//在URL中+/特殊字符,base64url(-_)替换
fmt.Println(base64.URLEncoding.EncodeToString([]byte("我发动机开始了解开了是tt")))
txt, _ = base64.URLEncoding.DecodeString("5oiR5Y-R5Yqo5py65byA5aeL5LqG6Kej5byA5LqG5pivdHQ=")
fmt.Println(string(txt))
//非对齐
fmt.Println(base64.RawStdEncoding.EncodeToString([]byte("我发动机开始了解开了是tt")))
fmt.Println(base64.RawURLEncoding.EncodeToString([]byte("我发动机开始了解开了是tt")))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testbase64> go run .\main.go
5oiR5pivdHQ=
[230 136 145 230 152 175 116 116] <nil>
我是tt
5oiR5Y-R5Yqo5py65byA5aeL5LqG6Kej5byA5LqG5pivdHQ=
我发动机开始了解开了是tt
5oiR5Y+R5Yqo5py65byA5aeL5LqG6Kej5byA5LqG5pivdHQ
5oiR5Y-R5Yqo5py65byA5aeL5LqG6Kej5byA5LqG5pivdHQ
*/
hex
package main
import (
"encoding/hex"
"fmt"
)
func main() {
//hex 不区分大小写 %X %x
fmt.Printf("%X\n", []byte("啦啦啦啦啦"))
fmt.Println(hex.EncodeToString([]byte("啦啦啦啦啦")))
txt, _ := hex.DecodeString("E595A6E595A6E595A6E595A6E595A6")
fmt.Println(string(txt))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhex> go run .\main.go
E595A6E595A6E595A6E595A6E595A6
e595a6e595a6e595a6e595a6e595a6
啦啦啦啦啦
*/
hash
md5 hash => 不可逆
string (n:1) -> md5
md5 =>string
彩虹表(暴力破解)MD5表 => string
A => md5密码iamtt =>abcdef
B => md5密码iamtt =>abcdef
某一天A被脱库了 abcdef==> iamtt
加盐
md5(imtt+随机字符)=> defg
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
)
func main() {
//hash算法 => 签名 (不可逆)
// MD5 sha1 sha256 sha512
fmt.Printf("%x\n", md5.Sum([]byte("我是tt")))
//返回字符数和错误信息
fmt.Println(fmt.Printf("%x\n", md5.Sum([]byte("我是tt"))))
//分两次传入
hasher := md5.New()
hasher.Write([]byte("我是"))
hasher.Write([]byte("tt"))
fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhash> go run .\main.go
ff665a79fe7bf3dfa112d4966196e99b
ff665a79fe7bf3dfa112d4966196e99b
33 <nil>
ff665a79fe7bf3dfa112d4966196e99b
*/
生成随机数(randString)
两种方式生成切片,rt1指定容量,用append添加,rt2指定长度,使用索引赋值
package main
import (
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().Unix())
}
func randString(n int) (string, string) {
rt1 := make([]byte, 0, n)
rt2 := make([]byte, n, n)
//定义取值范围切片
chars := []byte{'a', 'b', 'c', 'd', 'e'}
//循环n次,每次生成随机数(切片范围内),获取对应的字符
for i := 0; i < n; i++ {
rt1 = append(rt1, chars[rand.Intn(len(chars))])
rt2[i] = chars[rand.Intn(len(chars))]
}
return string(rt1), string(rt2)
}
func main() {
salt1, salt2 := randString(6)
fmt.Println(salt1, salt2)
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhash> go run .\main.go
adaaed ceebab
*/
md5string
package main
import (
"crypto/md5"
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().Unix())
}
func randString(n int) (string, string) {
rt1 := make([]byte, 0, n)
rt2 := make([]byte, n, n)
//定义取值范围切片
chars := []byte{'a', 'b', 'c', 'd', 'e'}
//循环n次,每次生成随机数(切片范围内),获取对应的字符
for i := 0; i < n; i++ {
rt1 = append(rt1, chars[rand.Intn(len(chars))])
rt2[i] = chars[rand.Intn(len(chars))]
}
return string(rt1), string(rt2)
}
func md5String(text string, salt string) string {
//sal+":"+text
bytes := []byte(salt)
bytes = append(bytes, ':')
bytes = append(bytes, []byte(text)...)
return fmt.Sprintf("%x\n", md5.Sum(bytes))
}
func main() {
// //hash算法 => 签名 (不可逆)
// // MD5 sha1 sha256 sha512
// fmt.Printf("%x\n", md5.Sum([]byte("我是tt")))
// //返回字符数和错误信息
// fmt.Println(fmt.Printf("%x\n", md5.Sum([]byte("我是tt"))))
// //分两次传入
// hasher := md5.New()
// hasher.Write([]byte("我是"))
// hasher.Write([]byte("tt"))
// fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
//加盐+md5
salt1, salt2 := randString(6)
fmt.Println(salt1, salt2)
fmt.Println(md5String("我是tt", salt1))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhash> go run .\main.go
ddeade ddccac
3341accdd922d89818d0e95301bedc19
*/
sha1
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().Unix())
}
func randString(n int) (string, string) {
rt1 := make([]byte, 0, n)
rt2 := make([]byte, n, n)
//定义取值范围切片
chars := []byte{'a', 'b', 'c', 'd', 'e'}
//循环n次,每次生成随机数(切片范围内),获取对应的字符
for i := 0; i < n; i++ {
rt1 = append(rt1, chars[rand.Intn(len(chars))])
rt2[i] = chars[rand.Intn(len(chars))]
}
return string(rt1), string(rt2)
}
func md5String(text string, salt string) string {
//sal+":"+text
bytes := []byte(salt)
bytes = append(bytes, ':')
bytes = append(bytes, []byte(text)...)
return fmt.Sprintf("%x\n", md5.Sum(bytes))
}
func main() {
// //hash算法 => 签名 (不可逆)
// // MD5 sha1 sha256 sha512
// fmt.Printf("%x\n", md5.Sum([]byte("我是tt")))
// //返回字符数和错误信息
// fmt.Println(fmt.Printf("%x\n", md5.Sum([]byte("我是tt"))))
// //分两次传入
// hasher := md5.New()
// hasher.Write([]byte("我是"))
// hasher.Write([]byte("tt"))
// fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
//加盐+md5
// salt1, salt2 := randString(6)
// fmt.Println(salt1, salt2)
// fmt.Println(md5String("我是tt", salt1))
fmt.Printf("%x\n", sha1.Sum([]byte("我是tt")))
fmt.Printf("%x\n", sha256.Sum256([]byte("我是tt")))
fmt.Printf("%x\n", sha512.Sum512([]byte("我是tt")))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhash> go run .\main.go
65687e1ffecfa849822e8989ff272cd2ef39b84b
685674d1fdaae933c8f8657806fccc87b1ea51b8c3faff4f1fcc10da4a03dd85
ec8ce5c566a93ac41c2adc2eba9a1fb04bf79d1cbf15d627872d7e7da655d4176b45bef6d6bd72ac2122dbc1fc496118f15b78e395c54e88b996cb53dfff6091
*/
sha1拼接
注意区分大小写
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().Unix())
}
func randString(n int) (string, string) {
rt1 := make([]byte, 0, n)
rt2 := make([]byte, n, n)
//定义取值范围切片
chars := []byte{'a', 'b', 'c', 'd', 'e'}
//循环n次,每次生成随机数(切片范围内),获取对应的字符
for i := 0; i < n; i++ {
rt1 = append(rt1, chars[rand.Intn(len(chars))])
rt2[i] = chars[rand.Intn(len(chars))]
}
return string(rt1), string(rt2)
}
func md5String(text string, salt string) string {
//sal+":"+text
bytes := []byte(salt)
bytes = append(bytes, ':')
bytes = append(bytes, []byte(text)...)
return fmt.Sprintf("%x\n", md5.Sum(bytes))
}
func main() {
// //hash算法 => 签名 (不可逆)
// // MD5 sha1 sha256 sha512
// fmt.Printf("%x\n", md5.Sum([]byte("我是tt")))
// //返回字符数和错误信息
// fmt.Println(fmt.Printf("%x\n", md5.Sum([]byte("我是tt"))))
// //分两次传入
// hasher := md5.New()
// hasher.Write([]byte("我是"))
// hasher.Write([]byte("tt"))
// fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
//加盐+md5
// salt1, salt2 := randString(6)
// fmt.Println(salt1, salt2)
// fmt.Println(md5String("我是tt", salt1))
fmt.Printf("%x\n", sha1.Sum([]byte("我是tt")))
fmt.Printf("%x\n", sha256.Sum256([]byte("我是tt")))
fmt.Printf("%x\n", sha512.Sum512([]byte("我是tt")))
sha256Hasher := sha256.New()
sha256Hasher.Write([]byte("我是"))
sha256Hasher.Write([]byte("tt"))
fmt.Println(hex.EncodeToString(sha256Hasher.Sum(nil)))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testhash> go run .\main.go
65687e1ffecfa849822e8989ff272cd2ef39b84b
685674d1fdaae933c8f8657806fccc87b1ea51b8c3faff4f1fcc10da4a03dd85
ec8ce5c566a93ac41c2adc2eba9a1fb04bf79d1cbf15d627872d7e7da655d4176b45bef6d6bd72ac2122dbc1fc496118f15b78e395c54e88b996cb53dfff6091
685674d1fdaae933c8f8657806fccc87b1ea51b8c3faff4f1fcc10da4a03dd85
*/
os/exec
cmd.Output()
直接用output 一般一次输出完
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("ping", "-n", "2", "www.baidu.com")
bytes, err := cmd.Output()
fmt.Println(string(bytes), err)
}
/*打印结果
PS D:\GoWork\src\go_course\day04-20230312\codes\testcmd> go run .\main.go
���� Ping www.a.shifen.com [110.242.68.3] ���� 32 �ֽڵ�����:
���� 110.242.68.3 �Ļظ�: �ֽ�=32 ʱ��=13ms TTL=53
���� 110.242.68.3 �Ļظ�: �ֽ�=32 ʱ��=15ms TTL=53
110.242.68.3 �� Ping ͳ����Ϣ:
���ݰ�: �ѷ��� = 2���ѽ��� = 2����ʧ = 0 (0% ��ʧ)��
�����г̵Ĺ���ʱ��(�Ժ���Ϊ��λ):
���� = 13ms��� = 15ms��ƽ�� = 14ms
<nil>
*/
cmd.StdoutPipe() 管道
使用cmd.StdoutPipe() 到管道,一般隔一段时间输出的使用这种方式
package main
import (
"fmt"
"io"
"os"
"os/exec"
)
func main() {
cmd := exec.Command("ping", "-n", "2", "www.baidu.com")
// bytes, err := cmd.Output()
// fmt.Println(string(bytes), err)
output, err := cmd.StdoutPipe()
cmd.Start()
fmt.Println(err)
//从管道拿取数据到输出,一般定时
io.Copy(os.Stdout, output)
cmd.Wait()
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testcmd> go run .\main.go
<nil>
���� Ping www.baidu.com [110.242.68.3] ���� 32 �ֽڵ�����:
���� 110.242.68.3 �Ļظ�: �ֽ�=32 ʱ��=71ms TTL=53
���� 110.242.68.3 �Ļظ�: �ֽ�=32 ʱ��=16ms TTL=53
110.242.68.3 �� Ping ͳ����Ϣ:
���ݰ�: �ѷ��� = 2���ѽ��� = 2����ʧ = 0 (0% ��ʧ)��
�����г̵Ĺ���ʱ��(�Ժ���Ϊ��λ):
���� = 16ms��� = 71ms��ƽ�� = 43ms
*/
解决乱码问题
package main
import (
"bufio"
"fmt"
"os/exec"
"golang.org/x/text/encoding/simplifiedchinese"
)
type Charset string
const (
UTF8 = Charset("UTF-8")
GB18030 = Charset("GB18030")
)
func main() {
cmd := exec.Command("ping", "-n", "2", "www.baidu.com")
// bytes, err := cmd.Output()
// fmt.Println(string(bytes), err)
output, err := cmd.StdoutPipe()
cmd.Start()
fmt.Println(err)
in := bufio.NewScanner(output)
for in.Scan() {
cmdRe := ConvertByte2String(in.Bytes(), "GB18030")
fmt.Println(cmdRe)
}
//从管道拿取数据到输出,一般定时
// io.Copy(os.Stdout, output)
cmd.Wait()
}
func ConvertByte2String(byte []byte, charset Charset) string {
var str string
switch charset {
case GB18030:
var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
str = string(decodeBytes)
case UTF8:
fallthrough
default:
str = string(byte)
}
return str
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testcmd> go run .\main.go
<nil>
正在 Ping www.a.shifen.com [110.242.68.3] 具有 32 字节的数据:
来自 110.242.68.3 的回复: 字节=32 时间=56ms TTL=53
来自 110.242.68.3 的回复: 字节=32 时间=53ms TTL=53
110.242.68.3 的 Ping 统计信息:
数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 53ms,最长 = 56ms,平均 = 54ms
*/
生成随机数(官方示例)
package main
import (
"bytes"
"fmt"
"math/rand"
)
func main() {
c := 10
b := make([]byte, c)
_, err := rand.Read(b)
fmt.Println(b)
if err != nil {
fmt.Println("error", err)
return
}
fmt.Println(bytes.Equal(b, make([]byte, c)))
}
/*
PS D:\GoWork\src\go_course\day04-20230312\codes\testrand> go run .\main.go
[205 251 34 232 77 192 249 191 123 108]
false
*/