第18位校验码生成标准
链接如下:
http://qyj.saic.gov.cn/wjfb/201509/t20150929_162430.html
第17位效验码生成文档
链接如下:
代码算法如下:传递一个16位的字符串即可:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
*
* @author Alan
* 2016年10月12日 下午5:05:52
* 注释:校验码生成工具类
*/
public class ValidCodeUtil {
/**
* 获取校验码
* @param str 16位字符串
* @return 18位校验码
*/
public static String getValidCode(String str){
if(str.length() == 16){
//1.通过传递过来的16位字符串获取第17位编码
String string = str.substring(8, str.length());
String num17 = getNum17(string);
str += num17;
//2.通过上面的17位字符串算出第18位编码
String num18 = getNum18(str);
str += num18;
}
return str;
}
/**
* 获取第17位字符
* @param str 16位长度的字符串
* @return 第17位字符
*/
private static String getNum17(String str){
int[] w = {3,7,9,10,5,8,4,2};//8位加权因子数组 , 传递进来的字符串参数为8位 , 从0到7分别代表一个整型值
//该集合存放熊0-9,A-Z所对应的整型值
Map<String, Integer> machineNumMap = new LinkedHashMap<>();
for(int i = 0 ; i < 10 ; i++){
machineNumMap.put(String.valueOf(i), i);
}
String ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] bigWord = ascii.toCharArray();
int num = 10;
for(char c : bigWord){
machineNumMap.put(String.valueOf(c), num++);
}
//算法开始计算 , 获取总和
char[] charArray = str.toCharArray();
int sum = 0;
for(int i = 0 ; i < charArray.length ; i++){
sum += w[i] * machineNumMap.get(String.valueOf(charArray[i]));
}
//当总和除以11余数为1时第9位校验码为X , 余数为0是校验码为0
int nine = sum % 11;
String nineStr = "";
if(nine == 1){
nineStr = "X";
}else if(nine == 0){
nineStr = "0";
}else{
nineStr = String.valueOf(11-nine);
}
return nineStr;
}
/**
* 获取第18位字符
* @param str 17位长度的字符串
* @return 第18位字符
*/
private static String getNum18(String str) {
int[] w = {1,2,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};//17位加权因子数组 , 传递进来的字符串参数为17位 , 从0到16分别代表一个整型值
// 该集合存放熊0-9,A-Z所对应的整型值
Map<String, Integer> machineNumMap = new LinkedHashMap<>();
for (int i = 0; i < 10; i++) {
machineNumMap.put(String.valueOf(i), i);
}
String ascii = "ABCDEFGHJKLMNPQRTUWXY";//没有IOZSV
char[] bigWord = ascii.toCharArray();
int num = 10;
for (char c : bigWord) {
machineNumMap.put(String.valueOf(c), num++);
}
// 算法开始计算 , 获取总和
char[] charArray = str.toCharArray();
int sum = 0;
for (int i = 0; i < charArray.length; i++) {
sum += w[i] * machineNumMap.get(String.valueOf(charArray[i]));
}
//当总和除以31余数为1时第9位校验码为Y , 余数为0是校验码为0
int eightteen = sum % 31;
String eighteenStr = "";
if(eightteen == 1){
eighteenStr = "Y";
}else if(eightteen == 0){
eighteenStr = "0";
}else{
for (Entry<String, Integer> entry : machineNumMap.entrySet()) {
if(entry.getValue() == 31-eightteen-1){
eighteenStr = entry.getKey();
}
}
}
return eighteenStr;
}
}