background/vendor/git.jiaxianghudong.com/go/utils/verifier.go

253 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package utils
import (
"reflect"
"regexp"
"strings"
"net/http"
"strconv"
"time"
"math"
)
// IsIDCard 检查是否是身份证
func IsIDCard(str string, args ...bool) bool {
if m, _ := regexp.MatchString("^(?:[\\dxX]{15}|[\\dxX]{18})$", str); !m {
return false
}
areaMap := map[int]string{
11 : "北京",
12 : "天津",
13 : "河北",
14 : "山西",
15 : "内蒙古",
21 : "辽宁",
22 : "吉林",
23 : "黑龙江",
31 : "上海",
32 : "江苏",
33 : "浙江",
34 : "安徽",
35 : "福建",
36 : "江西",
37 : "山东",
41 : "河南",
42 : "湖北",
43 : "湖南",
44 : "广东",
45 : "广西",
46 : "海南",
50 : "重庆",
51 : "四川",
52 : "贵州",
53 : "云南",
54 : "西藏",
61 : "陕西",
62 : "甘肃",
63 : "青海",
64 : "宁夏",
65 : "新疆",
71 : "台湾",
81 : "香港",
82 : "澳门",
91 : "国外",
}
allowLen15 := true
if len(args) == 1 {
allowLen15 = args[0]
}
province := Atoi(Substr(str, 0, 2))
if _, ok := areaMap[province]; !ok {
return false
}
//如果是15位身份证
if len(str) == 15 && allowLen15 {
// 如果身份证顺序码是996 997 998 999这些是为百岁以上老人的特殊编码
code := Substr(str, 12, 3)
if code == "996" || code == "997" || code == "998" || code == "999" {
str = Substr(str, 0, 6) + "18" + Substr(str, 6, 9)
} else {
str = Substr(str, 0, 6) + "19" + Substr(str, 6, 9)
}
str += idcardVerifyNumber(str)
}
if len(str) != 18 || !checkIdcardFormat(str) {
return false
}
return idcardVerifyNumber(Substr(str, 0, 17)) == strings.ToUpper(Substr(str, 17, 1))
}
// checkIdcardFormat 检查身份证号码的格式
// 针对近期出现身份证号码使用210000000000000000注册的用户
// 验证地区码(3-6位)以及生日(6-14)位
func checkIdcardFormat(str string) bool {
code := Atoi(Substr(str, 3, 3))
if code == 0 {
return false
}
if len(str) == 18 {
birthYear := Atoi(Substr(str, 6, 4))
birthMonth := Atoi(Substr(str, 10, 2))
birthDay := Atoi(Substr(str, 10, 2))
if birthYear < 1900 || (birthMonth == 0 || birthMonth > 12) || (birthDay == 0 || birthDay > 31) {
return false
}
return true
}
return false
}
// idcardVerifyNumber 计算身份证校验码根据国家标准GB 11643-1999
func idcardVerifyNumber(str string) string {
if len(str) != 17 {
return ""
}
//加权因子
factor := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
//校验码对应值
verifyNumberList := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
checkSum := 0
for i, l := 0, len(str); i < l; i++ {
checkSum += Atoi(Substr(str, i, 1)) * factor[i]
}
checkSum = checkSum % 11
return verifyNumberList[checkSum]
}
// 是否为空
func IsEmpty(val interface{}) (b bool) {
defer func() {
if err := recover(); err != nil {
b = true
}
}()
v := reflect.ValueOf(val)
switch v.Kind() {
case reflect.Bool:
b = (val.(bool) == false)
case reflect.String:
b = (val.(string) == "")
case reflect.Array:
fallthrough
case reflect.Slice:
fallthrough
case reflect.Map:
b = (v.Len() == 0)
default:
b = (v.Interface() == reflect.ValueOf(0).Interface() || v.Interface() == reflect.ValueOf(0.0).Interface())
}
return b
}
// 判断是否正确的ip地址
func IsIp(ip string) bool {
ips := strings.Split(ip, ".")
if len(ips) != 4 {
return false
}
for _, v := range ips {
i := Atoi(v, -1)
if i < 0 || i > 255 {
return false
}
}
return true
}
//检测是否为手机设备
func IsMobileDevice(r *http.Request) bool {
agent := r.UserAgent()
if strings.Contains(agent,"iPhone") || strings.Contains(agent,"iPad") || strings.Contains(agent,"iOS") || strings.Contains(agent,"Android") {
return true;
}
return false;
}
// 检查字符串是否为纯数字组成
func IsNumStr(s string) bool {
if _, err := strconv.Atoi(s); err == nil {
return true
}
return false
}
// 检查字符串是否为纯数字组成
func IsLongNumStr(s string) bool {
if m, _ := regexp.MatchString("^\\d+$", s); m {
return true
}
return false
}
// IsMobileNum 检查是否是手机号
func IsMobileNum(str string) bool {
if m, _ := regexp.MatchString("^((13[\\d])|(147)|(15[\\d])|17[\\d]|(18[\\d]))[0-9]{8}$", str); m {
return true
}
return false
}
// IsVersionStr 检查字符串是否是一个版本格式
func IsVersionStr(str string) bool {
return IsVersion(str, "{2}")
}
// IsVersion 检查字符串是否是一个版本格式
func IsVersion(str string, length ...string) bool {
vL := "{1,3}"
if len(length) == 1 {
vL = length[0]
}
if m, _ := regexp.MatchString("^\\d+(?:\\.\\d+)" + vL + "$", str); m {
return true
}
return false
}
// IsDeviceCode 检查字符串是否是一个机器码
func IsDeviceCode(str string) bool {
if m, _ := regexp.MatchString("^[a-zA-Z0-9]{40}$", str); m {
return true
}
return false
}
// RegexpOK 检查字符串被正则匹配
func RegexpOK(pattern, str string) bool {
if m, _ := regexp.MatchString(pattern, str); m {
return true
}
return false
}
// DiffDay 比较两个日志间隔的天数
// 第1个日期小于第2个日期时返回正数
// 第1个日期大于第2个日期时返回负数
func DiffDay(t1, t2 string, fm ...string) (int, error) {
format := "2006-01-02"
if len(fm) == 1 {
format = fm[0]
}
tm1, err := time.ParseInLocation(format, t1, time.Local)
if err != nil {
return 0, err
}
tm2, err := time.ParseInLocation(format, t2, time.Local)
if err != nil {
return 0, err
}
hour := tm2.Sub(tm1).Hours()
if -24 >= hour || hour >= 24 {
return int(math.Ceil(hour / 24)), nil
}
return 0, nil
}