组织机构代码
编码规则编辑
1.全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成。 本体代码采用系列(即分区段)顺序编码方法。 校验码按照以下公式计算: C9=11-MOD(∑Ci(i=1→8)×Wi,11) 式中: MOD——代表求余函数;
i——代表代码字符从左至右位置序号; Ci——代表第i位上的代码字符的值(具体代码字符见附表); C9——代表校验码;
Wi——代表第i位上的加权因子,其数值见下表: 当C9的值为10时,校验码应用大写的拉丁字母X表示;当C9的值为11时校验码用0表示。
2.代码的表示形式 为便于人工识别,应使用一个连字符“—”分隔本体代码与校验码。机读时,连字符省略。表示形式为: xxxxxxxx—X
3.自定义区 为满足各系统管理上的特殊需要,规定本体代码PDY00001至PDY99999为自定义区,供各系统编制内部组织机构代码使用。自定义区内编制的组织机构代码不作为个系统之间信息交换的依据。
统一社会信用代码
构成特点编辑
一是嵌入了组织机构代码作为主体标识码。通过组织机构代码的唯一性确保社会信用代码不会重码。换言之,组织机构代码的唯一性完美“遗传”给统一社会信用代码。
二是在组织机构代码前增加行政区划代码,这个组合不难发现就是税务登记证号码。这样就提高了统一社会代码的兼容性,在过渡期内税务机关可以利用这种嵌套规则更加便利地升级到新的信用代码系统。
三是预留前两位给登记机关和机构类别,这样统一社会信用代码在应用中更加清晰高效,第一位便于登记机关管理,可以作为检索条目,第二位可以准确给组织机构归类,方便细化分管。
四是统一社会信用代码的主体标识码天生具有的大容量。通过数字字母组合,加上指数级增长,可以确保在很长一段时间内无需升位就可容纳大量组织机构。
五是统一社会信用代码位数为18位,和身份证的位数相同,这一巧妙设计在未来“两码管两人”的应用中可以实现登记、检索、填表等统一。
六是统一社会信用代码中内嵌的主体标识码具有校验位,同时自身第十八位也是校验位,与身份证号相比是双校验,确保了号码准确性。
java校验工具类
package ;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
/**
*
* 组织机构代码/统一社会信用代码校验工具类
*
* 1.isUniformSocialCreditCode方法用于判断统一社会信用代码是否有效
* 2.isOrganizationCertificate方法用于判断组织机构代码是否有效
*
*
*
*/
public class RegexUtil {
private static final String BASE_CODE_STRING = "0123456789ABCDEFGHJKLMNPQRTUWXY";
private static final char[] BASE_CODE_ARRAY = BASE_CODE_STRING.toCharArray();
private static final List<Character> BASE_CODES = new ArrayList<Character>();
private static final String BASE_CODE_REGEX = "[" + BASE_CODE_STRING + "]{18}";
private static final int[] WEIGHT = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};
static {
for (char c : BASE_CODE_ARRAY) {
BASE_CODES.add(c);
}
}
/**
* 加权因子
*/
private static int power[] = {3,7,9,10,5,8,4,2};
/**
* 判断统一社会信用代码是否有效
* @param a
* @param b
* @return
*/
public static boolean isUniformSocialCreditCode(String socialCreditCode) {
if (StringUtils.isBlank(socialCreditCode) || !Pattern.matches(BASE_CODE_REGEX, socialCreditCode)) {
return false;
}
char[] businessCodeArray = socialCreditCode.toCharArray();
char check = businessCodeArray[17];
int sum = 0;
for (int i = 0; i < 17; i++) {
char key = businessCodeArray[i];
sum += (BASE_CODES.indexOf(key) * WEIGHT[i]);
}
int value = 31 - sum % 31;
return check == BASE_CODE_ARRAY[value % 31];
}
/**
* 判断组织机构代码是否有效
* @param organizationCertificate
* @return
*/
public static boolean isOrganizationCertificate(String organizationCertificate) {
String temp = organizationCertificate.toUpperCase();
if (temp.contains("-")) {
temp = temp.replace("-", "");
}
if(temp.length()!=9){
return false;
}
// 获取前面8位
String pre8 = temp.substring(0,8);
char[] pre8chars = pre8.toCharArray();// 0~z;
// 获取校验码
String code = temp.substring(8,9);
boolean isCode = isCode(code,sum(pre8chars));
return isCode;
}
/**
* 求和
* @param bit
* @return
*/
private static int sum(char[] bit){
int sum = 0;
for(int i=0;i<bit.length;i++){
int intTemp = bit[i]>'9'?(bit[i]-'A'+10):Integer.parseInt(bit[i]+"");
System.out.print(" "+intTemp);
sum +=intTemp*power[i];
}
return sum;
}
/**
* 判断机构代码的校验码和计算出的校验码是否一致
* @param a
* @param b
* @return
*/
private static boolean isCode(String a,int b){
String codeTEmp = (11- b%11)==10?"X":(11- b%11)==11?0+"":(11- b%11)+"";
return a.equals(codeTEmp);
}
}