我已经写了一个类来解密我们公司的客户ID和一个密钥。解密算法是DES。apache drill执行udf 2次,答案不是我想要的
然后,我重新考虑了下面的代码,并将算法从DES更改为AES,但是当我运行select函数时,解密将运行两次。首先得到正确的结果,然后第二个结果是错误的。 (所以最后的结果是错误的)
我在这里列出我的代码:
package org.apache.drill.exec.fn.impl;
import com.google.common.base.Charsets;
import io.netty.buffer.DrillBuf;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.net.BCodec;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.annotations.Workspace;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
@functiontemplate(
name = "decode_cid",
scope = FunctionTemplate.FunctionScope.SIMPLE,
nulls = FunctionTemplate.NullHandling.NULL_IF_NULL
)
public class DecodeCidFunction implements DrillSimpleFunc {
@Param
VarCharHolder raw_input;
// @Param
// VarCharHolder raw_key;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
// @workspace
// KeyGenerator keygenerator;
@Workspace
SecretKey myDesKey;
@Workspace
Cipher desCipher;
@Workspace
BCodec bCodec;
@Override
public void setup() {
try {
String key = "this is a secret";
javax.crypto.SecretKeyFactory factory = javax.crypto.SecretKeyFactory.getInstance("DES");
myDesKey = factory.generateSecret(new javax.crypto.spec.DESKeySpec(key.getBytes())) ;
System.out.println("myDesKey = "+myDesKey.toString());
// Create the cipher
desCipher = Cipher.getInstance("DES");
// Initialize the cipher for encryption
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
bCodec = new BCodec("UTF-8");
} catch(Exception e) {
System.out.println("may i come here");
e.printStackTrace();
}
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(raw_input.start, raw_input.end, raw_input.buffer);
String output = "";
System.out.println("input = " + input);
if (input.startsWith("=?"))
{
try{
output = bCodec.decode(input);
}catch(Exception e){
System.out.println("find an error :" +e.toString());
output = "";
}
}else{
byte[] bts = new byte[input.length()/2];
for (int i = 0; i < bts.length; i++) {
bts[i] = (byte) Integer.parseInt(input.substring(2*i, 2*i+2), 16);
}
System.out.println("bts = " +bts.toString());
try{
byte[] decodedString = desCipher.doFinal(bts) ;
output = new String(decodedString, "utf-8");
}catch(Exception e){
System.out.println("i come here " + e.toString());
output="";
}
}
System.out.println("output = " + output);
out.buffer = buffer;
out.start = 0;
out.end = output.getBytes().length;
buffer.setBytes(0, output.getBytes());
}
}
输出:
而我选择查询如下:+1:
0: jdbc:drill:zk=local> select decode_cid('A849333D2713FAFEA10780AD02139B29') from (values(1));
myDesKey = [email protected]
input = A849333D2713FAFEA10780AD02139B29
bts = [[email protected]
output = 20138690
myDesKey = [email protected]
input = A849333D2713FAFEA10780AD02139B29
bts = [[email protected]
I come here javax.crypto.BadPaddingException: Given final block not properly padded
output =
+---------+
| EXPR$0 |
+---------+
| |
+---------+
1 row selected (3.075 seconds)
你可以看到第一个输出是正确的,但是第二个是空的,null不是我想要的。我想知道它为什么运行两次?
我尽我所能来解决语法和解释你如何试图重新因子代码从DES解密AES解密转换。 – rjdkolb
非常感谢!我真的不知道为什么它执行了2次,并且在第一次执行之后密钥已经改变,并且第一次执行的结果是我想要的 – zilaiye1988