JAVA實(shí)現(xiàn)社會(huì)統(tǒng)一信用代碼校驗(yàn)的方法
網(wǎng)上找了幾個(gè),寫(xiě)的都不太適合,有的寫(xiě)出來(lái)了,也沒(méi)有給出參考的算法鏈接。這樣就導(dǎo)致了如果產(chǎn)生錯(cuò)誤我們無(wú)法排查(不懂原理怎么排查對(duì)吧)。
如果在使用過(guò)程中有疑慮,請(qǐng)參考:較驗(yàn)規(guī)則
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; /** * 統(tǒng)一社會(huì)停用用代碼 */ 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}; /** * 生成供較驗(yàn)使用的 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; } /** * 較驗(yàn)社會(huì)統(tǒng)一信用代碼 * * @param unifiedCreditCode 統(tǒng)一社會(huì)信息代碼 * @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)); } /** * 獲取較驗(yàn)碼 * * @param unifiedCreditCode 統(tǒng)一社會(huì)信息代碼 * @param codes 帶有映射關(guān)系的國(guó)家代碼 * @return 獲取較驗(yàn)位的值 */ 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; } /** * 獲取一個(gè)隨機(jī)的統(tǒng)一社會(huì)信用代碼 * * @return 統(tǒng)一社會(huì)信用代碼 */ 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("生成社會(huì)統(tǒng)一信用代碼不符合規(guī)則"); upperCode = generateOneUnifiedCreditCode(); } else { upperCode = upperCode + codes.getKey(parityBit); } return upperCode; } }
測(cè)試
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(); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 利用Java正則表達(dá)式校驗(yàn)郵箱與手機(jī)號(hào)
- java使用正則表達(dá)校驗(yàn)手機(jī)號(hào)碼示例(手機(jī)號(hào)碼正則)
- JAVA 18位身份證號(hào)碼校驗(yàn)碼的算法
- java累加和校驗(yàn)實(shí)現(xiàn)方式16進(jìn)制(推薦)
- java中文及特殊字符的校驗(yàn)方法
- java身份證合法性校驗(yàn)并提取身份證有效信息
- Java發(fā)送郵箱驗(yàn)證碼、session校驗(yàn)功能
- Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能示例
- Java校驗(yàn)銀行卡是否正確的核心代碼
- Java基于正則實(shí)現(xiàn)的日期校驗(yàn)功能示例
- JAVA正則表達(dá)式校驗(yàn)qq號(hào)碼的方法
相關(guān)文章
小白也可以學(xué)會(huì)的Java NIO的Write事件
剛開(kāi)始對(duì)NIO的寫(xiě)操作理解的不深,不知道為什么要注冊(cè)寫(xiě)事件,何時(shí)注冊(cè)寫(xiě)事件,為什么寫(xiě)完之后要取消注冊(cè)寫(xiě)事件,今天特地整理了本篇文章,需要的朋友可以參考下2021-06-06Springboot項(xiàng)目快速實(shí)現(xiàn)過(guò)濾器功能
上篇文章已經(jīng)給大家介紹了Springboot項(xiàng)目如何快速實(shí)現(xiàn)Aop功能,這篇文章給大家介紹Springboot項(xiàng)目如何快速實(shí)現(xiàn)過(guò)濾器功能,感興趣的小伙伴可以參考閱讀2023-03-03SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別淺析
這篇文章主要給大家介紹了關(guān)于SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12SpringBoot整合MinIO實(shí)現(xiàn)文件上傳的方法詳解
一般涉及到文件上傳,基本上都是保存在項(xiàng)目本地,這種方式比較省事,但是安全性不高。所以今天給大伙詳細(xì)介紹一些如何利用MinIO實(shí)現(xiàn)文件上傳,感興趣的可以了解一下2022-05-05springboot?web項(xiàng)目中?Set-Cookie?失敗原因及解決辦法
這篇文章主要介紹了springboot?web項(xiàng)目中?Set-Cookie?失敗原因及解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-10-10MyBatis批量插入大量數(shù)據(jù)(1w以上)
MyBatis進(jìn)行批量插入數(shù)時(shí),一次性插入超過(guò)一千條的時(shí)候MyBatis開(kāi)始報(bào)錯(cuò),本文主要介紹了MyBatis批量插入大量數(shù)據(jù)的解決方法,感興趣的可以了解一下2022-01-01MyBatisPlus條件構(gòu)造器圖文實(shí)例詳解
這篇文章主要介紹了MyBatisPlus條件構(gòu)造器,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時(shí)也是驗(yàn)證了一個(gè)人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會(huì)的2023-01-01java正則表達(dá)式判斷強(qiáng)密碼和隨機(jī)生成強(qiáng)密碼代碼示例
這篇文章主要給大家介紹了關(guān)于java正則表達(dá)式判斷強(qiáng)密碼和隨機(jī)生成強(qiáng)密碼的相關(guān)資料,最近需要一個(gè)密碼強(qiáng)度正則表達(dá)式在用戶(hù)注冊(cè)時(shí)校驗(yàn)用戶(hù)密碼強(qiáng)度,需要的朋友可以參考下2023-08-08spring依賴(lài)注入成功但在調(diào)用接口的時(shí)候拿到的依賴(lài)卻是null問(wèn)題
這篇文章主要介紹了spring依賴(lài)注入成功但在調(diào)用接口的時(shí)候拿到的依賴(lài)卻是null問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12