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