1
0

feat: 删除不需要文件夹

This commit is contained in:
TsMask
2023-10-10 10:56:44 +08:00
parent ce7c3cae68
commit d173205528
154 changed files with 32276 additions and 1 deletions

View File

@@ -0,0 +1,20 @@
package crypto
import (
"golang.org/x/crypto/bcrypt"
)
// BcryptHash Bcrypt密码加密
func BcryptHash(originStr string) string {
hash, err := bcrypt.GenerateFromPassword([]byte(originStr), bcrypt.DefaultCost)
if err != nil {
return ""
}
return string(hash)
}
// BcryptCompare Bcrypt密码匹配检查
func BcryptCompare(originStr, hashStr string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashStr), []byte(originStr))
return err == nil
}

133
lib/core/utils/ctx/ctx.go Normal file
View File

@@ -0,0 +1,133 @@
package ctx
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"path/filepath"
"ems.agt/lib/core/vo"
"github.com/gorilla/mux"
)
// Param 地址栏参数{id}
func Param(r *http.Request, key string) string {
vars := mux.Vars(r)
v, ok := vars[key]
if ok {
return v
}
return ""
}
// GetQuery 查询参数
func GetQuery(r *http.Request, key string) string {
return r.URL.Query().Get(key)
}
// QueryMap 查询参数转换Map
func QueryMap(r *http.Request) map[string]any {
queryValues := r.URL.Query()
queryParams := make(map[string]any)
for key, values := range queryValues {
queryParams[key] = values[0]
}
return queryParams
}
// 读取json请求结构团体
func ShouldBindJSON(r *http.Request, args any) error {
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) // 设置较大的长度,例如 1<<20 (1MB)
if err != nil {
return err
}
err = json.Unmarshal(body, args)
return err
}
// JSON 相应json数据
func JSON(w http.ResponseWriter, code int, data any) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
response, err := json.Marshal(data)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
} else {
w.WriteHeader(code)
w.Write(response)
}
}
// 将文件导出到外部下载
func FileAttachment(w http.ResponseWriter, r *http.Request, filepath, filename string) {
w.Header().Set("Content-Disposition", `attachment; filename=`+url.QueryEscape(filename))
w.Header().Set("Content-Type", "application/octet-stream")
http.ServeFile(w, r, filepath)
}
// 将文件上传保存到指定目录
// file, handler, err := r.FormFile("file")
// SaveUploadedFile uploads the form file to specific dst.
func SaveUploadedFile(r *http.Request, dst string) error {
// 解析请求中的文件
_, handler, err := r.FormFile("file")
if err != nil {
return err
}
src, err := handler.Open()
if err != nil {
return err
}
defer src.Close()
if err = os.MkdirAll(filepath.Dir(dst), 0750); err != nil {
return err
}
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src)
return err
}
/// ==== 登录用户信息, 通过中间件后预置入
// 定义自定义类型作为键
type ContextKey string
// LoginUser 登录用户信息需要Authorize中间件
func LoginUser(r *http.Request) (vo.LoginUser, error) {
// 上下文
v := r.Context().Value(ContextKey("LoginUser"))
if v != nil {
return v.(vo.LoginUser), nil
}
return vo.LoginUser{}, fmt.Errorf("无用户信息")
}
// LoginUserToUserID 登录用户信息-用户ID
func LoginUserToUserID(r *http.Request) string {
loginUser, err := LoginUser(r)
if err != nil {
return ""
}
return loginUser.UserID
}
// LoginUserToUserName 登录用户信息-用户名称
func LoginUserToUserName(r *http.Request) string {
loginUser, err := LoginUser(r)
if err != nil {
return ""
}
return loginUser.UserName
}

View File

@@ -0,0 +1,70 @@
package date
import (
"fmt"
"time"
"ems.agt/lib/log"
)
const (
// 年 列如2022
YYYY = "2006"
// 年-月 列如2022-12
YYYY_MM = "2006-01"
// 年-月-日 列如2022-12-30
YYYY_MM_DD = "2006-01-02"
// 年月日时分秒 列如20221230010159
YYYYMMDDHHMMSS = "20060102150405"
// 年-月-日 时:分:秒 列如2022-12-30 01:01:59
YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05"
)
// 格式时间字符串
//
// dateStr 时间字符串
//
// formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
func ParseStrToDate(dateStr, formatStr string) time.Time {
t, err := time.Parse(formatStr, dateStr)
if err != nil {
log.Infof("utils ParseStrToDate err %v", err)
return time.Time{}
}
return t
}
// 格式时间
//
// date 可转的Date对象
//
// formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
func ParseDateToStr(date any, formatStr string) string {
t, ok := date.(time.Time)
if !ok {
switch v := date.(type) {
case int64:
if v == 0 {
return ""
}
t = time.UnixMilli(v)
case string:
parsedTime, err := time.Parse(formatStr, v)
if err != nil {
fmt.Printf("utils ParseDateToStr err %v \n", err)
return ""
}
t = parsedTime
default:
return ""
}
}
return t.Format(formatStr)
}
// 格式时间成日期路径
//
// 年/月 列如2022/12
func ParseDatePath(date time.Time) string {
return date.Format("2006/01")
}

View File

@@ -0,0 +1,34 @@
package firewall
import (
"errors"
"os"
"ems.agt/lib/core/utils/firewall/client"
)
type FirewallClient interface {
Name() string // ufw firewalld
Start() error
Stop() error
Reload() error
Status() (string, error) // running not running
Version() (string, error)
ListPort() ([]client.FireInfo, error)
ListAddress() ([]client.FireInfo, error)
Port(port client.FireInfo, operation string) error
RichRules(rule client.FireInfo, operation string) error
PortForward(info client.Forward, operation string) error
}
func NewFirewallClient() (FirewallClient, error) {
if _, err := os.Stat("/usr/sbin/firewalld"); err == nil {
return client.NewFirewalld()
}
if _, err := os.Stat("/usr/sbin/ufw"); err == nil {
return client.NewUfw()
}
return nil, errors.New("no such type")
}

View File

@@ -0,0 +1,209 @@
package client
import (
"fmt"
"strings"
"sync"
"ems.agt/lib/core/cmd"
)
type Firewall struct{}
func NewFirewalld() (*Firewall, error) {
return &Firewall{}, nil
}
func (f *Firewall) Name() string {
return "firewalld"
}
func (f *Firewall) Status() (string, error) {
stdout, _ := cmd.Exec("firewall-cmd --state")
if stdout == "running\n" {
return "running", nil
}
return "not running", nil
}
func (f *Firewall) Version() (string, error) {
stdout, err := cmd.Exec("firewall-cmd --version")
if err != nil {
return "", fmt.Errorf("load the firewall version failed, err: %s", stdout)
}
return strings.ReplaceAll(stdout, "\n ", ""), nil
}
func (f *Firewall) Start() error {
stdout, err := cmd.Exec("systemctl start firewalld")
if err != nil {
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
}
return nil
}
func (f *Firewall) Stop() error {
stdout, err := cmd.Exec("systemctl stop firewalld")
if err != nil {
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
}
return nil
}
func (f *Firewall) Reload() error {
stdout, err := cmd.Exec("firewall-cmd --reload")
if err != nil {
return fmt.Errorf("reload firewall failed, err: %s", stdout)
}
return nil
}
func (f *Firewall) ListPort() ([]FireInfo, error) {
var wg sync.WaitGroup
var datas []FireInfo
wg.Add(2)
go func() {
defer wg.Done()
stdout, err := cmd.Exec("firewall-cmd --zone=public --list-ports")
if err != nil {
return
}
ports := strings.Split(strings.ReplaceAll(stdout, "\n", ""), " ")
for _, port := range ports {
if len(port) == 0 {
continue
}
var itemPort FireInfo
if strings.Contains(port, "/") {
itemPort.Port = strings.Split(port, "/")[0]
itemPort.Protocol = strings.Split(port, "/")[1]
}
itemPort.Strategy = "accept"
datas = append(datas, itemPort)
}
}()
go func() {
defer wg.Done()
stdout1, err := cmd.Exec("firewall-cmd --zone=public --list-rich-rules")
if err != nil {
return
}
rules := strings.Split(stdout1, "\n")
for _, rule := range rules {
if len(rule) == 0 {
continue
}
itemRule := f.loadInfo(rule)
if len(itemRule.Port) != 0 && itemRule.Family == "ipv4" {
datas = append(datas, itemRule)
}
}
}()
wg.Wait()
return datas, nil
}
func (f *Firewall) ListAddress() ([]FireInfo, error) {
stdout, err := cmd.Exec("firewall-cmd --zone=public --list-rich-rules")
if err != nil {
return nil, err
}
var datas []FireInfo
rules := strings.Split(stdout, "\n")
for _, rule := range rules {
if len(rule) == 0 {
continue
}
itemRule := f.loadInfo(rule)
if len(itemRule.Port) == 0 && len(itemRule.Address) != 0 {
datas = append(datas, itemRule)
}
}
return datas, nil
}
func (f *Firewall) Port(port FireInfo, operation string) error {
if cmd.CheckIllegal(operation, port.Protocol, port.Port) {
return fmt.Errorf("errCmdIllegal %v", port)
}
stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-port=%s/%s --permanent", operation, port.Port, port.Protocol)
if err != nil {
return fmt.Errorf("%s port failed, err: %s", operation, stdout)
}
return nil
}
func (f *Firewall) RichRules(rule FireInfo, operation string) error {
if cmd.CheckIllegal(operation, rule.Address, rule.Protocol, rule.Port, rule.Strategy) {
return fmt.Errorf("errCmdIllegal %v", rule)
}
ruleStr := ""
if strings.Contains(rule.Address, "-") {
std, err := cmd.Execf("firewall-cmd --permanent --new-ipset=%s --type=hash:ip", rule.Address)
if err != nil {
return fmt.Errorf("add new ipset failed, err: %s", std)
}
std2, err := cmd.Execf("firewall-cmd --permanent --ipset=%s --add-entry=%s", rule.Address, rule.Address)
if err != nil {
return fmt.Errorf("add entry to ipset failed, err: %s", std2)
}
if err := f.Reload(); err != nil {
return err
}
ruleStr = fmt.Sprintf("rule source ipset=%s %s", rule.Address, rule.Strategy)
} else {
ruleStr = "rule family=ipv4 "
if len(rule.Address) != 0 {
ruleStr += fmt.Sprintf("source address=%s ", rule.Address)
}
if len(rule.Port) != 0 {
ruleStr += fmt.Sprintf("port port=%s ", rule.Port)
}
if len(rule.Protocol) != 0 {
ruleStr += fmt.Sprintf("protocol=%s ", rule.Protocol)
}
ruleStr += rule.Strategy
}
stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleStr)
if err != nil {
return fmt.Errorf("%s rich rules failed, err: %s", operation, stdout)
}
return nil
}
func (f *Firewall) PortForward(info Forward, operation string) error {
ruleStr := fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Target)
if len(info.Address) != 0 {
ruleStr = fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toaddr=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Address, info.Target)
}
stdout, err := cmd.Exec(ruleStr)
if err != nil {
return fmt.Errorf("%s port forward failed, err: %s", operation, stdout)
}
return nil
}
func (f *Firewall) loadInfo(line string) FireInfo {
var itemRule FireInfo
ruleInfo := strings.Split(strings.ReplaceAll(line, "\"", ""), " ")
for _, item := range ruleInfo {
switch {
case strings.Contains(item, "family="):
itemRule.Family = strings.ReplaceAll(item, "family=", "")
case strings.Contains(item, "ipset="):
itemRule.Address = strings.ReplaceAll(item, "ipset=", "")
case strings.Contains(item, "address="):
itemRule.Address = strings.ReplaceAll(item, "address=", "")
case strings.Contains(item, "port="):
itemRule.Port = strings.ReplaceAll(item, "port=", "")
case strings.Contains(item, "protocol="):
itemRule.Protocol = strings.ReplaceAll(item, "protocol=", "")
case item == "accept" || item == "drop" || item == "reject":
itemRule.Strategy = item
}
}
return itemRule
}

View File

@@ -0,0 +1,20 @@
package client
type FireInfo struct {
Family string `json:"family"` // ipv4 ipv6
Address string `json:"address"` // Anywhere
Port string `json:"port"`
Protocol string `json:"protocol"` // tcp udp tcp/udp
Strategy string `json:"strategy"` // accept drop
APPName string `json:"appName"`
IsUsed bool `json:"isUsed"`
Description string `json:"description"`
}
type Forward struct {
Protocol string `json:"protocol"`
Address string `json:"address"`
Port string `json:"port"`
Target string `json:"target"`
}

View File

@@ -0,0 +1,238 @@
package client
import (
"fmt"
"strings"
"ems.agt/lib/core/cmd"
)
type Ufw struct {
CmdStr string
}
func NewUfw() (*Ufw, error) {
var ufw Ufw
if cmd.HasNoPasswordSudo() {
ufw.CmdStr = "sudo ufw"
} else {
ufw.CmdStr = "ufw"
}
return &ufw, nil
}
func (f *Ufw) Name() string {
return "ufw"
}
func (f *Ufw) Status() (string, error) {
stdout, _ := cmd.Execf("%s status | grep Status", f.CmdStr)
if stdout == "Status: active\n" {
return "running", nil
}
stdout1, _ := cmd.Execf("%s status | grep 状态", f.CmdStr)
if stdout1 == "状态: 激活\n" {
return "running", nil
}
return "not running", nil
}
func (f *Ufw) Version() (string, error) {
stdout, err := cmd.Execf("%s version | grep ufw", f.CmdStr)
if err != nil {
return "", fmt.Errorf("load the firewall status failed, err: %s", stdout)
}
info := strings.ReplaceAll(stdout, "\n", "")
return strings.ReplaceAll(info, "ufw ", ""), nil
}
func (f *Ufw) Start() error {
stdout, err := cmd.Execf("echo y | %s enable", f.CmdStr)
if err != nil {
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
}
return nil
}
func (f *Ufw) Stop() error {
stdout, err := cmd.Execf("%s disable", f.CmdStr)
if err != nil {
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
}
return nil
}
func (f *Ufw) Reload() error {
return nil
}
func (f *Ufw) ListPort() ([]FireInfo, error) {
stdout, err := cmd.Execf("%s status verbose", f.CmdStr)
if err != nil {
return nil, err
}
portInfos := strings.Split(stdout, "\n")
var datas []FireInfo
isStart := false
for _, line := range portInfos {
if strings.HasPrefix(line, "-") {
isStart = true
continue
}
if !isStart {
continue
}
itemFire := f.loadInfo(line, "port")
if len(itemFire.Port) != 0 && itemFire.Port != "Anywhere" && !strings.Contains(itemFire.Port, ".") {
itemFire.Port = strings.ReplaceAll(itemFire.Port, ":", "-")
datas = append(datas, itemFire)
}
}
return datas, nil
}
func (f *Ufw) ListAddress() ([]FireInfo, error) {
stdout, err := cmd.Execf("%s status verbose", f.CmdStr)
if err != nil {
return nil, err
}
portInfos := strings.Split(stdout, "\n")
var datas []FireInfo
isStart := false
for _, line := range portInfos {
if strings.HasPrefix(line, "-") {
isStart = true
continue
}
if !isStart {
continue
}
if !strings.Contains(line, " IN") {
continue
}
itemFire := f.loadInfo(line, "address")
if strings.Contains(itemFire.Port, ".") {
itemFire.Address += ("-" + itemFire.Port)
itemFire.Port = ""
}
if len(itemFire.Port) == 0 && len(itemFire.Address) != 0 {
datas = append(datas, itemFire)
}
}
return datas, nil
}
func (f *Ufw) Port(port FireInfo, operation string) error {
switch port.Strategy {
case "accept":
port.Strategy = "allow"
case "drop":
port.Strategy = "deny"
default:
return fmt.Errorf("unsupport strategy %s", port.Strategy)
}
if cmd.CheckIllegal(port.Protocol, port.Port) {
return fmt.Errorf("errCmdIllegal %v", port)
}
command := fmt.Sprintf("%s %s %s", f.CmdStr, port.Strategy, port.Port)
if operation == "remove" {
command = fmt.Sprintf("%s delete %s %s", f.CmdStr, port.Strategy, port.Port)
}
if len(port.Protocol) != 0 {
command += fmt.Sprintf("/%s", port.Protocol)
}
stdout, err := cmd.Exec(command)
if err != nil {
return fmt.Errorf("%s port failed, err: %s", operation, stdout)
}
return nil
}
func (f *Ufw) RichRules(rule FireInfo, operation string) error {
switch rule.Strategy {
case "accept":
rule.Strategy = "allow"
case "drop":
rule.Strategy = "deny"
default:
return fmt.Errorf("unsupport strategy %s", rule.Strategy)
}
if cmd.CheckIllegal(operation, rule.Protocol, rule.Address, rule.Port) {
return fmt.Errorf("errCmdIllegal %v", rule)
}
ruleStr := fmt.Sprintf("%s %s ", f.CmdStr, rule.Strategy)
if operation == "remove" {
ruleStr = fmt.Sprintf("%s delete %s ", f.CmdStr, rule.Strategy)
}
if len(rule.Protocol) != 0 {
ruleStr += fmt.Sprintf("proto %s ", rule.Protocol)
}
if strings.Contains(rule.Address, "-") {
ruleStr += fmt.Sprintf("from %s to %s ", strings.Split(rule.Address, "-")[0], strings.Split(rule.Address, "-")[1])
} else {
ruleStr += fmt.Sprintf("from %s ", rule.Address)
}
if len(rule.Port) != 0 {
ruleStr += fmt.Sprintf("to any port %s ", rule.Port)
}
stdout, err := cmd.Exec(ruleStr)
if err != nil {
return fmt.Errorf("%s rich rules failed, err: %s", operation, stdout)
}
return nil
}
func (f *Ufw) PortForward(info Forward, operation string) error {
ruleStr := fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Target)
if len(info.Address) != 0 {
ruleStr = fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toaddr=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Address, info.Target)
}
stdout, err := cmd.Exec(ruleStr)
if err != nil {
return fmt.Errorf("%s port forward failed, err: %s", operation, stdout)
}
if err := f.Reload(); err != nil {
return err
}
return nil
}
func (f *Ufw) loadInfo(line string, fireType string) FireInfo {
fields := strings.Fields(line)
var itemInfo FireInfo
if len(fields) < 4 {
return itemInfo
}
if fields[1] == "(v6)" {
return itemInfo
}
if fields[0] == "Anywhere" && fireType != "port" {
itemInfo.Strategy = "drop"
if fields[1] == "ALLOW" {
itemInfo.Strategy = "accept"
}
itemInfo.Address = fields[3]
return itemInfo
}
if strings.Contains(fields[0], "/") {
itemInfo.Port = strings.Split(fields[0], "/")[0]
itemInfo.Protocol = strings.Split(fields[0], "/")[1]
} else {
itemInfo.Port = fields[0]
itemInfo.Protocol = "tcp/udp"
}
itemInfo.Family = "ipv4"
if fields[1] == "ALLOW" {
itemInfo.Strategy = "accept"
} else {
itemInfo.Strategy = "drop"
}
itemInfo.Address = fields[3]
return itemInfo
}

View File

@@ -0,0 +1,139 @@
package parse
import (
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"github.com/robfig/cron/v3"
)
// Number 解析数值型
func Number(str any) int64 {
switch str := str.(type) {
case string:
if str == "" {
return 0
}
num, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return 0
}
return num
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return reflect.ValueOf(str).Int()
case float32, float64:
return int64(reflect.ValueOf(str).Float())
default:
return 0
}
}
// Boolean 解析布尔型
func Boolean(str any) bool {
switch str := str.(type) {
case string:
if str == "" || str == "false" || str == "0" {
return false
}
// 尝试将字符串解析为数字
if num, err := strconv.ParseFloat(str, 64); err == nil {
return num != 0
}
return true
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
num := reflect.ValueOf(str).Int()
return num != 0
case float32, float64:
num := reflect.ValueOf(str).Float()
return num != 0
default:
return false
}
}
// FirstUpper 首字母转大写
//
// 字符串 abc_123!@# 结果 Abc_123
func FirstUpper(str string) string {
if len(str) == 0 {
return str
}
reg := regexp.MustCompile(`[^_\w]+`)
str = reg.ReplaceAllString(str, "")
return strings.ToUpper(str[:1]) + str[1:]
}
// Bit 比特位为单位
func Bit(bit float64) string {
var GB, MB, KB string
if bit > float64(1<<30) {
GB = fmt.Sprintf("%0.2f", bit/(1<<30))
}
if bit > float64(1<<20) && bit < (1<<30) {
MB = fmt.Sprintf("%.2f", bit/(1<<20))
}
if bit > float64(1<<10) && bit < (1<<20) {
KB = fmt.Sprintf("%.2f", bit/(1<<10))
}
if GB != "" {
return GB + "GB"
} else if MB != "" {
return MB + "MB"
} else if KB != "" {
return KB + "KB"
} else {
return fmt.Sprintf("%vB", bit)
}
}
// CronExpression 解析 Cron 表达式,返回下一次执行的时间戳(毫秒)
//
// 【*/5 * * * * ?】 6个参数
func CronExpression(expression string) int64 {
specParser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
schedule, err := specParser.Parse(expression)
if err != nil {
fmt.Println(err)
return 0
}
return schedule.Next(time.Now()).UnixMilli()
}
// SafeContent 内容值进行安全掩码
func SafeContent(value string) string {
if len(value) < 3 {
return strings.Repeat("*", len(value))
} else if len(value) < 6 {
return string(value[0]) + strings.Repeat("*", len(value)-1)
} else if len(value) < 10 {
return string(value[0]) + strings.Repeat("*", len(value)-2) + string(value[len(value)-1])
} else if len(value) < 15 {
return value[:2] + strings.Repeat("*", len(value)-4) + value[len(value)-2:]
} else {
return value[:3] + strings.Repeat("*", len(value)-6) + value[len(value)-3:]
}
}
// RemoveDuplicates 数组内字符串去重
func RemoveDuplicates(ids []string) []string {
uniqueIDs := make(map[string]bool)
uniqueIDSlice := make([]string, 0)
for _, id := range ids {
_, ok := uniqueIDs[id]
if !ok && id != "" {
uniqueIDs[id] = true
uniqueIDSlice = append(uniqueIDSlice, id)
}
}
return uniqueIDSlice
}

View File

@@ -0,0 +1,54 @@
package regular
import (
"regexp"
)
// Replace 正则替换
func Replace(originStr, pattern, repStr string) string {
regex := regexp.MustCompile(pattern)
return regex.ReplaceAllString(originStr, repStr)
}
// 判断是否为有效用户名格式
//
// 用户名不能以数字开头可包含大写小写字母数字且不少于5位
func ValidUsername(username string) bool {
if username == "" {
return false
}
pattern := `^[a-zA-Z][a-z0-9A-Z]{5,}`
match, err := regexp.MatchString(pattern, username)
if err != nil {
return false
}
return match
}
// 判断是否为有效手机号格式1开头的11位手机号
func ValidMobile(mobile string) bool {
if mobile == "" {
return false
}
pattern := `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
match, err := regexp.MatchString(pattern, mobile)
if err != nil {
return false
}
return match
}
// 判断是否为http(s)://开头
//
// link 网络链接
func ValidHttp(link string) bool {
if link == "" {
return false
}
pattern := `^http(s)?:\/\/+`
match, err := regexp.MatchString(pattern, link)
if err != nil {
return false
}
return match
}

View File

@@ -0,0 +1,31 @@
package scan
import (
"net"
"strconv"
)
func ScanPort(port int) bool {
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
if err != nil {
return true
}
defer ln.Close()
return false
}
func ScanUDPPort(port int) bool {
ln, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: port})
if err != nil {
return true
}
defer ln.Close()
return false
}
func ScanPortWithProto(port int, proto string) bool {
if proto == "udp" {
return ScanUDPPort(port)
}
return ScanPort(port)
}