java 组织机构代码_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 generateCodes() {

BidiMap 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 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 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 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();

}

}

希望对你有帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值