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

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

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

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


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

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

猜你喜欢

  • C# FileStream文件读写详解

    2021-10-27 15:44:14
  • Android中读取中文字符的文件与文件读取相关介绍

    2022-02-02 07:20:53
  • Spring中RedisTemplate的基本使用浅析

    2023-03-08 05:46:50
  • Spring boot外部配置(配置中心化)详解

    2022-07-11 23:13:26
  • WPF实现倒计时转场动画效果

    2023-01-10 11:46:23
  • SpringBoot+Shiro+LayUI权限管理系统项目源码

    2021-07-13 16:35:19
  • Java I/O中I/O流的典型使用方式详解

    2023-07-08 21:07:51
  • java后端解决跨域的几种问题解决

    2022-01-05 06:34:24
  • JavaWeb开发之JSTL标签库的使用、 自定义EL函数、自定义标签(带属性的、带标签体的)

    2021-08-22 10:25:00
  • java 实现简单圣诞树的示例代码(圣诞节快乐)

    2023-03-13 13:13:37
  • Android列表组件ListView使用详解之动态加载或修改列表数据

    2023-10-01 16:14:38
  • Android RIL使用详解

    2021-09-30 18:06:45
  • C#采用递归实现阶乘的方法

    2022-12-09 09:24:56
  • Android Studio 3.0后出现AAPT2与“android.enableAapt2”问题的解决方法

    2021-08-28 20:29:54
  • Spring Cloud Hystrix 服务降级限流策略详解

    2022-05-02 15:20:27
  • python实现数独游戏 java简单实现数独游戏

    2022-10-18 00:46:29
  • c#编写webservice服务引用实例分享

    2023-05-11 19:28:41
  • Java聊天室之实现一个服务器与多个客户端通信

    2021-06-03 11:34:45
  • Java Runtime的使用详解

    2021-10-23 06:46:39
  • spring boot写java web和接口

    2022-10-02 09:52:02
  • asp之家 软件编程 m.aspxhome.com