github.com/profzone/eden-framework@v1.0.10/pkg/validate/validatetpl/unity_social_credit_code.go (about)

     1  /*
     2  规则参考:https://zh.wikisource.org/zh-hans/GB_32100-2015_%E6%B3%95%E4%BA%BA%E5%92%8C%E5%85%B6%E4%BB%96%E7%BB%84%E7%BB%87%E7%BB%9F%E4%B8%80%E7%A4%BE%E4%BC%9A%E4%BF%A1%E7%94%A8%E4%BB%A3%E7%A0%81%E7%BC%96%E7%A0%81%E8%A7%84%E5%88%99
     3  */
     4  
     5  package validatetpl
     6  
     7  import (
     8  	"fmt"
     9  	"regexp"
    10  )
    11  
    12  const (
    13  	InvalidUnitySocialCreditCodeType             = "社会信用代码类型错误"
    14  	InvalidUnitySocialCreditCodeValue            = "无效的社会信用代码"
    15  	UnitySocialCreditCodeValueVerifyCodeNotMatch = "社会信用代码校验码不匹配"
    16  	UnitySocialCreditCodeValueWeightNotFound     = "社会信用代码权重值不存在"
    17  )
    18  
    19  var unity_social_credit_code_regexp *regexp.Regexp
    20  var code2value map[string]int
    21  var positionWeights []int
    22  
    23  func init() {
    24  	first := `(1|5|9|Y)`
    25  	second := `(1|2|3|9)`
    26  	thirdToEight := `(\d{6})`
    27  	nineToEighteen := `([0-9A-Z^IOZSV]{10})`
    28  	str := fmt.Sprintf(`^%s%s%s%s$`, first, second, thirdToEight, nineToEighteen)
    29  	unity_social_credit_code_regexp = regexp.MustCompile(str)
    30  	code2value = map[string]int{
    31  		`0`: 0,
    32  		`1`: 1,
    33  		`2`: 2,
    34  		`3`: 3,
    35  		`4`: 4,
    36  		`5`: 5,
    37  		`6`: 6,
    38  		`7`: 7,
    39  		`8`: 8,
    40  		`9`: 9,
    41  		`A`: 10,
    42  		`B`: 11,
    43  		`C`: 12,
    44  		`D`: 13,
    45  		`E`: 14,
    46  		`F`: 15,
    47  		`G`: 16,
    48  		`H`: 17,
    49  		`J`: 18,
    50  		`K`: 19,
    51  		`L`: 20,
    52  		`M`: 21,
    53  		`N`: 22,
    54  		`P`: 23,
    55  		`Q`: 24,
    56  		`R`: 25,
    57  		`T`: 26,
    58  		`U`: 27,
    59  		`W`: 28,
    60  		`X`: 29,
    61  		`Y`: 30,
    62  	}
    63  	positionWeights = []int{1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28}
    64  }
    65  
    66  func CheckoutUnitySocialCreditCode(array string) (bool, string) {
    67  	var r int
    68  	for index, i := range array[:17] {
    69  		c, ok := code2value[string(i)]
    70  		if !ok {
    71  			return false, UnitySocialCreditCodeValueWeightNotFound
    72  		}
    73  		r += c * positionWeights[index]
    74  	}
    75  	r = 31 - r%31
    76  	if r == 31 {
    77  		r = 0
    78  	}
    79  	if r == 30 {
    80  		r = code2value[`Y`]
    81  	}
    82  
    83  	checkCode, ok := code2value[string(array[17])]
    84  	if !ok {
    85  		return false, UnitySocialCreditCodeValueWeightNotFound
    86  	}
    87  
    88  	if r != checkCode {
    89  		return false, UnitySocialCreditCodeValueVerifyCodeNotMatch
    90  	}
    91  
    92  	return true, ""
    93  }
    94  
    95  func ValidateUnitySocialCreditCode(v interface{}) (bool, string) {
    96  	array, ok := v.(string)
    97  	if !ok {
    98  		return false, InvalidUnitySocialCreditCodeType
    99  	}
   100  	if !unity_social_credit_code_regexp.MatchString(array) {
   101  		return false, InvalidUnitySocialCreditCodeValue
   102  	}
   103  
   104  	// Note: 存在不能通过校验的统一社会信用码,
   105  	// 目前只做正则验证即可
   106  	// if ok, str := CheckoutUnitySocialCreditCode(array); !ok {
   107  	// 	return ok, str
   108  	// }
   109  
   110  	return true, ""
   111  }
   112  
   113  func ValidateUnitySocialCreditCodeOrEmpty(v interface{}) (bool, string) {
   114  	s, ok := v.(string)
   115  	if !ok {
   116  		return false, InvalidUnitySocialCreditCodeType
   117  	}
   118  	if s != "" && !unity_social_credit_code_regexp.MatchString(s) {
   119  		return false, InvalidUnitySocialCreditCodeValue
   120  	}
   121  	return true, ""
   122  }