//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.sm.hive;
import com.sm.util.Sm4Util;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.io.Text;
public class Sm4EncryptUDF extends GenericUDF {
private static final Log log = LogFactory.getLog(Sm4EncryptUDF.class.getName());
private transient StringObjectInspector oi = null;
public Sm4EncryptUDF() {
}
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
this.oi = (StringObjectInspector)arguments[0];
if (arguments.length != 2) {
throw new UDFArgumentLengthException("函数参数格式不正确!");
} else {
return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
}
}
public Object evaluate(GenericUDF.DeferredObject[] arguments) throws HiveException {
log.info(String.format("入参1:%s,入参2:%s", arguments[0].get().toString(), arguments[1].get().toString()));
Object dataArgument = arguments[0].get();
if (dataArgument != null) {
Text t = this.oi.getPrimitiveWritableObject(arguments[0].get());
byte[] bytes = t.getBytes();
String utfStr = new String(bytes, StandardCharsets.UTF_8);
log.info(String.format("原始入参转UTF8后值:%s", utfStr));
String sm4KeyArgument = arguments[1].get().toString();
if (StringUtils.isBlank(sm4KeyArgument)) {
throw new UDFArgumentTypeException(1, "函数参数二格式或长度不正确!");
} else {
String encrypt = Sm4Util.encrypt(utfStr, sm4KeyArgument);
log.info(String.format("加密后密文数据:%s", encrypt));
Text text = new Text(encrypt.getBytes(StandardCharsets.UTF_8));
log.info(String.format("加密后密文数据:%s", new String(text.getBytes(), StandardCharsets.UTF_8)));
return text;
}
} else {
return "";
}
}
public String getDisplayString(String[] strings) {
return strings[0] + strings[1];
}
}
使用上面代码进行udf函数注册,在hive实际使用过程中发现select出来的加密后的中文值,和直接insert select出来的值不一致,
根据您提供的代码和描述,出现结果不一致的原因可能是以下几个方面:
字符集编码问题:在您的UDF函数中,涉及到字符串的编码和解码操作。确保在不同步骤中使用相同的字符集编码,以免引起数据丢失或乱码。请检查以下代码段:
java
byte[] bytes = t.getBytes();
String utfStr = new String(bytes, StandardCharsets.UTF_8);
确认该代码与插入语句或查询语句中的字符集编码一致。
数据处理一致性:在UDF函数中,可能对输入数据进行了某些处理(如加密)。确保在插入和选择数据时,使用相同的方法和参数来处理数据。检查以下代码段:
java
String encrypt = Sm4Util.encrypt(utfStr, sm4KeyArgument);
确认加密方法Sm4Util.encrypt()在插入和选择数据时的调用方式和参数是一致的。
字段类型转换:如果输入数据的字段类型有变化,例如从字符串到二进制,或者从二进制到字符串,那么在插入和选择数据时需要正确处理类型转换。确保在插入和选择数据时,将数据转换为正确的类型。
数据源问题:如果使用不同的数据源进行插入和选择数据操作,例如在插入数据时使用了不同的库或表,可能会导致结果不一致。请确保在相同的数据源中进行插入和选择操作。
同时,请确保在使用UDF函数时,注册和加载该函数的过程正确无误,以及在查询或插入语句中正确引用了UDF函数。
如果您排除了上述问题仍然存在结果不一致的情况,可能需要进一步检查代码逻辑、调试日志、输入数据和输出结果,以确定具体原因。