软件编程
位置:首页>> 软件编程>> java编程>> JAVA实现社会统一信用代码校验的方法

JAVA实现社会统一信用代码校验的方法

作者:myskies  发布时间:2023-04-10 08:38:21 

标签:JAVA,社会统一信用代码,校验

网上找了几个,写的都不太适合,有的写出来了,也没有给出参考的算法链接。这样就导致了如果产生错误我们无法排查(不懂原理怎么排查对吧)。

如果在使用过程中有疑虑,请参考:较验规则


package com.mengyunzhi.common.utils;

import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.TreeBidiMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ValidationException;
import java.util.Map;
import java.util.Random;

/**
* 统一社会停用用代码
*/
public interface UnifiedCreditCodeUtils {
 Logger logger = LoggerFactory.getLogger(UnifiedCreditCodeUtils.class);
 String baseCode = "0123456789ABCDEFGHJKLMNPQRTUWXY";
 char[] baseCodeArray = baseCode.toCharArray();
 int[] wi = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};

/**
  * 生成供较验使用的 Code Map
  *
  * @return BidiMap
  */
 static BidiMap<Character, Integer> generateCodes() {
   BidiMap<Character, Integer> codes = new TreeBidiMap<>();
   for (int i = 0; i < baseCode.length(); i++) {
     codes.put(baseCodeArray[i], i);
   }

return codes;
 }

/**
  * 较验社会统一信用代码
  *
  * @param unifiedCreditCode 统一社会信息代码
  * @return 符合: true
  */
 static boolean validateUnifiedCreditCode(String unifiedCreditCode) {
   if ((unifiedCreditCode.equals("")) || unifiedCreditCode.length() != 18) {
     return false;
   }

Map<Character, Integer> codes = generateCodes();
   int parityBit;
   try {
     parityBit = getParityBit(unifiedCreditCode, codes);
   } catch (ValidationException e) {
     return false;
   }

return parityBit == codes.get(unifiedCreditCode.charAt(unifiedCreditCode.length() - 1));
 }

/**
  * 获取较验码
  *
  * @param unifiedCreditCode 统一社会信息代码
  * @param codes       带有映射关系的国家代码
  * @return 获取较验位的值
  */
 static int getParityBit(String unifiedCreditCode, Map<Character, Integer> codes) {
   char[] businessCodeArray = unifiedCreditCode.toCharArray();

int sum = 0;
   for (int i = 0; i < 17; i++) {
     char key = businessCodeArray[i];
     if (baseCode.indexOf(key) == -1) {
       throw new ValidationException("第" + String.valueOf(i + 1) + "位传入了非法的字符" + key);
     }
     sum += (codes.get(key) * wi[i]);
   }
   int result = 31 - sum % 31;
   return result == 31 ? 0 : result;
 }

/**
  * 获取一个随机的统一社会信用代码
  *
  * @return 统一社会信用代码
  */
 static String generateOneUnifiedCreditCode() {
   Random random = new Random();
   StringBuilder buf = new StringBuilder();

for (int i = 0; i < 17; ++i) {
     int num = random.nextInt(baseCode.length() - 1);
     buf.append(baseCode.charAt(num));
   }

String code = buf.toString();
   String upperCode = code.toUpperCase();
   BidiMap<Character, Integer> codes = generateCodes();
   int parityBit = getParityBit(upperCode, codes);

if (codes.getKey(parityBit) == null) {
     logger.debug("生成社会统一信用代码不符合规则");
     upperCode = generateOneUnifiedCreditCode();
   } else {
     upperCode = upperCode + codes.getKey(parityBit);
   }

return upperCode;
 }
}

测试


package com.mengyunzhi.common.utils;

import org.assertj.core.api.Assertions;
import org.junit.Test;

import static org.junit.Assert.*;

public class UnifiedCreditCodeUtilsTest {

@Test
 public void validateUnifiedCreditCode() {
   String code = "911310827965850580";
   Assertions.assertThat(UnifiedCreditCodeUtils.validateUnifiedCreditCode(code)).isTrue();
 }
}

来源:https://segmentfault.com/a/1190000019636243

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com