@@ -0,0 +1,91 @@ | |||
package face_check | |||
import ( | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"crypto/hmac" | |||
"crypto/sha256" | |||
"encoding/base64" | |||
"errors" | |||
"fmt" | |||
"sort" | |||
"time" | |||
) | |||
func Send(url string, appKey, appSecret string, arg, HeaderArr map[string]string) (string, error) { | |||
sign := Sign(url, arg, "POST", appKey, appSecret, HeaderArr) | |||
HeaderArr["X-Ca-Signature"] = sign | |||
domain := "https://zfah.market.alicloudapi.com" | |||
post, err := zhios_third_party_utils.CurlPost(domain+url, arg, HeaderArr) | |||
if err != nil { | |||
return "", err | |||
} | |||
if post == nil { | |||
return "", errors.New("获取数据失败") | |||
} | |||
fmt.Println(post) | |||
fmt.Println(err) | |||
return string(post), nil | |||
} | |||
func Sign(url string, arg map[string]string, HTTPMethod, appKey, appSecret string, header map[string]string) string { | |||
headerStr := make([]string, 0) | |||
for k := range header { | |||
headerStr = append(headerStr, k) | |||
} | |||
sort.Strings(headerStr) | |||
str := HTTPMethod + "\n" | |||
str += header["Accept"] + "\n" | |||
str += header["Content-MD5"] + "\n" | |||
str += header["Content-Type"] + "\n" | |||
str += header["Date"] + "\n" | |||
var filter = []string{"X-Ca-Signature", "X-Ca-Signature-Headers", "Accept", "Content-MD5", "Content-Type", "Date"} | |||
for _, v := range headerStr { | |||
if zhios_third_party_utils.InArr(v, filter) { | |||
continue | |||
} | |||
str += v + ":" + header[v] + "\n" | |||
} | |||
pathStr := "" | |||
argStr := make([]string, 0) | |||
for k := range arg { | |||
argStr = append(argStr, k) | |||
} | |||
sort.Strings(argStr) | |||
for _, v := range argStr { | |||
if pathStr == "" { | |||
pathStr += "?" + v + "=" + arg[v] | |||
} else { | |||
pathStr += "&" + v + "=" + arg[v] | |||
} | |||
} | |||
str += url + pathStr | |||
fmt.Println(str) | |||
hmacSHA256 := GenHmacSha256(str, appSecret) | |||
fmt.Println(hmacSHA256) | |||
return hmacSHA256 | |||
} | |||
func GenHmacSha256(message string, secret string) string { | |||
h := hmac.New(sha256.New, []byte(secret)) | |||
h.Write([]byte(message)) | |||
//sha := hex.EncodeToString(h.Sum(nil)) | |||
//fmt.Printf("sha:%s\n", sha) | |||
return Base64UrlSafeEncode(h.Sum(nil)) | |||
} | |||
func Base64UrlSafeEncode(source []byte) string { | |||
byteArr := base64.StdEncoding.EncodeToString(source) | |||
return byteArr | |||
} | |||
func Header(appKey string) map[string]string { | |||
headers := map[string]string{ | |||
"Accept": "application/json; charset=utf-8", | |||
"X-Ca-Key": appKey, | |||
"X-Ca-Nonce": zhios_third_party_utils.RandNum(), | |||
"X-Ca-Signature-Method": "HmacSHA256", | |||
"X-Ca-Timestamp": zhios_third_party_utils.Int64ToStr(time.Now().Unix() * 1000), | |||
"X-Ca-Signature-Headers": "X-Ca-Key,X-Ca-Nonce,X-Ca-Signature-Method,X-Ca-Timestamp", | |||
} | |||
return headers | |||
} |
@@ -0,0 +1,17 @@ | |||
package face_check | |||
/* | |||
base64Str string 是 人脸照片的base64位编码字符串(需utf8编码的urlencode) 注:照片需要大于5kb,小于100kb 头像姿态建议:平面旋转:-15°~15°,俯仰变化:-10°~10°,姿态偏转:-15°~15°, 特别注意:图片中头像不可倒置 base64不需要带(data:image/png;base64,) | |||
liveChk string 否 是否进行活体检测;1:进行活体检测; 0:不进行活体检测; | |||
name string 是 姓名 | |||
number string 是 身份证号码 | |||
*/ | |||
func Check(appKey, appSecret string, args map[string]string) (string, error) { | |||
url := "/efficient/idfaceIdentity" | |||
//argStr, _ := json.Marshal(args) | |||
HeaderArr := Header(appKey) | |||
HeaderArr["Content-MD5"] = "" | |||
HeaderArr["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8" | |||
post, err := Send(url, appKey, appSecret, args, HeaderArr) | |||
return post, err | |||
} |
@@ -0,0 +1,14 @@ | |||
package face_check | |||
import "testing" | |||
func TestFace(t *testing.T) { | |||
args := map[string]string{ | |||
"Threshold": "0.33", | |||
"base64Str": "111", | |||
"liveChk": "0", | |||
"name": "123", | |||
"number": "333", | |||
} | |||
Check(args) | |||
} |
@@ -81,6 +81,7 @@ func curl(method, router string, body interface{}, header map[string]string) ([] | |||
if er != nil { | |||
return nil, er | |||
} | |||
fmt.Println("================接口数据", resp) | |||
res, err := ioutil.ReadAll(resp.Body) | |||
if CurlDebug { | |||
blob := SerializeStr(body) | |||
@@ -0,0 +1,31 @@ | |||
package zhios_third_party_utils | |||
import ( | |||
crand "crypto/rand" | |||
"fmt" | |||
"math/big" | |||
"math/rand" | |||
"time" | |||
) | |||
func RandString(l int, c ...string) string { | |||
var ( | |||
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |||
str string | |||
num *big.Int | |||
) | |||
if len(c) > 0 { | |||
chars = c[0] | |||
} | |||
chrLen := int64(len(chars)) | |||
for len(str) < l { | |||
num, _ = crand.Int(crand.Reader, big.NewInt(chrLen)) | |||
str += string(chars[num.Int64()]) | |||
} | |||
return str | |||
} | |||
func RandNum() string { | |||
seed := time.Now().UnixNano() + rand.Int63() | |||
return fmt.Sprintf("%05v", rand.New(rand.NewSource(seed)).Int31n(1000000)) | |||
} |
@@ -0,0 +1,203 @@ | |||
package zhios_third_party_utils | |||
import ( | |||
"fmt" | |||
"github.com/syyongx/php2go" | |||
"math/rand" | |||
"reflect" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
func Implode(glue string, args ...interface{}) string { | |||
data := make([]string, len(args)) | |||
for i, s := range args { | |||
data[i] = fmt.Sprint(s) | |||
} | |||
return strings.Join(data, glue) | |||
} | |||
//字符串是否在数组里 | |||
func InArr(target string, str_array []string) bool { | |||
for _, element := range str_array { | |||
if target == element { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
func InArrToInt(target int, str_array []int) bool { | |||
for _, element := range str_array { | |||
if target == element { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
//把数组的值放到key里 | |||
func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { | |||
result = make(map[string]interface{}) | |||
t := reflect.TypeOf(array) | |||
v := reflect.ValueOf(array) | |||
if t.Kind() != reflect.Slice { | |||
return nil, nil | |||
} | |||
if v.Len() == 0 { | |||
return nil, nil | |||
} | |||
for i := 0; i < v.Len(); i++ { | |||
indexv := v.Index(i) | |||
if indexv.Type().Kind() != reflect.Struct { | |||
return nil, nil | |||
} | |||
mapKeyInterface := indexv.FieldByName(key) | |||
if mapKeyInterface.Kind() == reflect.Invalid { | |||
return nil, nil | |||
} | |||
mapKeyString, err := InterfaceToString(mapKeyInterface.Interface()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
result[mapKeyString] = indexv.Interface() | |||
} | |||
return result, err | |||
} | |||
//转string | |||
func InterfaceToString(v interface{}) (result string, err error) { | |||
switch reflect.TypeOf(v).Kind() { | |||
case reflect.Int64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: | |||
result = fmt.Sprintf("%v", v) | |||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | |||
result = fmt.Sprintf("%v", v) | |||
case reflect.String: | |||
result = v.(string) | |||
default: | |||
err = nil | |||
} | |||
return result, err | |||
} | |||
func HideTrueName(name string) string { | |||
res := "**" | |||
if name != "" { | |||
runs := []rune(name) | |||
leng := len(runs) | |||
if leng <= 3 { | |||
res = string(runs[0:1]) + res | |||
} else if leng < 5 { | |||
res = string(runs[0:2]) + res | |||
} else if leng < 10 { | |||
res = string(runs[0:2]) + "***" + string(runs[leng-2:leng]) | |||
} else if leng < 16 { | |||
res = string(runs[0:3]) + "****" + string(runs[leng-3:leng]) | |||
} else { | |||
res = string(runs[0:4]) + "*****" + string(runs[leng-4:leng]) | |||
} | |||
} | |||
return res | |||
} | |||
func GetQueryParam(uri string) map[string]string { | |||
//根据问号分割路由还是query参数 | |||
uriList := strings.Split(uri, "?") | |||
var query = make(map[string]string, 0) | |||
//有参数才处理 | |||
if len(uriList) == 2 { | |||
//分割query参数 | |||
var queryList = strings.Split(uriList[1], "&") | |||
if len(queryList) > 0 { | |||
//key value 分别赋值 | |||
for _, v := range queryList { | |||
var valueList = strings.Split(v, "=") | |||
if len(valueList) == 2 { | |||
value, _ := php2go.URLDecode(valueList[1]) | |||
if value == "" { | |||
value = valueList[1] | |||
} | |||
query[valueList[0]] = value | |||
} | |||
} | |||
} | |||
} | |||
return query | |||
} | |||
//JoinStringsInASCII 按照规则,参数名ASCII码从小到大排序后拼接 | |||
//data 待拼接的数据 | |||
//sep 连接符 | |||
//onlyValues 是否只包含参数值,true则不包含参数名,否则参数名和参数值均有 | |||
//includeEmpty 是否包含空值,true则包含空值,否则不包含,注意此参数不影响参数名的存在 | |||
//exceptKeys 被排除的参数名,不参与排序及拼接 | |||
func JoinStringsInASCII(data map[string]string, sep string, onlyValues, includeEmpty bool, exceptKeys ...string) string { | |||
var list []string | |||
var keyList []string | |||
m := make(map[string]int) | |||
if len(exceptKeys) > 0 { | |||
for _, except := range exceptKeys { | |||
m[except] = 1 | |||
} | |||
} | |||
for k := range data { | |||
if _, ok := m[k]; ok { | |||
continue | |||
} | |||
value := data[k] | |||
if !includeEmpty && value == "" { | |||
continue | |||
} | |||
if onlyValues { | |||
keyList = append(keyList, k) | |||
} else { | |||
list = append(list, fmt.Sprintf("%s=%s", k, value)) | |||
} | |||
} | |||
if onlyValues { | |||
sort.Strings(keyList) | |||
for _, v := range keyList { | |||
list = append(list, AnyToString(data[v])) | |||
} | |||
} else { | |||
sort.Strings(list) | |||
} | |||
return strings.Join(list, sep) | |||
} | |||
//x的y次方 | |||
func RandPow(l int) string { | |||
var i = "1" | |||
for j := 0; j < l; j++ { | |||
i += "0" | |||
} | |||
k := StrToInt64(i) | |||
n := rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(k) | |||
ls := "%0" + IntToStr(l) + "v" | |||
str := fmt.Sprintf(ls, n) | |||
//min := int(math.Pow10(l - 1)) | |||
//max := int(math.Pow10(l) - 1) | |||
return str | |||
} | |||
//根据显示长度截取字符串 | |||
func ShowSubstr(s string, l int) string { | |||
if len(s) <= l { | |||
return s | |||
} | |||
ss, sl, rl, rs := "", 0, 0, []rune(s) | |||
for _, r := range rs { | |||
rint := int(r) | |||
if rint < 128 { | |||
rl = 1 | |||
} else { | |||
rl = 2 | |||
} | |||
if sl+rl > l { | |||
break | |||
} | |||
sl += rl | |||
ss += string(r) | |||
} | |||
return ss | |||
} |
@@ -0,0 +1,43 @@ | |||
package zhios_third_party_utils | |||
import ( | |||
"fmt" | |||
"math/rand" | |||
"time" | |||
) | |||
const ( | |||
KC_RAND_KIND_NUM = 0 // 纯数字 | |||
KC_RAND_KIND_LOWER = 1 // 小写字母 | |||
KC_RAND_KIND_UPPER = 2 // 大写字母 | |||
KC_RAND_KIND_ALL = 3 // 数字、大小写字母 | |||
) | |||
func newUUID() *[16]byte { | |||
u := &[16]byte{} | |||
rand.Read(u[:16]) | |||
u[8] = (u[8] | 0x80) & 0xBf | |||
u[6] = (u[6] | 0x40) & 0x4f | |||
return u | |||
} | |||
func UUIDString() string { | |||
u := newUUID() | |||
return fmt.Sprintf("%x-%x-%x-%x-%x", u[:4], u[4:6], u[6:8], u[8:10], u[10:]) | |||
} | |||
func Krand(size int, kind int) []byte { | |||
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size) | |||
isAll := kind > 2 || kind < 0 | |||
rand.Seed(time.Now().UnixNano()) | |||
for i := 0; i < size; i++ { | |||
if isAll { // random ikind | |||
ikind = rand.Intn(3) | |||
} | |||
scope, base := kinds[ikind][0], kinds[ikind][1] | |||
result[i] = uint8(base + rand.Intn(scope)) | |||
} | |||
return result | |||
} |