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

 更新时间:2019年07月02日 09:25:58   作者:myskies  
这篇文章主要介绍了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();
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java HashMap两种简便排序方法解析

    Java HashMap两种简便排序方法解析

    这篇文章主要介绍了Java HashMap两种简便排序方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • 浅谈java中BigDecimal的equals与compareTo的区别

    浅谈java中BigDecimal的equals与compareTo的区别

    下面小编就为大家带来一篇浅谈java中BigDecimal的equals与compareTo的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • java中Optional的使用详细解析

    java中Optional的使用详细解析

    这篇文章主要介绍了java新特性之Optional的详细解析,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • SpringBoot整合Lettuce redis过程解析

    SpringBoot整合Lettuce redis过程解析

    这篇文章主要介绍了SpringBoot整合Lettuce redis过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java JVM中线程状态详解

    Java JVM中线程状态详解

    这篇文章主要介绍了Java JVM中线程状态详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的朋友可以参考一下
    2022-09-09
  • Java阻塞队列的实现及应用

    Java阻塞队列的实现及应用

    这篇文章主要介绍了剖析Java中阻塞队列的实现原理及应用场景,这里也对阻塞和非阻塞队列的不同之处进行了对比,需要的朋友可以参考下
    2021-10-10
  • Java框架解说之BIO NIO AIO不同IO模型演进之路

    Java框架解说之BIO NIO AIO不同IO模型演进之路

    网上很多IO资料,对新手来说,越看越晕。根据自己的理解,总结对比了一下BIO、NIO、AIO,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Java通过JsApi方式实现微信支付

    Java通过JsApi方式实现微信支付

    本文讲解了Java如何实现JsApi方式的微信支付,代码内容详细,文章思路清晰,需要的朋友可以参考下
    2015-07-07
  • idea compile项目正常启动项目的时候build失败报“找不到符号”等问题及解决方案

    idea compile项目正常启动项目的时候build失败报“找不到符号”等问题及解决方案

    这篇文章主要介绍了idea compile项目正常,启动项目的时候build失败,报“找不到符号”等问题,这种问题属于lombok编译失败导致,可能原因是依赖jar包没有更新到最新版本,需要的朋友可以参考下
    2023-10-10
  • springcloud项目占用内存好几个G导致服务器崩溃的问题

    springcloud项目占用内存好几个G导致服务器崩溃的问题

    这篇文章主要介绍了springcloud项目占用内存好几个G导致服务器崩溃的问题,本文给大家分享解决方案供大家参考,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10

最新评论