github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/function.go (about) 1 package kgo 2 3 import ( 4 "bytes" 5 "crypto/md5" 6 "crypto/sha1" 7 "crypto/sha256" 8 "crypto/sha512" 9 "encoding/base64" 10 "encoding/binary" 11 "encoding/hex" 12 "encoding/json" 13 "errors" 14 "fmt" 15 "hash" 16 "reflect" 17 "strconv" 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 "unsafe" 22 ) 23 24 // dumpPrint 打印调试变量,变量可多个. 25 func dumpPrint(vs ...interface{}) { 26 for _, v := range vs { 27 fmt.Printf("%+v\n", v) 28 //fmt.Printf("%#v\n", v) 29 } 30 } 31 32 // lenArrayOrSlice 获取数组/切片的长度. 33 // chkType为检查类型,枚举值有(1仅数组,2仅切片,3数组或切片);结果为-1表示变量不是数组或切片,>=0表示合法长度. 34 func lenArrayOrSlice(val interface{}, chkType uint8) int { 35 if chkType != 1 && chkType != 2 && chkType != 3 { 36 chkType = 3 37 } 38 39 var res = -1 40 refVal := reflect.ValueOf(val) 41 switch refVal.Kind() { 42 case reflect.Array: 43 if chkType == 1 || chkType == 3 { 44 res = refVal.Len() 45 } 46 case reflect.Slice: 47 if chkType == 2 || chkType == 3 { 48 res = refVal.Len() 49 } 50 } 51 52 return res 53 } 54 55 // isBool 是否布尔值. 56 func isBool(val interface{}) bool { 57 return val == true || val == false 58 } 59 60 // isMap 检查变量是否字典. 61 func isMap(val interface{}) bool { 62 return reflect.ValueOf(val).Kind() == reflect.Map 63 } 64 65 // isStruct 检查变量是否结构体. 66 func isStruct(val interface{}) bool { 67 r := reflectPtr(reflect.ValueOf(val)) 68 return r.Kind() == reflect.Struct 69 } 70 71 // isInterface 变量是否接口. 72 func isInterface(val interface{}) bool { 73 r := reflectPtr(reflect.ValueOf(val)) 74 return r.Kind() == reflect.Invalid 75 } 76 77 // isString 变量是否字符串. 78 func isString(val interface{}) bool { 79 return GetVariateType(val) == "string" 80 } 81 82 // isByte 变量是否字节切片. 83 func isByte(val interface{}) bool { 84 return GetVariateType(val) == "[]uint8" 85 } 86 87 // isBinary 字符串是否二进制. 88 func isBinary(s string) bool { 89 for _, b := range s { 90 if 0 == b { 91 return true 92 } 93 } 94 return false 95 } 96 97 // isHex 是否十六进制字符串. 98 func isHex(str string) (res bool) { 99 if len(str) > 0 { 100 _, err := hex2Byte(str) 101 res = (err == nil) 102 } 103 104 return 105 } 106 107 // isInt 变量是否整型数值. 108 func isInt(val interface{}) bool { 109 switch val.(type) { 110 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 111 return true 112 case string: 113 str := val.(string) 114 if str == "" { 115 return false 116 } 117 _, err := strconv.Atoi(str) 118 return err == nil 119 } 120 121 return false 122 } 123 124 // isFloat 变量是否浮点数值. 125 func isFloat(val interface{}) bool { 126 switch val.(type) { 127 case float32, float64: 128 return true 129 case string: 130 str := val.(string) 131 if str == "" { 132 return false 133 } 134 135 if ok := RegFloat.MatchString(str); ok { 136 return true 137 } 138 } 139 140 return false 141 } 142 143 // isNumeric 变量是否数值(不包含复数). 144 func isNumeric(val interface{}) bool { 145 switch val.(type) { 146 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 147 return true 148 case float32, float64: 149 return true 150 case string: 151 str := val.(string) 152 if str == "" { 153 return false 154 } 155 _, err := strconv.ParseFloat(str, 64) 156 return err == nil 157 } 158 159 return false 160 } 161 162 // isNil 检查变量是否nil. 163 func isNil(val interface{}) bool { 164 if val == nil { 165 return true 166 } 167 168 rv := reflect.ValueOf(val) 169 switch rv.Kind() { 170 case reflect.Invalid: 171 return true 172 case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface: 173 return rv.IsNil() 174 } 175 return false 176 } 177 178 // isEmpty 检查变量是否为空. 179 func isEmpty(val interface{}) bool { 180 if val == nil { 181 return true 182 } 183 v := reflect.ValueOf(val) 184 switch v.Kind() { 185 case reflect.Invalid: 186 return true 187 case reflect.String, reflect.Array: 188 return v.Len() == 0 189 case reflect.Map, reflect.Slice: 190 return v.Len() == 0 || v.IsNil() 191 case reflect.Bool: 192 return !v.Bool() 193 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 194 return v.Int() == 0 195 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 196 return v.Uint() == 0 197 case reflect.Float32, reflect.Float64: 198 return v.Float() == 0 199 case reflect.Interface, reflect.Ptr: 200 return v.IsNil() 201 } 202 203 return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface()) 204 } 205 206 // isLittleEndian 系统字节序类型是否小端存储. 207 func isLittleEndian() bool { 208 var i int32 = 0x01020304 209 210 // 将int32类型的指针转换为byte类型的指针 211 u := unsafe.Pointer(&i) 212 pb := (*byte)(u) 213 214 // 取得pb位置对应的值 215 b := *pb 216 217 // 由于b是byte类型的,最多保存8位,那么只能取得开始的8位 218 // 小端: 04 (03 02 01) 219 // 大端: 01 (02 03 04) 220 return (b == 0x04) 221 } 222 223 // getEndian 获取系统字节序类型,小端返回binary.LittleEndian,大端返回binary.BigEndian . 224 func getEndian() binary.ByteOrder { 225 var nativeEndian binary.ByteOrder = binary.BigEndian 226 buf := [2]byte{} 227 *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) 228 229 switch buf { 230 case [2]byte{0xCD, 0xAB}: 231 nativeEndian = binary.LittleEndian 232 //case [2]byte{0xAB, 0xCD}: 233 // nativeEndian = binary.BigEndian 234 } 235 236 return nativeEndian 237 } 238 239 // numeric2Float 将数值转换为float64. 240 func numeric2Float(val interface{}) (res float64, err error) { 241 switch val.(type) { 242 case int: 243 res = float64(val.(int)) 244 case int8: 245 res = float64(val.(int8)) 246 case int16: 247 res = float64(val.(int16)) 248 case int32: 249 res = float64(val.(int32)) 250 case int64: 251 res = float64(val.(int64)) 252 case uint: 253 res = float64(val.(uint)) 254 case uint8: 255 res = float64(val.(uint8)) 256 case uint16: 257 res = float64(val.(uint16)) 258 case uint32: 259 res = float64(val.(uint32)) 260 case uint64: 261 res = float64(val.(uint64)) 262 case float32: 263 res = float64(val.(float32)) 264 case float64: 265 res = val.(float64) 266 case string: 267 str := val.(string) 268 res, err = strconv.ParseFloat(str, 64) 269 } 270 return 271 } 272 273 // md5Byte 计算字节切片的 MD5 散列值. 274 func md5Byte(str []byte, length uint8) []byte { 275 var res []byte 276 h := md5.New() 277 _, _ = h.Write(str) 278 279 hBytes := h.Sum(nil) 280 dst := make([]byte, hex.EncodedLen(len(hBytes))) 281 hex.Encode(dst, hBytes) 282 if length > 0 && length < 32 { 283 res = dst[:length] 284 } else { 285 res = dst 286 } 287 288 return res 289 } 290 291 // shaXByte 计算字节切片的 shaX 散列值,x为1/256/512. 292 func shaXByte(str []byte, x uint16) []byte { 293 var h hash.Hash 294 switch x { 295 case 1: 296 h = sha1.New() 297 break 298 case 256: 299 h = sha256.New() 300 break 301 case 512: 302 h = sha512.New() 303 break 304 default: 305 panic(fmt.Sprintf("[shaXByte]`x must be in [1, 256, 512]; but: %d", x)) 306 } 307 308 h.Write(str) 309 310 hBytes := h.Sum(nil) 311 res := make([]byte, hex.EncodedLen(len(hBytes))) 312 hex.Encode(res, hBytes) 313 return res 314 } 315 316 // arrayValues 返回arr(数组/切片/字典/结构体)中所有的值. 317 // filterZero 是否过滤零值元素(nil,false,0,'',[]),true时排除零值元素,false时保留零值元素. 318 func arrayValues(arr interface{}, filterZero bool) []interface{} { 319 var res []interface{} 320 var fieldVal reflect.Value 321 val := reflect.ValueOf(arr) 322 switch val.Kind() { 323 case reflect.Array, reflect.Slice: 324 for i := 0; i < val.Len(); i++ { 325 fieldVal = val.Index(i) 326 if !filterZero || (filterZero && !fieldVal.IsZero()) { 327 res = append(res, fieldVal.Interface()) 328 } 329 } 330 case reflect.Map: 331 for _, k := range val.MapKeys() { 332 fieldVal = val.MapIndex(k) 333 if !filterZero || (filterZero && !fieldVal.IsZero()) { 334 res = append(res, fieldVal.Interface()) 335 } 336 } 337 case reflect.Struct: 338 for i := 0; i < val.NumField(); i++ { 339 fieldVal = val.Field(i) 340 if fieldVal.CanInterface() { 341 if !filterZero || (filterZero && !fieldVal.IsZero()) { 342 res = append(res, fieldVal.Interface()) 343 } 344 } 345 } 346 default: 347 panic("[arrayValues]`arr type must be array|slice|map|struct; but : " + val.Kind().String()) 348 } 349 350 return res 351 } 352 353 // reflectPtr 获取反射的指向. 354 func reflectPtr(r reflect.Value) reflect.Value { 355 // 如果是指针,则获取其所指向的元素 356 if r.Kind() == reflect.Ptr { 357 r = r.Elem() 358 } 359 return r 360 } 361 362 // reflect2Itf 将反射值转为接口(原值) 363 func reflect2Itf(r reflect.Value) (res interface{}) { 364 switch r.Kind() { 365 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: 366 res = r.Int() 367 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: 368 res = r.Uint() 369 case reflect.Float32, reflect.Float64: 370 res = r.Float() 371 case reflect.String: 372 res = r.String() 373 case reflect.Bool: 374 res = r.Bool() 375 default: 376 if r.CanInterface() { 377 res = r.Interface() 378 } else { 379 res = r 380 } 381 } 382 383 return 384 } 385 386 // structVal 获取结构体的反射值. 387 func structVal(obj interface{}) (reflect.Value, error) { 388 v := reflect.ValueOf(obj) 389 390 for v.Kind() == reflect.Ptr { 391 v = v.Elem() 392 } 393 394 if v.Kind() != reflect.Struct { 395 return v, errors.New("[structVal]`obj type must be struct; but : " + v.Kind().String()) 396 } 397 398 return v, nil 399 } 400 401 // structFields 获取结构体的字段;all是否包含所有字段(包括未导出的). 402 func structFields(obj interface{}, all bool) ([]reflect.StructField, error) { 403 v, e := structVal(obj) 404 if e != nil { 405 return nil, e 406 } 407 408 var fs []reflect.StructField 409 var t = v.Type() 410 for i := 0; i < t.NumField(); i++ { 411 field := t.Field(i) 412 // 不能访问未导出的字段 413 if !all && field.PkgPath != "" { 414 continue 415 } 416 417 fs = append(fs, field) 418 } 419 420 return fs, nil 421 } 422 423 // struct2Map 结构体转为字典;tagName为要导出的标签名,可以为空,为空时将导出所有字段. 424 func struct2Map(obj interface{}, tagName string) (map[string]interface{}, error) { 425 v, e := structVal(obj) 426 if e != nil { 427 return nil, e 428 } 429 430 t := v.Type() 431 var res = make(map[string]interface{}) 432 for i := 0; i < t.NumField(); i++ { 433 field := t.Field(i) 434 if tagName != "" { 435 if tagValue := field.Tag.Get(tagName); tagValue != "" { 436 res[tagValue] = reflect2Itf(v.Field(i)) 437 } 438 } else { 439 res[field.Name] = reflect2Itf(v.Field(i)) 440 } 441 } 442 443 return res, nil 444 } 445 446 // creditChecksum 计算身份证校验码,其中id为身份证号码. 447 func creditChecksum(id string) byte { 448 //∑(ai×Wi)(mod 11) 449 // 加权因子 450 factor := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2} 451 // 校验位对应值 452 code := []byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'} 453 454 leng := len(id) 455 sum := 0 456 for i, char := range id[:leng-1] { 457 num, _ := strconv.Atoi(string(char)) 458 sum += num * factor[i] 459 } 460 461 return code[sum%11] 462 } 463 464 // compareConditionMap 比对数组是否匹配条件.condition为条件字典,arr为要比对的数据(字典/结构体). 465 func compareConditionMap(condition map[string]interface{}, arr interface{}) (res interface{}) { 466 val := reflect.ValueOf(arr) 467 conNum := len(condition) 468 if conNum > 0 { 469 chkNum := 0 470 471 switch val.Kind() { 472 case reflect.Map: 473 if conNum > 0 { 474 for _, k := range val.MapKeys() { 475 if condVal, ok := condition[k.String()]; ok && reflect.DeepEqual(val.MapIndex(k).Interface(), condVal) { 476 chkNum++ 477 } 478 } 479 } 480 case reflect.Struct: 481 var field reflect.Value 482 for k, v := range condition { 483 field = val.FieldByName(k) 484 485 if field.IsValid() && field.CanInterface() && reflect.DeepEqual(field.Interface(), v) { 486 chkNum++ 487 } 488 } 489 default: 490 panic("[compareConditionMap]`arr type must be map|struct; but : " + val.Kind().String()) 491 } 492 493 if chkNum == conNum { 494 res = arr 495 } 496 } 497 498 return 499 } 500 501 // getTrimMask 获取要修剪的字符串集合,masks为要屏蔽的字符切片. 502 func getTrimMask(masks []string) string { 503 var str string 504 if len(masks) == 0 { 505 str = blankChars 506 } else { 507 str = strings.Join(masks, "") 508 } 509 return str 510 } 511 512 // methodExists 检查val结构体中是否存在methodName方法. 513 func methodExists(val interface{}, methodName string) (bool, error) { 514 if methodName == "" { 515 return false, errors.New("[methodExists]`methodName can not be empty.") 516 } 517 518 r := reflect.ValueOf(val) 519 if r.Type().Kind() != reflect.Ptr { 520 r = reflect.New(reflect.TypeOf(val)) 521 } 522 523 method := r.MethodByName(methodName) 524 if !method.IsValid() { 525 return false, fmt.Errorf("[methodExists] Method `%s` not exists in interface `%s`", methodName, r.Type()) 526 } 527 528 return true, nil 529 } 530 531 // getMethod 获取val结构体的methodName方法. 532 // 注意:返回的方法中的第一个参数是接收者. 533 // 所以,调用返回的方法时,必须将接收者作为第一个参数传递. 534 func getMethod(val interface{}, methodName string) interface{} { 535 if val == nil || methodName == "" { 536 return nil 537 } 538 539 r := reflect.ValueOf(val) 540 if r.Type().Kind() != reflect.Ptr { 541 r = reflect.New(reflect.TypeOf(val)) 542 } 543 544 method := r.MethodByName(methodName) 545 if !method.IsValid() { 546 return nil 547 } 548 549 return method.Interface() 550 } 551 552 // getFuncNames 获取变量的所有函数名. 553 func getFuncNames(val interface{}) (res []string) { 554 if val == nil { 555 return 556 } 557 558 r := reflect.ValueOf(val) 559 if r.Type().Kind() != reflect.Ptr { 560 r = reflect.New(reflect.TypeOf(val)) 561 } 562 563 typ := r.Type() 564 for i := 0; i < r.NumMethod(); i++ { 565 res = append(res, typ.Method(i).Name) 566 } 567 return 568 } 569 570 // camelCaseToLowerCase 驼峰转为小写. 571 func camelCaseToLowerCase(str string, connector rune) string { 572 if len(str) == 0 { 573 return "" 574 } 575 576 buf := &bytes.Buffer{} 577 var prev, r0, r1 rune 578 var size int 579 580 r0 = connector 581 582 for len(str) > 0 { 583 prev = r0 584 r0, size = utf8.DecodeRuneInString(str) 585 str = str[size:] 586 587 switch { 588 case r0 == utf8.RuneError: 589 continue 590 591 case unicode.IsUpper(r0): 592 if prev != connector && !unicode.IsNumber(prev) { 593 buf.WriteRune(connector) 594 } 595 596 buf.WriteRune(unicode.ToLower(r0)) 597 598 if len(str) == 0 { 599 break 600 } 601 602 r0, size = utf8.DecodeRuneInString(str) 603 str = str[size:] 604 605 if !unicode.IsUpper(r0) { 606 buf.WriteRune(r0) 607 break 608 } 609 610 // find next non-upper-case character and insert connector properly. 611 // it's designed to convert `HTTPServer` to `http_server`. 612 // if there are more than 2 adjacent upper case characters in a word, 613 // treat them as an abbreviation plus a normal word. 614 for len(str) > 0 { 615 r1 = r0 616 r0, size = utf8.DecodeRuneInString(str) 617 str = str[size:] 618 619 if r0 == utf8.RuneError { 620 buf.WriteRune(unicode.ToLower(r1)) 621 break 622 } 623 624 if !unicode.IsUpper(r0) { 625 if isCaseConnector(r0) { 626 r0 = connector 627 628 buf.WriteRune(unicode.ToLower(r1)) 629 } else if unicode.IsNumber(r0) { 630 // treat a number as an upper case rune 631 // so that both `http2xx` and `HTTP2XX` can be converted to `http_2xx`. 632 buf.WriteRune(unicode.ToLower(r1)) 633 buf.WriteRune(connector) 634 buf.WriteRune(r0) 635 } else { 636 buf.WriteRune(connector) 637 buf.WriteRune(unicode.ToLower(r1)) 638 buf.WriteRune(r0) 639 } 640 641 break 642 } 643 644 buf.WriteRune(unicode.ToLower(r1)) 645 } 646 647 if len(str) == 0 || r0 == connector { 648 buf.WriteRune(unicode.ToLower(r0)) 649 } 650 651 case unicode.IsNumber(r0): 652 if prev != connector && !unicode.IsNumber(prev) { 653 buf.WriteRune(connector) 654 } 655 656 buf.WriteRune(r0) 657 658 default: 659 if isCaseConnector(r0) { 660 r0 = connector 661 } 662 663 buf.WriteRune(r0) 664 } 665 } 666 667 return buf.String() 668 } 669 670 // isCaseConnector 是否字符转换连接符. 671 func isCaseConnector(r rune) bool { 672 return r == '-' || r == '_' || unicode.IsSpace(r) 673 } 674 675 // pkcs7Padding PKCS7填充. 676 // cipherText为密文;blockSize为分组长度;isZero是否零填充. 677 func pkcs7Padding(cipherText []byte, blockSize int, isZero bool) []byte { 678 clen := len(cipherText) 679 if cipherText == nil || clen == 0 || blockSize <= 0 { 680 return nil 681 } 682 683 var padtext []byte 684 padding := blockSize - clen%blockSize 685 if isZero { 686 padtext = bytes.Repeat([]byte{0}, padding) 687 } else { 688 padtext = bytes.Repeat([]byte{byte(padding)}, padding) 689 } 690 691 return append(cipherText, padtext...) 692 } 693 694 // pkcs7UnPadding PKCS7拆解. 695 // origData为源数据;blockSize为分组长度. 696 func pkcs7UnPadding(origData []byte, blockSize int) []byte { 697 //origData = zeroUnPadding(origData) 698 olen := len(origData) 699 if origData == nil || olen == 0 || blockSize <= 0 || olen%blockSize != 0 { 700 return nil 701 } 702 703 unpadding := int(origData[olen-1]) 704 if unpadding > olen { 705 return nil 706 } 707 708 return origData[:(olen - unpadding)] 709 } 710 711 // zeroPadding PKCS7使用0填充. 712 func zeroPadding(cipherText []byte, blockSize int) []byte { 713 return pkcs7Padding(cipherText, blockSize, true) 714 } 715 716 // zeroUnPadding PKCS7-0拆解. 717 func zeroUnPadding(origData []byte) []byte { 718 return bytes.TrimRightFunc(origData, func(r rune) bool { 719 return r == rune(0) 720 }) 721 } 722 723 // GetFieldValue 获取(字典/结构体的)字段值;fieldName为字段名,大小写敏感. 724 func GetFieldValue(arr interface{}, fieldName string) (res interface{}, err error) { 725 val := reflect.ValueOf(arr) 726 switch val.Kind() { 727 case reflect.Map: 728 for _, subKey := range val.MapKeys() { 729 if fmt.Sprintf("%s", subKey) == fieldName { 730 res = val.MapIndex(subKey).Interface() 731 break 732 } 733 } 734 case reflect.Struct: 735 field := val.FieldByName(fieldName) 736 if !field.IsValid() || !field.CanInterface() { 737 break 738 } 739 res = field.Interface() 740 default: 741 err = errors.New("[GetFieldValue]`arr type must be map|struct; but : " + val.Kind().String()) 742 } 743 744 return 745 } 746 747 // str2Int 将字符串转换为int.其中"true", "TRUE", "True"为1;若为浮点字符串,则取整数部分. 748 func str2Int(val string) (res int) { 749 if val == "true" || val == "TRUE" || val == "True" { 750 res = 1 751 return 752 } else if ok := RegFloat.MatchString(val); ok { 753 fl, _ := strconv.ParseFloat(val, 1) 754 res = int(fl) 755 return 756 } 757 758 res, _ = strconv.Atoi(val) 759 return 760 } 761 762 // str2Int 将字符串转换为uint.其中"true", "TRUE", "True"为1;若为浮点字符串,则取整数部分;若为负值则为0. 763 func str2Uint(val string) (res uint) { 764 if val == "true" || val == "TRUE" || val == "True" { 765 res = 1 766 return 767 } else if ok := RegFloat.MatchString(val); ok { 768 fl, _ := strconv.ParseFloat(val, 1) 769 if fl > 0 { 770 res = uint(fl) 771 } 772 773 return 774 } 775 776 n, e := strconv.Atoi(val) 777 if e == nil && n > 0 { 778 res = uint(n) 779 } 780 781 return 782 } 783 784 // str2Float32 将字符串转换为float32;其中"true", "TRUE", "True"为1.0 . 785 func str2Float32(val string) (res float32) { 786 if val == "true" || val == "TRUE" || val == "True" { 787 res = 1.0 788 } else { 789 r, _ := strconv.ParseFloat(val, 32) 790 res = float32(r) 791 } 792 793 return 794 } 795 796 // str2Float64 将字符串转换为float64;其中"true", "TRUE", "True"为1.0 . 797 func str2Float64(val string) (res float64) { 798 if val == "true" || val == "TRUE" || val == "True" { 799 res = 1.0 800 } else { 801 res, _ = strconv.ParseFloat(val, 64) 802 } 803 804 return 805 } 806 807 // str2Bool 将字符串转换为布尔值. 808 // 1, t, T, TRUE, true, True 等字符串为真; 809 // 0, f, F, FALSE, false, False 等字符串为假. 810 func str2Bool(val string) (res bool) { 811 if val != "" { 812 res, _ = strconv.ParseBool(val) 813 } 814 815 return 816 } 817 818 // bool2Int 将布尔值转换为整型. 819 func bool2Int(val bool) int { 820 if val { 821 return 1 822 } 823 return 0 824 } 825 826 // str2Bytes 将字符串转换为字节切片. 827 func str2Bytes(val string) []byte { 828 return []byte(val) 829 } 830 831 // bytes2Str 将字节切片转换为字符串. 832 func bytes2Str(val []byte) string { 833 return string(val) 834 } 835 836 // str2BytesUnsafe (非安全的)将字符串转换为字节切片. 837 // 该方法零拷贝,但不安全.它直接转换底层指针,两者指向的相同的内存,改一个另外一个也会变. 838 // 仅当临时需将长字符串转换且不长时间保存时可以使用. 839 // 转换之后若没做其他操作直接改变里面的字符,则程序会崩溃. 840 // 如 b:=str2BytesUnsafe("xxx"); b[1]='d'; 程序将panic. 841 func str2BytesUnsafe(val string) []byte { 842 psHeader := &reflect.SliceHeader{} 843 strHeader := (*reflect.StringHeader)(unsafe.Pointer(&val)) 844 psHeader.Data = strHeader.Data 845 psHeader.Len = strHeader.Len 846 psHeader.Cap = strHeader.Len 847 return *(*[]byte)(unsafe.Pointer(psHeader)) 848 } 849 850 // bytes2StrUnsafe (非安全的)将字节切片转换为字符串. 851 // 零拷贝,不安全.效率是string([]byte{})的百倍以上,且转换量越大效率优势越明显. 852 func bytes2StrUnsafe(val []byte) string { 853 return *(*string)(unsafe.Pointer(&val)) 854 } 855 856 // runes2Bytes 将[]rune转为[]byte. 857 func runes2Bytes(rs []rune) []byte { 858 size := 0 859 for _, r := range rs { 860 size += utf8.RuneLen(r) 861 } 862 863 bs := make([]byte, size) 864 865 count := 0 866 for _, r := range rs { 867 count += utf8.EncodeRune(bs[count:], r) 868 } 869 870 return bs 871 } 872 873 // toStr 强制将变量转换为字符串. 874 func toStr(val interface{}) string { 875 //先处理其他类型 876 v := reflect.ValueOf(val) 877 switch v.Kind() { 878 case reflect.Invalid: 879 return "" 880 case reflect.Bool: 881 return strconv.FormatBool(v.Bool()) 882 case reflect.String: 883 return v.String() 884 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 885 return strconv.FormatInt(v.Int(), 10) 886 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 887 return strconv.FormatUint(v.Uint(), 10) 888 case reflect.Float32: 889 return strconv.FormatFloat(v.Float(), 'f', -1, 32) 890 case reflect.Float64: 891 return strconv.FormatFloat(v.Float(), 'f', -1, 64) 892 case reflect.Ptr, reflect.Struct, reflect.Map: //指针、结构体和字典 893 b, err := json.Marshal(v.Interface()) 894 if err != nil { 895 return "" 896 } 897 return string(b) 898 } 899 900 //再处理字节切片 901 switch val.(type) { 902 case []uint8: 903 return string(val.([]uint8)) 904 } 905 906 return fmt.Sprintf("%v", val) 907 } 908 909 // toBool 强制将变量转换为布尔值. 910 // 数值类型将检查值是否>0; 911 // 字符串将使用str2Bool; 912 // 数组、切片、字典、通道类型将检查它们的长度是否>0; 913 // 指针、结构体类型为true,其他为false. 914 func toBool(val interface{}) (res bool) { 915 switch val.(type) { 916 case int: 917 res = (val.(int) > 0) 918 case int8: 919 res = (val.(int8) > 0) 920 case int16: 921 res = (val.(int16) > 0) 922 case int32: 923 res = (val.(int32) > 0) 924 case int64: 925 res = (val.(int64) > 0) 926 case uint: 927 res = (val.(uint) > 0) 928 case uint8: 929 res = (val.(uint8) > 0) 930 case uint16: 931 res = (val.(uint16) > 0) 932 case uint32: 933 res = (val.(uint32) > 0) 934 case uint64: 935 res = (val.(uint64) > 0) 936 case float32: 937 res = (val.(float32) > 0) 938 case float64: 939 res = (val.(float64) > 0) 940 case string: 941 res = str2Bool(val.(string)) 942 case bool: 943 res = val.(bool) 944 default: 945 v := reflect.ValueOf(val) 946 switch v.Kind() { 947 case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan: 948 res = v.Len() > 0 949 case reflect.Ptr, reflect.Struct: 950 res = true 951 } 952 } 953 954 return 955 } 956 957 // toInt 强制将变量转换为整型. 958 // 数值类型将转为整型; 959 // 字符串将使用str2Int; 960 // 布尔型的true为1,false为0; 961 // 数组、切片、字典、通道类型将取它们的长度; 962 // 指针、结构体类型为1,其他为0. 963 func toInt(val interface{}) (res int) { 964 switch val.(type) { 965 case int: 966 res = val.(int) 967 case int8: 968 res = int(val.(int8)) 969 case int16: 970 res = int(val.(int16)) 971 case int32: 972 res = int(val.(int32)) 973 case int64: 974 res = int(val.(int64)) 975 case uint: 976 res = int(val.(uint)) 977 case uint8: 978 res = int(val.(uint8)) 979 case uint16: 980 res = int(val.(uint16)) 981 case uint32: 982 res = int(val.(uint32)) 983 case uint64: 984 res = int(val.(uint64)) 985 case float32: 986 res = int(val.(float32)) 987 case float64: 988 res = int(val.(float64)) 989 case string: 990 res = str2Int(val.(string)) 991 case bool: 992 res = bool2Int(val.(bool)) 993 default: 994 v := reflect.ValueOf(val) 995 switch v.Kind() { 996 case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan: 997 res = v.Len() 998 case reflect.Ptr, reflect.Struct: 999 res = 1 1000 } 1001 } 1002 1003 return 1004 } 1005 1006 // toFloat 强制将变量转换为浮点型. 1007 // 数值类型将转为浮点型; 1008 // 字符串将使用str2Float64; 1009 // 布尔型的true为1.0,false为0; 1010 // 数组、切片、字典、通道类型将取它们的长度; 1011 // 指针、结构体类型为1.0,其他为0. 1012 func toFloat(val interface{}) (res float64) { 1013 switch val.(type) { 1014 case int: 1015 res = float64(val.(int)) 1016 case int8: 1017 res = float64(val.(int8)) 1018 case int16: 1019 res = float64(val.(int16)) 1020 case int32: 1021 res = float64(val.(int32)) 1022 case int64: 1023 res = float64(val.(int64)) 1024 case uint: 1025 res = float64(val.(uint)) 1026 case uint8: 1027 res = float64(val.(uint8)) 1028 case uint16: 1029 res = float64(val.(uint16)) 1030 case uint32: 1031 res = float64(val.(uint32)) 1032 case uint64: 1033 res = float64(val.(uint64)) 1034 case float32: 1035 res = float64(val.(float32)) 1036 case float64: 1037 res = val.(float64) 1038 case string: 1039 res = str2Float64(val.(string)) 1040 case bool: 1041 if val.(bool) { 1042 res = 1.0 1043 } 1044 default: 1045 v := reflect.ValueOf(val) 1046 switch v.Kind() { 1047 case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan: 1048 res = float64(v.Len()) 1049 case reflect.Ptr, reflect.Struct: 1050 res = 1.0 1051 } 1052 } 1053 1054 return 1055 } 1056 1057 // dec2Bin 将十进制转换为二进制字符串. 1058 func dec2Bin(num int64) string { 1059 return strconv.FormatInt(num, 2) 1060 } 1061 1062 // bin2Dec 将二进制字符串转换为十进制. 1063 func bin2Dec(str string) (int64, error) { 1064 i, err := strconv.ParseInt(str, 2, 0) 1065 if err != nil { 1066 return 0, err 1067 } 1068 return i, nil 1069 } 1070 1071 // hex2Bin 将十六进制字符串转换为二进制字符串. 1072 func hex2Bin(str string) (string, error) { 1073 i, err := strconv.ParseInt(str, 16, 0) 1074 if err != nil { 1075 return "", err 1076 } 1077 return strconv.FormatInt(i, 2), nil 1078 } 1079 1080 // bin2Hex 将二进制字符串转换为十六进制字符串. 1081 func bin2Hex(str string) (string, error) { 1082 i, err := strconv.ParseInt(str, 2, 0) 1083 if err != nil { 1084 return "", err 1085 } 1086 return strconv.FormatInt(i, 16), nil 1087 } 1088 1089 // dec2Hex 将十进制转换为十六进制. 1090 func dec2Hex(num int64) string { 1091 return strconv.FormatInt(num, 16) 1092 } 1093 1094 // hex2Dec 将十六进制转换为十进制. 1095 func hex2Dec(str string) (int64, error) { 1096 start := 0 1097 if len(str) > 2 && str[0:2] == "0x" { 1098 start = 2 1099 } 1100 1101 // bitSize 表示结果的位宽(包括符号位),0 表示最大位宽 1102 return strconv.ParseInt(str[start:], 16, 0) 1103 } 1104 1105 // hex2Byte 16进制字符串转字节切片. 1106 func hex2Byte(str string) ([]byte, error) { 1107 start := 0 1108 if len(str) > 2 && str[0:2] == "0x" { 1109 start = 2 1110 } 1111 1112 h, e := hex.DecodeString(str[start:]) 1113 return h, e 1114 } 1115 1116 // dec2Oct 将十进制转换为八进制. 1117 func dec2Oct(num int64) string { 1118 return strconv.FormatInt(num, 8) 1119 } 1120 1121 // oct2Dec 将八进制转换为十进制. 1122 func oct2Dec(str string) (int64, error) { 1123 start := 0 1124 if len(str) > 1 && str[0:1] == "0" { 1125 start = 1 1126 } 1127 1128 return strconv.ParseInt(str[start:], 8, 0) 1129 } 1130 1131 // getIntersectStrings 获取两个字符串相同部分的切片. 1132 // minLen为子串最小长度,为0则不限制. 1133 func getIntersectStrings(minLen int, str1, str2 string) (res []string) { 1134 var lenA, lenB, runesLen int 1135 var runes []rune 1136 var longStr, itm string 1137 var chkMap = make(map[string]bool) 1138 var chk, ok bool 1139 1140 lenA = len(str1) 1141 lenB = len(str2) 1142 1143 if lenA == 0 || lenB == 0 { 1144 return 1145 } 1146 1147 if lenA > lenB { 1148 longStr = str1 1149 runes = []rune(str2) 1150 } else { 1151 longStr = str2 1152 runes = []rune(str1) 1153 } 1154 runesLen = len(runes) 1155 1156 for i := 0; i < runesLen; i++ { 1157 for j := i + 1; j <= runesLen; j++ { 1158 itm = string(runes[i:j]) 1159 if minLen == 0 || (minLen > 0 && len(itm) >= minLen) { 1160 _, ok = chkMap[itm] 1161 if !ok { 1162 chk = strings.Contains(longStr, itm) 1163 chkMap[itm] = true 1164 if chk { 1165 res = append(res, itm) 1166 } 1167 } 1168 } 1169 } 1170 } 1171 1172 return 1173 } 1174 1175 // longestSameString 获取两个字符串最长相同的子串. 1176 func longestSameString(str1, str2 string) (res string) { 1177 var resLen, itmLen int 1178 strs := getIntersectStrings(0, str1, str2) 1179 if len(strs) > 0 { 1180 res = strs[0] 1181 resLen = len(res) 1182 for _, v := range strs { 1183 itmLen = len(v) 1184 if itmLen > resLen { 1185 res = v 1186 resLen = itmLen 1187 } 1188 } 1189 } 1190 1191 return 1192 } 1193 1194 // img2Base64 将图片字节转换为base64字符串.imgType为图片扩展名. 1195 func img2Base64(content []byte, imgType string) string { 1196 return fmt.Sprintf("data:image/%s;base64,%s", imgType, base64.StdEncoding.EncodeToString(content)) 1197 } 1198 1199 // formatPath 格式化路径. 1200 func formatPath(fpath string) string { 1201 //替换特殊字符 1202 fpath = strings.NewReplacer(`|`, "", `<`, "", `>`, "", `?`, "", `\`, "/").Replace(fpath) 1203 //替换连续斜杠 1204 fpath = RegFormatDir.ReplaceAllString(fpath, "/") 1205 1206 //处理windows路径(带":") 1207 slashPos := strings.Index(fpath, "/") 1208 colonPos := strings.Index(fpath, ":") 1209 if colonPos >= 0 { //路径中存在":" 1210 if slashPos == 0 { //路径以"/"开头 1211 fpath = strings.ReplaceAll(fpath, ":", "") 1212 } else { 1213 front := fpath[0 : colonPos+1] 1214 back := strings.ReplaceAll(fpath[colonPos:], ":", "") 1215 fpath = front + back 1216 } 1217 } 1218 1219 return fpath 1220 } 1221 1222 // formatDir 格式化目录,将"\","//"替换为"/",且以"/"结尾. 1223 func formatDir(fpath string) string { 1224 if fpath == "" { 1225 return "" 1226 } 1227 1228 fpath = formatPath(fpath) 1229 1230 return strings.TrimRight(fpath, "/") + "/" 1231 } 1232 1233 // buildQueryMap 创建URL Query参数字典. 1234 // result 为结果字典;keys 为键数组;value为键值. 1235 func buildQueryMap(result map[string]interface{}, keys []string, value interface{}) error { 1236 length := len(keys) 1237 // trim '," 1238 key := strings.Trim(keys[0], "',\"") 1239 if length == 1 { 1240 result[key] = value 1241 return nil 1242 } 1243 1244 // The end is slice. like f[], f[a][] 1245 if keys[1] == "" && length == 2 { 1246 if key == "" { 1247 return nil 1248 } 1249 val, ok := result[key] 1250 if !ok { 1251 result[key] = []interface{}{value} 1252 return nil 1253 } 1254 children, ok := val.([]interface{}) 1255 if !ok { 1256 return fmt.Errorf("[buildQueryMap] expected type '[]interface{}' for key '%s', but got '%T'", key, val) 1257 } 1258 result[key] = append(children, value) 1259 return nil 1260 } 1261 1262 // The end is slice + map. like f[][a] 1263 if keys[1] == "" && length > 2 && keys[2] != "" { 1264 val, ok := result[key] 1265 if !ok { 1266 result[key] = []interface{}{} 1267 val = result[key] 1268 } 1269 children, ok := val.([]interface{}) 1270 if !ok { 1271 return fmt.Errorf("[buildQueryMap] expected type '[]interface{}' for key '%s', but got '%T'", key, val) 1272 } 1273 if l := len(children); l > 0 { 1274 if child, ok := children[l-1].(map[string]interface{}); ok { 1275 if _, ok := child[keys[2]]; !ok { 1276 _ = buildQueryMap(child, keys[2:], value) 1277 return nil 1278 } 1279 } 1280 } 1281 child := map[string]interface{}{} 1282 _ = buildQueryMap(child, keys[2:], value) 1283 result[key] = append(children, child) 1284 1285 return nil 1286 } 1287 1288 // map. like f[a], f[a][b] 1289 val, ok := result[key] 1290 if !ok { 1291 result[key] = map[string]interface{}{} 1292 val = result[key] 1293 } 1294 children, ok := val.(map[string]interface{}) 1295 if !ok { 1296 return fmt.Errorf("[buildQueryMap] expected type 'map[string]interface{}' for key '%s', but got '%T'", key, val) 1297 } 1298 1299 return buildQueryMap(children, keys[1:], value) 1300 } 1301 1302 // isPort 变量值是否端口号(1~65535). 1303 func isPort(val interface{}) bool { 1304 if isInt(val) { 1305 port := toInt(val) 1306 if port > 0 && port < 65536 { 1307 return true 1308 } 1309 } 1310 1311 return false 1312 } 1313 1314 // similarText 计算两个字符串的相似度. 1315 func similarText(str1, str2 string, len1, len2 int) int { 1316 var sum, max int 1317 pos1, pos2 := 0, 0 1318 1319 // Find the longest segment of the same section in two strings 1320 for i := 0; i < len1; i++ { 1321 for j := 0; j < len2; j++ { 1322 for l := 0; (i+l < len1) && (j+l < len2) && (str1[i+l] == str2[j+l]); l++ { 1323 if l+1 > max { 1324 max = l + 1 1325 pos1 = i 1326 pos2 = j 1327 } 1328 } 1329 } 1330 } 1331 1332 if sum = max; sum > 0 { 1333 if pos1 > 0 && pos2 > 0 { 1334 sum += similarText(str1, str2, pos1, pos2) 1335 } 1336 if (pos1+max < len1) && (pos2+max < len2) { 1337 s1 := []byte(str1) 1338 s2 := []byte(str2) 1339 sum += similarText(string(s1[pos1+max:]), string(s2[pos2+max:]), len1-pos1-max, len2-pos2-max) 1340 } 1341 } 1342 1343 return sum 1344 } 1345 1346 // GetVariateType 获取变量类型. 1347 func GetVariateType(v interface{}) string { 1348 return fmt.Sprintf("%T", v) 1349 } 1350 1351 // GetVariatePointerAddr 获取变量的指针地址. 1352 func GetVariatePointerAddr(val interface{}) int64 { 1353 var p string 1354 v := reflect.ValueOf(val) 1355 switch v.Kind() { 1356 case reflect.Ptr: //变量是指针 1357 p = fmt.Sprintf("%p", val) 1358 default: 1359 p = fmt.Sprintf("%p", &val) 1360 } 1361 1362 res, _ := hex2Dec(p) 1363 return res 1364 } 1365 1366 // IsPointer 检查变量是否指针类型; 1367 // notNil 是否检查变量非nil. 1368 func IsPointer(val interface{}, notNil bool) (res bool) { 1369 v := reflect.ValueOf(val) 1370 if v.Kind() == reflect.Ptr { 1371 if notNil == false || (notNil && val != nil) { 1372 res = true 1373 } 1374 } 1375 1376 return 1377 } 1378 1379 // VerifyFunc 验证是否函数,并且参数个数、类型是否正确. 1380 // 返回有效的函数、有效的参数. 1381 func VerifyFunc(f interface{}, args ...interface{}) (vf reflect.Value, vargs []reflect.Value, err error) { 1382 vf = reflect.ValueOf(f) 1383 if vf.Kind() != reflect.Func { 1384 return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %v is not the function", f) 1385 } 1386 1387 tf := vf.Type() 1388 _len := len(args) 1389 if tf.NumIn() != _len { 1390 return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %d number of the argument is incorrect", _len) 1391 } 1392 1393 vargs = make([]reflect.Value, _len) 1394 for i := 0; i < _len; i++ { 1395 typ := tf.In(i).Kind() 1396 if (typ != reflect.Interface) && (typ != reflect.TypeOf(args[i]).Kind()) { 1397 return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %d-td argument`s type is incorrect", i+1) 1398 } 1399 vargs[i] = reflect.ValueOf(args[i]) 1400 } 1401 return vf, vargs, nil 1402 } 1403 1404 // CallFunc 动态调用函数. 1405 func CallFunc(f interface{}, args ...interface{}) (results []interface{}, err error) { 1406 vf, vargs, _err := VerifyFunc(f, args...) 1407 if _err != nil { 1408 return nil, _err 1409 } 1410 ret := vf.Call(vargs) 1411 _len := len(ret) 1412 results = make([]interface{}, _len) 1413 for i := 0; i < _len; i++ { 1414 results[i] = ret[i].Interface() 1415 } 1416 return 1417 }