统一社会信用代码校验

统一社会信用代码校验

import org.apache.commons.lang.StringUtils;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * 统一社会信用代码有效性校验
 *
 */
public class TyshxydmVerificationUtil {
	public final static String ISTYSHXYDM = "true";
	public final static String ERROR_TYSHXYDM = "统一社会信用代码有误,请核对后再输入!";
	public final static String ERROR_TYSHXYDM_MIN = "统一社会信用代码不足18位,请核对后再输入!";
	public final static String ERROR_TYSHXYDM_MAX = "统一社会信用代码大于18位,请核对后再输入!";
	public final static String ERROR_TYSHXYDM_EMPTY ="统一社会信用代码不能为空!";
	private static Map<String,Integer> datas = null;
	static int[] power = {1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};
	// 社会统一信用代码不含(I、O、S、V、Z) 等字母
	static char[] code = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','T','U','W','X','Y'};
	static {
		datas = new HashMap<>();
		for(int i=0;i<code.length;i++){
			datas.put(code[i]+"",i);
		}
	}
	
	/**
	 * 判断是否是一个有效的统一社会信用代码
	 * @param tyshxydm
	 * @return
	 */
	public static String isTyshxydm(String tyshxydm){
		if(StringUtils.isEmpty(tyshxydm) || StringUtils.isEmpty(tyshxydm.trim())){
			return ERROR_TYSHXYDM_EMPTY;
		}else if(tyshxydm.trim().length()<18){
			return ERROR_TYSHXYDM_MIN;
		}else if(tyshxydm.trim().length()>18){
			return ERROR_TYSHXYDM_MAX;
		}else if(tyshxydm.equals("000000000000000000")){
			return ERROR_TYSHXYDM;
		}else if(tyshxydm.startsWith("2")){
			return ERROR_TYSHXYDM;
		}else{
			tyshxydm = tyshxydm.trim();
			String checkCharResult = checkChar(tyshxydm); // 校验字符合法性
			if (!StringUtils.isEmpty(checkCharResult)) {
				return checkCharResult;
			}
			int sum = sum(tyshxydm.substring(0,17).toCharArray());
			int temp = sum%31;
			temp = temp==0?31:temp;
			return tyshxydm.substring(17,18).equals(code[31-temp]+"")?ISTYSHXYDM:ERROR_TYSHXYDM;
		}
	}
 
	private static String checkChar(String tyshxydm){
		String result = StringUtils.EMPTY;
		char[] chars = tyshxydm.toCharArray();
		for(int i = 0; i < chars.length; i++){
			if (Character.isSpaceChar(chars[i]) || !datas.containsKey(chars[i]+"")) {
				result = ERROR_TYSHXYDM;
				break;
			}
		}
		return result;
	}
	
	/**
	 * 加权计算
	 * @param chars
	 * @return
	 */
	private static int sum(char[] chars){
		int sum = 0;
		for(int i=0;i<chars.length;i++){
			int code = datas.get(chars[i]+"");
			sum += power[i]*code;
		}
		return sum;
 
	}
	
	
	public static void main(String[] args) {
		System.out.println(isTyshxydm("91220524MA84KJU9N"));
	}
	
}
### 实现统一社会信用代码校验逻辑 统一社会信用代码是一个18位的字符串,由数字和大写字母组成(不包括字母I、O、Z、S、V)。校验逻辑包括以下步骤: 1. **格式校验**:检查字符串是否符合18位且仅包含合法字符。 2. **校验码计算**:根据前17位计算校验码,并与第18位进行比对。 以下是使用JavaScript实现的完整校验逻辑: ```javascript function validateUnifiedSocialCreditCode(code) { // 正则表达式校验格式:18位,仅包含数字和大写字母(排除I、O、S、Z、V) const regex = /^[1-9A-NP-RT-UW-Y][1-9][0-9]{6}[0-9A-HJ-NP-RT-UW-Y]{10}$/; if (!regex.test(code)) { return false; } // 权重因子 const weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]; // 字符与数值的映射 const charMap = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18, 'K': 19, 'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24, 'R': 25, 'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30 }; let sum = 0; for (let i = 0; i < 17; i++) { const char = code[i]; if (!(char in charMap)) { return false; } sum += charMap[char] * weights[i]; } const checkDigit = (31 - (sum % 31)) % 31; const checkChar = code[17]; // 校验码比对 return checkDigit === charMap[checkChar]; } // 示例用法 const code = "91310115MA1K3YJ123"; const isValid = validateUnifiedSocialCreditCode(code); console.log(`统一社会信用代码 ${code} 校验结果: ${isValid ? "有效" : "无效"}`); ``` ### 代码说明: 1. **正则表达式校验**:使用正则表达式检查字符串是否符合18位,且仅包含合法字符。 2. **权重因子数组**:`weights`数组表示每一位的权重因子,用于计算校验码。 3. **字符映射**:`charMap`对象将字符映射到对应的数值。 4. **校验码计算**:通过前17位的字符和权重因子计算校验码,并与第18位进行比对。 ### 校验规则: - 如果校验码与计算结果一致,则统一社会信用代码有效。 - 否则,无效。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值