hive自定义函数实现组织机构代码、统一社会信用代码校验

一、根据中华人民共和国国家标准全国组织机构代码(9位)编制规则实现规则校验

1、组织机构代码编码规则

1.1组织机构代码的组成

全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成。

1.2效验码生成规则

本体代码采用系列(即分区段)顺序编码方法

校验码按照以下公式计算:

C9=11-MOD(∑Ci(i=1→8)×Wi,11)

式中: MOD——代表求余函数;

i——代表代码字符从左至右位置序号;

Ci——代表第i位上的代码字符的值(具体代码字符见附表);

C9——代表校验码;

Wi——代表第i位上的加权因子,其数值见下表:

i

1

2

3

4

5

6

7

8

Wi

3

7

9

10

5

8

4

2

C9的值为1-9时,效验码为1-9;当C9的值为10时,校验码应用大写的拉丁字母X表示;当C9的值为11时校验码用0表示。

1.3代码的表示形式

为便于人工识别,应使用一个连字符“—”分隔本体代码与校验码。机读时,连字符省略。表示形式为:

xxxxxxxx—X

1.4自定义区

为满足各系统管理上的特殊需要,规定本体代码PDY00001至PDY99999为自定义区,供各系统编制内部组织机构代码使用。自定义区内编制的组织机构代码不作为个系统之间信息交换的依据。

1.5代码字符集

代码字符与机器处理字符数值对照表:

字符

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

G

H

数值

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

字符

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

数值

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

2、UDF代码实现

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

public class CheckNineOrganizationCode extends GenericUDF {

    //自定义区:为满足各系统管理上的特殊需要,本标准规定本体代码PDY00001至PDY99999为自定义区,供各系统编制内部组织机构代码使用。自定义区内编制的组织机构代码不作为各系统之间信息交换的依据
    private static final String patrnSpecial = "^PDY[0-9]{5}[0-9A-Z]{1}$";
    //(组织机构代码)9位正则表达式
    private static final String patrnOld = "^[0-9A-Z]{9}$";

    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        if (arguments.length!=1){
            throw new UDFArgumentLengthException("input arguments length less then one");
        }
        if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE))
        {
            throw  new UDFArgumentTypeException(0,"input arguments type error");
        }
        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
    }

    //获取传进来的信用代码在代码字符集(lastCodeMap)中的位置,即机器处理用代码字符数值
    //例如传进来M,则对应的机器处理用代码字符数值为 22
    public int getIndex(char[] arr,char item){
        int index = 0;
        for(int i = 0;i<arr.length;i++){
            if(arr[i]== item ){
                index = i;
            }
        }
        return index;
    }
    
    public boolean checkNineOrganizationCode(String code){

        if(code==null || code.equals("PDY000000")){
            return false;
        }else {
            //判断是否满足自定义区正则
            if(code.matches(patrnSpecial)){
                return true;
            }else {
                if(!code.matches(patrnOld)){
                    return false;
                }else {
                    //代码字符集
                    char[] lastCodeMap = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
                    //对应位置的加权因子,如位置0上的加权因子为3
                    int[] lastCodeW = {3, 7, 9, 10, 5, 8, 4, 2};
                    //对应位置的效验码
                    char[] lastCodeMapNew = {'0','1','2','3','4','5','6','7','8','9','X','0'};
                    int num = 0;
                    for(int i = 0; i < 8 ; i++){
                        //本体代码与加权因子对应各位相乘求和
                        num += getIndex(lastCodeMap, code.charAt(i))*lastCodeW[i];
                    }
                    //求出来的和对11取模,然后  11-余数 得出下标
                    int index = 11 - num % 11;
                    //得出来的下标对应在(lastCodeMapNew)中的效验码
                    char lastCode = lastCodeMapNew[index];
                    //与原信用代码最后1位效验码作比对,看是否相同
                    return code.charAt(8) == lastCode;
                }
            }
        }
    }
    
    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {

        if (arguments[0].get()==null){
            return false;
        }
        return checkNineOrganizationCode(arguments[0].get().toString());
    }

    @Override
    public String getDisplayString(String[] children) {
        return "check code";
    }
}

二、根据十八位统一社会信用代码编制规则实现规则校验

1、统一社会信用代码编码规则:

1.1统一社会信用代码的组成

统一社会信用代码由18位数字或者大写字母组成,但是字母不包括 I、O、Z、S、V

一共由五部分组成

第一部分:登记管理部门代码1位 (数字或大写英文字母)

第二部分:机构类别代码1位 (数字或大写英文字母)

第三部分:登记管理机关行政区划码6位 (数字)

第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)

第五部分:校验码1位 (数字或大写英文字母)

1.2效验码生成规则

第18位校验码按照以下公式计算:(遇0则Ci为0)

C18=31-MOD(∑Ci(i=1→17)×Wi,31)

C18的值为1-31,在代码字符集中有对应的字符表示,即为对应的校验码

加权因子表如下:

i

1

2

3

4

5

6

7

8

9

10

Wi

1

3

9

27

19

26

17

20

29

25

i

11

12

13

14

15

16

17

Wi

13

13

8

24

10

30

28

1.3代码字符集

代码字符与机器处理字符数值对照表:

字符

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

G

数值

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

字符

H

J

K

L

M

N

P

Q

R

T

U

W

X

Y

0

数值

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

2、UDF代码实现

udf编写流程和全国组织结构代码实现一样并且可一并验证组织结构代码,在原有的基础上加上18位校验规则

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

public class CheckUnifiedSocialCreditCode extends GenericUDF {
    //整体18位正则表达式
    private static final String patrn = "^(([15N]{1}[1239]{1})|([248A]{1}[19]{1})|([3]{1}[123459]{1})|([67]{1}[129]{1})|([Y]{1}[1]{1})|([9]{1}[123]{1}))(([1]{1}[012345]{1})|([2]{1}[123])|([3]{1}[1234567]{1})|([4]{1}[123456]{1})|([5]{1}[01234]{1})|([6]{1}[12345]{1})|([7]{1}[1]{1})|([8]{1}[12]{1}))[A-Y\\d]{14}$";
    //自定义区正则表达式
    private static final String patrnSpecial = "^PDY[0-9]{5}[0-9A-Z]{1}$";
    //组织机构代码9位正则表达式
    private static final String patrnOld = "^[0-9A-Z]{9}$";

    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        if (arguments.length!=1){
            throw new UDFArgumentLengthException("input arguments length less then one");
        }
        if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE))
        {
            throw  new UDFArgumentTypeException(0,"input arguments type error");
        }
        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
    }

    public int getIndex(char[] arr,char item){
        int index = 0;
        for(int i = 0;i<arr.length;i++){
            if(arr[i]==(item)){
                index = i;
            }
        }
        return index;
    }

    public boolean checkEighteenOrganizationCode(String column){
        if (column.substring(8,17).matches(patrnSpecial)) {
            return true;
        }
        //代码字符集,不包括I,O,Z,S,V,也用于判断最后一位是否与其计算出对应的效验码值相同
        char[] lastCodeMap = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','T','U','W','X','Y','0'};
        //加权因子值列表
        int[] lastCodeW = {1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};
        int num = 0;
        for(int i = 0;i<17;i++){
            num += (column.charAt(i)=='0'? 0 : getIndex(lastCodeMap,column.charAt(i)))*lastCodeW[i];
        }
        int index = 31 - num % 31;
        char lastCode = lastCodeMap[index];
        return column.charAt(17) == lastCode;
    }

    public boolean checkNineOrganizationCode(String code){
        if(code==null){
            return false;
        }else {
            if(code.matches(patrnSpecial)){
                return true;
            }else {
                if(!code.matches(patrnOld)){
                    return false;
                }else {
                    char[] lastCodeMap = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
                    int[] lastCodeW = {3, 7, 9, 10, 5, 8, 4, 2};
                    char[] lastCodeMapNew = {'0','1','2','3','4','5','6','7','8','9','X','0'};
                    int num = 0;
                    for(int i = 0; i < 8 ; i++){
                        num += getIndex(lastCodeMap, code.charAt(i))*lastCodeW[i];
                    }
                    int index = 11 - num % 11;
                    char lastCode = lastCodeMapNew[index];
                    return code.charAt(8) == lastCode;
                }
            }
        }
    }

    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {

        if (arguments[0].get()==null){
            return false;
        }else {
            if(!arguments[0].get().toString().trim().matches(patrn)){
                return false;
            }else {
                return checkEighteenOrganizationCode(arguments[0].get().toString()) && checkNineOrganizationCode(arguments[0].get().toString().substring(8, 17));
            }
        }
    }

    @Override
    public String getDisplayString(String[] children) {
        return "check code";
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是Java代码示例(假设已经导入了相关的MySQL和Hive依赖): ``` import java.sql.*; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; import org.apache.hadoop.hive.ql.exec.UDFReturnType; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; public class MySQLToHive extends GenericUDF { private Connection conn; @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { if (arguments.length != 3) { throw new UDFArgumentLengthException("The function MySQLToHive requires three arguments: jdbcUrl, username, and password"); } for (ObjectInspector argument : arguments) { if (!argument.getTypeName().equals("string")) { throw new UDFArgumentTypeException(0, "The arguments to MySQLToHive must all be strings"); } } return ObjectInspectorFactory.getStandardListObjectInspector( PrimitiveObjectInspectorFactory.writableStringObjectInspector); } @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { String jdbcUrl = arguments[0].get().toString(); String username = arguments[1].get().toString(); String password = arguments[2].get().toString(); try { if (conn == null || conn.isClosed()) { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(jdbcUrl, username, password); } Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM my_table"); List<Text> values = new ArrayList<Text>(); while (rs.next()) { Text value = new Text(rs.getString("col1") + "\t" + rs.getString("col2") + "\t" + rs.getString("col3")); values.add(value); } return values; } catch (Exception e) { throw new HiveException(e); } } @Override public String getDisplayString(String[] children) { return "MySQLToHive(jdbcUrl, username, password)"; } @Override public ObjectInspector getObjectInspector() throws UDFArgumentException { return ObjectInspectorFactory.getStandardListObjectInspector( PrimitiveObjectInspectorFactory.writableStringObjectInspector); } @Override public UDFReturnType getReturnType() { return UDFReturnType.LIST; } } ``` 这是一个自定义Hive函数,它将从MySQL中读取数据并将其写入Hive表。它需要三个参数:MySQL数据库的JDBC URL,用户名和密码。它将返回一个包含所有MySQL行数据的列表。修改SQL查询语句以适应你的表格结构。 在编译和打包Java代码后,将JAR文件上传到Hive服务器上,并在Hive中注册该函数: ``` ADD JAR /path/to/my_jar.jar; CREATE TEMPORARY FUNCTION mysql_to_hive AS 'MySQLToHive'; ``` 现在你可以在Hive中使用该函数: ``` INSERT INTO my_hive_table SELECT * FROM TABLE(mysql_to_hive('jdbc:mysql://localhost:3306/my_database', 'my_username', 'my_password')); ``` 这将从MySQL中读取所有行并将它们插入到名为 my_hive_table 的Hive表中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值